3. 컨테이너
● VM 과의 차이를 더 상세히 참고 ) https://www.slideshare.net/BodenRussell/kvm-and-docker-lxc-benchmarking-with-openstack
장점 단점
● 빠른 시작과 종료
OS 입장에서는 단순한 프로세스 실행 & 종료
● 오버헤드가 낮음
GuestOS 가 없이 Host OS 자원을 공유하므로
가상화의 오버헤드가 적음
● 자원의 효율적 사용
애플리케이션 동작에 필요한 자원으로 구성
● Host OS 에 종속적
단일 하드웨어에 다양한 OS 의 사용이 필요한
경우 VM 을 사용해야 함 .
● 각각의 컨테이너에 독립된 커널 구성이
불가능함
커널 자원을 공유하기 때문에 컨테이너가 사용
하는 커널 환경은 동일
● Container 란 ? 격리된 공간에서 프로세스가 동작하는 기술 .
5. Docker 에서 사용되는 기술
- LXC(LinuX Container), namespaces, cgroup, etc, ...
6. Docker 컨테이너 생성 및 관리
● LXC
- 초기 Docker 에서 사용된 Linux 용 컨테이너 관리 기술
● libvirt
- libvirt 는 가상머신을 수행하며 공통 API 에 제공하는 라이브러리에서 다양한 가상화를 지
원하며 그 중에서도 LXC 를 지원
● libcontainer
- Docker version 0.9 이후부터 default 로 사용
- Linux 플랫폼에 의존적인 LXC 를 대체하기 위해 Docker 에서 만든 컨테이너 기술
Host OS 의존성을 제거해 다양한 플랫폼 지원 (Red Hat, Microsoft Windows, etc)
- libcontainer -> runC (libcontainer 의 리팩토링 구현체 ) 로 자체 구현체를 가짐
● Systemd
- 일부 리눅스 배포판에서 최종적으로 모든 프로세스들을 관리하는 init 시스템 .
- Systemd 라는 이름 뒤에 추가된 명칭은 유닉스에서의 데몬을 나타낸다 .
7. 리눅스 컨테이너 (LXC)
● LXC (LinuX Contianer)
- chroot 가 기원 (chroot : 시스템을 보호하기 위해 특정 경로를 최상위 경로에 보이게함 )
- namespace, cgroup 를 사용해 컨테이너를 생성 및 관리함
9. Docker Engine, containerd, runc
● Docker Engine
-Doker 의 진입점
-Docker 이미지 , 오케스트레이션 , 볼륨관리 , 네트워킹 확장 등을 담당
-Docker 엔진에 이미지 실행을 요청하면 containerd 데몬에 책임을 위임
● Containerd
- 컨테이너 이미지를 저장하고 전송
- 루트 파일시스템을 만들고
-runc 호출하여 컨테이너를 시작
- 컨테이너 관리
- 저수준의 스토리지와 네트워크 인터페이스 관리
● runC
- 컨테이너의 실행 시작을 담당하는 프로세스 .
-libcontainer 의 리팩토링 구현체 .
10. ● 프로세스 테이블
컨테이너마다 별도의 프로세스 테이블을 관리
특정 컨테이너의 프로세스에서 다른 컨테이너의 프로세스로 접근할 수 없음
● CPU, 메모리 장치 ( “/dev” 다음 장치 파일 )
컨테이너에서 사용할 수있는 범위를 제한
● 파일 시스템
컨테이너마다 특정 디렉토리를 루트 파일 시스템으로 보이게 함 .
● 네트워크
네트워크 네임 스페이스 (netns) 의 기능으로 컨테이너마다 별도의 네트워크 설정 구성 .
veth 라는 가상 NIC 장치를 이용하여 veth 의 한쪽을 컨테이너 내부 네임 스페이스에 할당
Docker 자원의 가상화
12. 컨테이너 구분 : namespace
namespace 기능
PID 독립적인 프로세스 공간 할당
Network 네트워크 디바이스 , IP Address, 포트 번호 , 라우팅 테이블 , 필터링
테이블 등 네트워크 리소스를 namespace 별로 할당 가능
UID 독립적인 사용자 할당
User ID(UID) 와 Group ID(GID) 공간을 격리
namespace 외부에 있는 user 나 group 이 내부의 공간을 보거나 건드릴 수
없음
Mount
파일 시스템 추상화를 위해 사용
마운트를 조작하여 namespace 내에 파일 시스템 트리를 구성
UTS namespace 별로 호스트명과 도메인 명을 독자적으로 가질 수 있음
IPC 공유 메모리 , 큐 , 세마포어 등 프로세스 간의 통신 (IPC, Inter-Process
Communication) 자원을 분리 할 수 있음
13. 리소스 관리 : cgroup
항목 기능
cpu CPU 사용량 제한
cpuacct CPU 사용량 통계 정보 제공
cpuset CPU 와 메모리 배치 제어
memory 메모리와 swap 사용량 제한
devices 디바이스 엑세스 허가 및 제한
freezer 그룹에 속한 프로세스 정지 및 재개
net_cls 네트워크 제어 태그 추가
blkio 블록 디바이스 입출력 량 제어
- 컨테이너에 할당하는 자원을 조정하는데 사용
- 프로세스 및 Thread 를 그룹화하여 관리하는 기능
- Host OS 의 CPU, 메모리와 같은 리소스를 그룹별로 제한 가능
-다음과 같은 주요 서브 시스템 관리 가능
-계층구조로 프로세스를 그룹화하여 관리가능
-하위 cgroup 은 상위 cgroup 의 제한 설정이 그대로 적용
14. 이미지 데이터 관리 : Union File System
● Btrfs
Linux 용 Copy on Write 파일 시스템 .
subvolume 기능과 snapshot 기능을 사용하여
컨테이너 이미지의 변경을 파일 시스템 층에서 관리
● AUFS
서로 다른 파일 시스템의 파일과 디렉터리를 중첩하여 하나의 파일트리를 구성할 수 있는 파일 시
스템
● Device Mapper
Linux 블록 디바이스 드라이버와 이를 지원하는 라이브러리 . 파일 시스템의 블록 I/O 와 디
바이스 매핑을 관리 . 개별 파일 시스템에 의존하지 않아 다양한 환경에서 사용 가능
● overlay
Union filesystem 의 하나로 파일 시스템에 또 다른 파일 시스템을 합치는 구조
16. Docker Networking ( 가상 bridge 및 가상 NIC)
- Docker 컨테이너는 서버의 물리 NIC 와 별도로 각 컨테이너 마다 가상 NIC 할당
- Default gateway 로 Linux bridge 인 docker0 를 만듦
· 외부 네트워크와 교환하는 페킷에 NAT 작업 수행
· 컨테이너 간 네트워크 연결
- 각 컨테이너에 격리된 네트워크 공간을 만들고 컨테이너의 eth0 에 static IP 할당
- 컨테이너 내부의 eth0 와 docker0 로 연결된 veth 인터페이스를 연결해 컨테이너 외부와 통신
17. ● Docker 컨테이너간 통신
- 링크 기능을 사용한 통신
( 동일 호스트상인 bridge docker0 에 접속한
컨테이너끼리만 가능 )
● Docker 컨테이너와 외부 네트워크 통신
- 가상 bridge docker0 와 호스트 OS 의 물리
NIC 에서 패킷을 전송
(NAPT 기능을 사용하여 접속 )
Docker Networking (Docker 컨테이너간 통신 )
18. Docker Security
● Capability
프로세스가 가지는 권한을 세분화 관리하는 기능
컨테이너 내에서 호스트에 악영향을 미치지 않도록 제어
● SElinux
강제 액세스 제어 기능
Docker 는 컨테이너 시작할 때 SElinux MCS 레이블을 컨테이너에 부여하고 컨테이너 프로세
스의 동작을 컨테이너로 제한함
● AppArmor
강제 접근 제어를 위해 DTE, RBAC, MLS 를 지원
타 보안 프레임워크에 비해 사용 및 정책관리가 편리
19. 참고링크
● [Docker] 완벽한 IT 인프라 구축을 위한 Docker: 제 2 장 컨테이너 가상화 기술과 Docker 요약
http://miiingo.tistory.com/88?category=644188
● Docker(container) 의 작동 원리 : namespaces and cgroups
https://tech.ssut.me/2017/08/15/what-even-is-a-container/
● what is Docker? ( 가상화 , LXC, 이미지 )
https://kbss27.github.io/2017/04/09/whydocker/
● Docker Network 구조 (1) - docker0 와 container network 구조
http://bluese05.tistory.com/15
● Docker Container
https://www.slideshare.net/rkawkxms/docker-container
● 도커 아키텍쳐 및 동작원리
http://gyus.me/?p=512
● 도커 그리고 Linux 컨테이너 기술들
http://www.opennaru.com/openshift/docker/what-is-the-difference-between-docker-lxd-and-lxc/
● 도커 vs LXC 비교
http://wiki.rockplace.co.kr/pages/viewpage.action?pageId=3868344
● What is Containerd ?
https://blog.docker.com/2017/08/what-is-containerd-runtime/
● What is docker ?
https://indrabasak.wordpress.com/2017/04/03/what-is-docker/
● Docker 에서 지원하는 Linux Kernel 의 기능 ( 요약편 ) 일본사이트
http://blog.etsukata.com/2014/05/docker-linux-kernel.html
● docker 가 libcontianer 를 시작한 이유
https://www.zdnet.com/article/docker-libcontainer-unifies-linux-container-powers/
● docker 0.9 : libcontianer 실행드라이버 소개
https://blog.docker.com/2014/03/docker-0-9-introducing-execution-drivers-and-libcontainer/
Notes de l'éditeur
도커는 컨테이너 가상화 환경에서 애플리케이션의 관리 및 실행을 위한 오픈 소스 플랫폼으로
윈도우 및 리눅스 에서 운영체제 수준의 가상화를 추상화 하고 자동화 하는 추가 계층을 제공합니다.
Container란 격리된 공간에서 프로세스가 동작하는 기술.
기존 VM에서의 가상화 방식은 주로 OS를 가상화 하는 방식이였던 반면에
container는 간단히 보면 filesystem의 가상화만을 이루고 있습니다.
기존 VM에서 각각 VM마다 Guest OS를 설치하였지만 container에서는
Guest OS가 필요없이 Host OS의 자원을 공유하기 때문에 가상화의 오버헤드가 적습니다.
또한 container에서는 부팅 개념이 존재하지 않아 시작과 종료가 빠릅니다.
도커는 클라이언트-서버 아키텍쳐를 사용하며 클라이언트와 서버는 호스트 머신에 설치된 Docker daemon으로 빌드와 실행, 배포등을 할 수 있도록 통신합니다.
● 도커의 동작 방식
어플리케이션을 담기 위해 도커 이미지를 빌드하고,도커 이미지로 부터 어플리케이션을 실행하기 위한 도커 컨테이너를 만들며
도커의 이미지는 공개/사설 저장소에서 공유할 수 있습니다.
--------------------------------------------
● DOCKER IMAGES
도커 이미지는 읽기전용 템플릿이다. 예를들면, 우분투에 아파치 웹서버를 설치한 것을 하나의 이미지라고 볼 수 있다.도커 이미지는 도커 컨테이너를 만드는데 사용되고, 도커는 새로운 이미지를 빌드할 수 있는 심플한 방법을 제공한다.
혹은 다른 사람이 만든것을 다운받을 수도 있다. 이미지는 도커의 빌드 컴포넌트이다.
● DOCKER REGISTRIES
도커 레지스트리는 이미지들을 보관하는 곳이다.
이미지를 업로드/다운로드 할 수 있는 공개 저장소와 사설 저장소가 있다. 공개 저장소는 Docker hub에서 제공되고 있다.도커 레지스트리는 도커의 배포 컴포넌트이다.
● DOCKER CONTAINERS
도커 컨테이너는 디렉토리와 비슷하다.
도커 컨테이너는 어플리케이션을 실행하기 위한 모든것을 가지고 있다. 각각의 컨테이너는 하나의 도커 이미지로 만들어 진다.도커 컨테이너는 실행될수 있고, 시작 시킬 수 있고, 중지 시킬 수 있고, 이동 시킬 수 있고, 삭제 할 수 있다. 각각의 컨테이너는 고립되어 있어며 안전한 어플리케이션 플랫폼이다.도커 컨테이너는 도커의 실행 컴포넌트이다.
Docker는 컨테이너를 관리하기 위하여
libvirt, LXC 및 systemd-nspawn을 통해 추상화된 가상화 인터페이스를 사용하며
리눅스에서 제공하는 가상화 기능 외에 자체적으로 libcontainer 라이브러리를 포함합니다.
또한, cgroups 및 namespaces와 같은 Linux 커널의 리소스 격리기능과 Union 파일 시스템을 사용하여 독립적인 컨테이너를 실행하고 유지 관리할 수 있습니다.
도커는 libvirt, LXC (리눅스 컨테이너), systemd-nspawn을 통한 추상화된 가상화 인터페이스를 사용하는 것 뿐 아니라
리눅스 커널이 제공하는 가상화 기능을 직접 사용하기 위한 자체적인 수단으로 libcontainer 라이브러리를 포함하고 있습니다
도커는 이 기술들을 사용하여 도커는 간접적으로 리눅스 커널의 가상화 기능들에 접근하며 현재 default 포맷은 libcontainer입니다.
리눅스 컨테이너의 기원은 chroot라고 할 수 있습니다.
과거에는 chroot 명령어로 컨테이너를 생성하였는데, chroot는 파일시스템에서 루트 디렉터리를 변경하는 명령어로
특정 디렉터리를 루트 디렉터리로 설정하면 chroot jail이라는 환경이 생성되서 chroot jail안에서는 바깥의 파일과 디렉터리에 접근 할 수 없습니다.
이처럼 chroot는 디렉터리 경로를 격리하기 때문에 서버 정보 유출과 피해를 최소화하는데 주로 사용되었습니다.
하지만 chroot jail에 들어갈 실행 파일과 공유 라이브러리를 직접 준비해야 했고 설정이 복잡하며 완벽한 가상 환경이 아니기 때문에
chroot에서 제어 할 수 있는 파일이나 디렉토리에 대한 엑세스만으로 네트워크 및 프로세스 등을 컨트롤 할 수 없습니다.
이후 리눅스는 chroot를 발전시켜 리눅스 컨테이너라는 시스템 레벨 가상화를 제공했습니다.
Namespaces에서 제공하는 프로세스 트리, 사용자 계정, 파일시스템, IPC, 네트워크 장치 등의 운영환경을 고립시켰으며 cgroups를 통해 각각의 고립된 환경에 cpu, memory, disk, network와 같은 자원을 할당합니다.
이러한 방식으로 LXC는 격리된 컨테이너를 생성하고 제공했습니다.
사실 컨테이너만 필요하다면 LXC만 사용해도 되지만 LXC는 컨테이너의 생성 및 관리, 배포에 대한 부가 기능이 없기 때문에 실제 서비스를 운용하기에는 부족함이 있습니다.
Docker는 이를 보충하여 컨테이너에 대한 부가 기능을 제공하고 컨테이너의 상태를 이미지화하여 배포를 손쉽게 해주었습니다.
기존의 컨테이너는 각각의 OS 내에서 작동하는 경량화된 VM의 구현이라는 목적이었다면
Docker는 개발자들이 다양한 OS에서 작동하는 동일한 개발환경을 구현하는 것을 목적으로 만들어졌습니다.
(이전 페이지에서처럼)
Docker 프로젝트 초기에는 LXC가 네임 스페이스, cgroup, 기능 등과 같은 일부 커널 기능에 대한 인터페이스와 같이 기본 실행 드라이버로 사용되며 Linux 사용자가 시스템 또는 응용 프로그램 컨테이너를 쉽게 만들고 관리 할 수 있었습니다.
하지만 의존성으로 인해 문제를 발생 시켰고 Docker의 핵심 기능이였던 LXC 개발을 제어 할 수 없어 새로운 오픈 소스 실행 드라이버 인 libcontainer가 만들어졌습니다.
Docker 에서 LXC를 사용하는 컨테이너의 표준 런타임 환경으로 제공하지만 default로 libcontainer와 함께 제공됩니다.
libcontainer 는 다른 의존성 없이 커널의 컨테이너 API에 직접 액세스하기 위해 개발 된 라이브러리입니다.
libcontainer 를 사용하면 LXC 나 다른 사용자 영역 패키지에 의존하지 않고도 즉시 네임 스페이스, 제어 그룹, 기능, 네트워크 인터페이스 및 방화벽 규칙을 일관되게 사용 할 수 있고 예측 가능한 방식으로 조작 할 수 있으며, LXC 처럼 버전 및 배포판과 관련된 문제에 영향을 받지 않습니다.
그리고 libcontianer는 시간이 지남에 따라 더 큰 오픈 소스 생태계와 산업 표준을 준수하기 위해 여러 추상화 레이어를 추가하면서 추후 runC 기술로 합쳐졌습니다.
현재 Docker 엔진의 주요 구성 요소는 containerd 및 runC입니다.
도커는 LXC를 기반으로 시작해서 0.9버전에서 자체적인 libcontainer 기술을 사용하였고 추후 runC기술로 합쳐졌습니다.
runC 와 containerd를 기반으로 한 Docker 1.11이 처음 출시되었고
이후 Docker 는 Kubernetes(쿠버네티스)와 같은 컨테이너 플랫폼의 요구와 동등한 수준까지 끌어 올 수 있는 많은 기능이 추가되었습니다.
docker 엔진은 Docker의 주요 진입 점으로 Docker 이미지, 오케스트레이션, 볼륨 관리, 네트워킹, 확장 등을 담당합니다.
Docker Command Line (CL)에서 Docker Engine에 이미지 실행을 요청하면, Docker Engine은 해당 책임을 containerd 데몬에 위임합니다.
containerd는 컨테이너 이미지를 저장하고 전송하는 것을 담당하며
루트 파일 시스템을 만들고 containerd-shim을 통해 runC를 호출하여 컨테이너를 시작하고, 컨테이너를 감독합니다.
또한 저수준의 스토리지 및 네트워크 인터페이스를 관리합니다.
containerd-shim : 컨테이너 프로세스의 부모
*OCI
오픈 컨테이너 프로젝트(OCP)라는 계획이 발표되었고 나중에 오픈 컨테이너 계획(OCI)이라는 이름으로 바뀌었다. 리눅스 재단의 후원으로 운영되는 OCI의 목적은 컨테이너 형식의 업계 표준과 모든 플랫폼에 대한 컨테이너 런타임 소프트웨어를 개발하는 것이다.원문보기: http://www.ciokorea.com/news/34694#csidx4daa22a1f377731bb8709aede46da5f
컨테이너마다 분할되는 자원에는 다음과 같은 것이 있습니다.
컨테이너마다 별도의 프로세스 테이블을 관리하여 컨테이너의 프로세스에서 다른 컨테이너의 프로세스가 보이지 않도록 하며,cgroups의 기능을 통해 컨테이너에서 사용할 수 있는 범위를 제한합니다
컨테이너마다 특정 디렉토리를 루트 파일 시스템으로 보이게 합니다. 이는 “chroot”와 동일한 개념입니다.
네트워크 네임 스페이스 (netns)의 기능은 컨테이너마다 별도의 네트워크 설정을 구성합니다.
Docker에서 사용되는 Linux Kernel의 기능은 다음과 같습니다.
각 기능은 크게, Namespaces , Cgroups , Storage , Networking , Security 로 나눌 수 있습니다.
Namespace란
어떤 namespace에 속하느냐에 따라 서로 다른 존재로 인식됨으로써 각 레이어를 격리하는 기술로
한 곳에 합쳐진 데이터에 이름을 붙여 충돌 가능성을 낮추고 쉽게 참조할 수 있도록 하는 기능을 제공합니다.
docker는 이런 namespaces 기능 사용하며,
컨테이너를 실행하게 되면 해당 컨테이너의 namesapce를 생성하여 컨테이너를 격리합니다.
도커가 사용하는 namespace는 다음과 같습니다.
- PID : 프로세스 격리에 사용
- NET : 네트워크인터페이스 관리에 사용
- UID : 독립적인 사용자 할당
- UTS : 독립적인 hostname 할당하며 커널 격리와 버전 인식에 사용 (UTS : Unix Timesharing System)
- MNT : 마운트 포인트의 관리에 사용
- IPC : 프로세스간의 통신 자원 접근에 대한 관리 (IPC : InterProcess Communication)
※ MOUNT(마운트) : 컴퓨터 내에 접속한 기기와 기억장치를 OS에 인식시키는 것
cgroups은 운영체제가 관리하는 다양한 리소스를 중앙에서 제어하기 위한 도구입니다.
리소스를 그룹화하고 각 그룹에 대해 우선 순위나 사용 가능한 리소스를 제한하거나 리소스 그룹을 분리하는 등의 기능을 제공합니다.
cgroups에서 관리하는 대상은 파일 시스템이나 프로세스뿐만 아니라 CPU 리소스와 메모리, 각종 디바이스, 네트워크 패킷, 네트워크 인터페이스 등 입니다.
cgroups의 이용 예로는 특정 프로세스에서 사용 가능한 메모리와 CPU 시간 등을 제한하는 것 등이 있습니다.
도커는 이 기술을 사용하여 CPU나 메모리 디스크 같은 하드웨어 리소스를 제어하여 컨테이너마다 자원을 분할 합니다.
Union file system은 여러 file system을 통합해 하나의 file system으로 보이게 하는 기술로 수정된 layer만 새로 빌드 후 교체하는 경량화된 방식 입니다.
Docker는 Copy on Write 방식으로 컨테이너 이미지 간의 차이를 취급함으로써 낭비없이 컨테이너 이미지의 변경을 관리합니다.
Docker 컨테이너에서 이미지를 관리하는 Storage 플러그인으로 btrfs, AUFS, vfs, DeviceMapper 커널 기능을 허용하고 있습니다.
* Copy on Wirte
데이터를 바로 복사하지 않고 원본을 그대로 참조하여 원본 또는 복사본 데이터 중 하나가 변경될 때 빈 공간을 확보하여 데이터를 복사하는 구조를 'Copy on Wirte'라고 하는데
기본 이미지에 필요한 프로그램과 라이브러리, 소스를 설치한 뒤 파일 하나로 만든 것을 Docker이미지라고 합니다.
매번 기본 이미지에 필요한 프로그램과 라이브러리, 소스를 설치하면 용량이 큰 이미지가 중복되어 생성될 것이라고 생각하기 쉽지만, 보시는 이미지처럼 Docker이미지는 현재 이미지에서 바뀐 부분만 이미지로 생성하고 실행할 때는 현재이미지와 바뀐 부분을 합쳐서 실행합니다.
* 여기서의 기본 이미지는 리눅스 배포판의 사용자 공간에서 실행되는 실행파일과 라이브러리 파일을 의미합니다.
(입출력을 수행하고 파일 시스템 오브젝트를 처리하는 소프트웨어를 아우릅니다.)
● 브리지(bridge)
OSI 모델의 데이터 링크 계층에 있는 여러 개의 네트워크 세그먼트를 연결해줌.
● NIC(Network Interface Controller)
컴퓨터를 네트워크에 연결하여 통신하기 위해 사용하는 하드웨어 장치.
랜 카드, 네트워크 인터페이스 컨트롤러(NIC), 네트워크 인터페이스 카드, 네트워크 어댑터, 네트워크 카드, 이더넷 카드 등으로도 불림.
==============================================================
Docker의 컨테이너는 서버의 물리 NIC와 별도로 각 컨테이너마다 가상 NIC가 할당되어 있습니다.
가상 NIC는 docker0이라는 가상 bridge에 접속하여 컨테이너끼리 통신합니다.
docker0은 Docker 데몬을 기동한 후에 생성되며 container가 통신하기 위한 기본적인 bridge interface 입니다.
가상 NIC(vethxxx)는 각 컨테이너에서 eth0으로 인식되며
eth0에는 호스트OS에 생성된 가상 NIC(vethxxx)가 페어로 할당됩니다.
veth는 OSI 7계층 Layer 2의 가상 네트워크 인터페이스로서 페어된 NIC끼리 터널링 통신을 수행합니다.
● Docker 컨테이너간 통신
동일한 호스트 상의 Docker 컨테이너는 구동 시 private Address가 자동으로 할당되므로 컨테이너끼리 통신하기 위하여 '링크 기능'을 사용합니다.
컨테이너를 구동할 때, 통신하려는 컨테이너 이름을 지정하여 링크하면 해당 정보가 /etc/host에 환경변수로 저장되어 직접 통신할 수 있습니다.
단, 링크 기능을 사용한 통신은 동일 호스트, 즉 가상 bridge docker0에 접속한 컨테이너끼리만 가능합니다. 멀티 호스트 환경에서는 링크 기능을 이용한 통신이 불가능하므로 주의해야 합니다.
또한 보안 요구 사항에 따라 컨테이너 간 통신을 차단하도록 설정할 수 있습니다.
● Docker 컨테이너와 외부 네트워크 통신
Docker 컨테이너가 외부 네트워크와 통신할 때에는 가상 bridge docker0와 호스트OS의 물리 NIC에서 패킷을 전송해야 합니다.
이 때, Docker에서는 NAPT 기능을 사용하여 접속합니다. 이 기능은 컨테이너를 구동할 때, 내부에서 사용하고 있는 포트를 가상 bridge docker0에서 개방할 때 사용됩니다
NAPT(Network Address Port Translation)란? 하나의 IP를 여러 컴퓨터에서 공유하는 기술로 IP와 포트 번호를 변환하는 기능입니다. TCP 및 UDP 포트 번호까지 동적으로 변환하기 때문에 여러 머신에서 한 global IP로 접속할 수 있습니다.
예를 들어 컨테이너 구동 시, 컨테이너 내의 웹 서버(http 데몬)가 사용하는 80번 포트를 호스트OS의 8080번 포트로 전송하도록 설정하였을 때, 외부 네트워크에서 호스트OS의 8080번 포트에 액세스하면 컨테이너 내의 80번 포트로 연결되는 구조입니다.
리눅스 커널의 기능 중 보안을 위한 강제 접근(mandatory access) 제어를 제공하는 보안 프레임워크에는 capablilty, SEL inux, 앱아머(AppArmor) 등이 존재합니다.
SecurityOption은 Docker 에서 필수 옵션은 아닙니다.