어제에 이어서 network plugin에 대해 알아보자. 공식문서를 번역하면서 주석을 달은 포스팅이다. (튜토리얼은 생략한다. 공식문서 튜토리얼을 그대로 따라가면 이해되기 때문에!)
Use bridge networks
네트워킹 측면에서 브리지 네트워크는 네트워크 세그먼트 간에 트래픽을 전달하는 링크 계층 장치이다. -위키피디아-
링크 계층이란?
링크 계층은 호스트가 물리적으로 연결되는 링크 상에서만 운용되는 메서드, 통신 프로토콜이 모여있다. 링크는 네트워크 상의 호스트나 노드를 상호 연결하기 위해 사용되는 물리, 논리 네트워크 구성 요소이며 링크 프로토콜은 근거리 통신망 세그먼트나 광역 통신망 연결의 인접한 네트워크 노드 간에만 운용되는 메서드와 표준의 스위트이다.
브리지는 호스트 시스템의 커널 내에서 실행되는 하드웨어 장치 또는 소프트웨어 장치일 수 있다. Docker의 관점에서 브리지 네트워크는 소프트웨어 브리지를 사용하여 (1). 동일한 브리지 네트워크에 연결된 컨테이너가 통신할 수 있도록 하는 동시에 (2). 해당 브리지 네트워크에 연결되지 않은 컨테이너로부터 격리한다. Docker bridge 드라이버는 서로 다른 bridge 네트워크의 컨테이너가 직접 통신할 수 없도록 호스트 시스템에 규칙을 자동으로 설치한다.
bridge 네트워크는 동일한 Docker daemon host에서 실행되는 컨테이너에 적용된다. 서로 다른 Docker daemon host에서 실행되는 컨테이너 간의 통신을 위해 OS 수준에서 라우팅을 관리하거나 overlay 네트워크를 사용할 수 있다.
데몬이란?
사용자가 직접적으로 제어하지 않고, 백그라운드에서 돌면서 여러 작업을 하는 프로그램을 말한다. -위키피디아-
Docker를 시작하면 기본 bridge 네트워크(그냥 bridge 라고도 함)가 자동으로 생성되고, 달리 지정되지 않는 한 새로 시작된 컨테이너가 연결된다. 사용자 정의 bridge 네트워크를 생성할 수도 있다. 사용자 정의 bridge 네트워크는 기본 bridge보다 우수하다.
Differences between user-defined bridges and the default bridge
1. User-defined bridges provide automatic DNS resolution between containers.
기본 bridge 네트워크의 컨네이너들은 레거시로 간주되는 --link 옵션을 사용하지 않는 한 IP 주소로만 서로 액세스 할 수 있다. 사용자 정의 bridge 네트워크에서 컨테이너는 이름 또는 별칭으로 서로를 호출할 수 있다.
웹 프런트 엔드와 데이터베이스 백엔드가 있는 응용프로그램을 상상해 보면 이해가 쉽다. 컨테이너를 web 및 db 라고 호출하면 응용 프로그램 스택이 실행 중인 Docker 호스트에 관계없이 웹 컨테이너가 db 컨테이너와 연결할 수 있다.
기본 bridge 네트워크에서 동일한 응용 프로그램 스택을 실행하는 경우 컨테이너 간의 링크를 수동으로 만들어야 한다. (--link flag *레거시로 분류돼 있다.) 이러한 링크는 양방향으로 생성되어야 하므로 통신해야 하는 두 개 이상의 컨테이너로 복잡해지는 것을 볼 수 있다. 또는 컨테이너 내에서 /etc/host 파일을 조작할 수 있지만 디버그 하기 어려운 문제가 발생한다.
2. User-defined bridges provide better isolation.
--network 가 지정되지 않은 모든 컨테이너는 기본 bridge 네트워크에 연결된다. 이는 관련이 없는 스택/서비스/컨테이너가 통신할 수 있기 때문에 위험할 수 있다. 사용자 정의 네트워크를 사용하면 해당 네트워크에 연결된 컨테이너만 통신할 수 있는 범위가 지정된 네트워크를 제공한다.
3. Each user-defined network creates a configurable bridge.
컨테이너가 기본 bridge 네트워크를 사용하는 경우 모든 컨테이너는 MTU 및 iptables 규칙과 같은 동일한 설정을 사용한다. 또한 기본 bridge 네트워크 구성은 Docker 자체 외부에서 발생하며 Docker를 다시 시작해야 한다.
사용자 정의 bridge 네트워크는 docker network create를 사용하여 생성 및 구성된다. 애플리케이션 그룹마다 네트워크 요구 사항이 다른 경우 각 사용자 정의 bridge를 생성할 때 개별적으로 구성할 수 있다.
4. Linked containers on the default bridge network share environment variables.
원래 두 컨테이너 간에 환경 변수를 공유하는 유일한 방법은 --link를 사용하여 연결하는 것이었다. 사용자 정의 네트워크에서는 이러한 유형의 변수 공유가 불가능하다. 그러나 환경 변수를 공유할 수 있는 방법이 있다.
- 여러 컨테이너가 Docker volume을 사용하여 공유 정보를 포함하는 파일 또는 디렉터리를 마운트 할 수 있다.
- docker-compose를 사용하여 여러 컨테이너를 함께 시작할 수 있으며 compose 파일은 공유 변수를 정의할 수 있다.
- 독립 실행형 컨테이너 대신 swarm서비스를 사용할 수 있으며 공유된 secrets 파일과 config를 활용할 수 있다.
동일한 사용자 정의 bridge 네트워크에 연결된 컨테이너는 모든 포트를 서로 효과적으로 노출시킨다. 다른 네트워크의 컨네이너 또는 비 Docker 호스트에서 포트에 액세스 할 수 있으려면 -p 또는 --publish flag를 사용하여 포트를 게시해야 한다.
Manage a user-defined bridge
docker netwrok create 커맨드를 이용하여 사용자 정의 네트워크를 생성하자
$ docker network create my-net
(1) 서브넷, (2) IP 주소 범위, (3) 게이트웨이 및 기타 옵션을 지정할 수 있다. 자세한 사항은 docker network create --help를 통해 확인하자.
docker network rm 명령을 사용하여 사용자 정의 bridge 네트워크를 제거한다. 현재 네트워크에 연결되어 있는 경우 먼저 연결을 끊는다.
$ docker network rm my-net
사용자 정의 bridge를 만들거나 제거하거나 컨테이너를 연결하고 연결을 끊으면 Docker는 운영 체제 관련 도구를 사용하여 기본 네트워크 인프라(예: Linux에서 bridge 디바이스 추가 또는 제거 또는 iptables 규칙 구성)를 관리한다. 이러한 세부사항은 구현 세부사항으로 간주되어야 한다. Docker 사용자 정의 네트워크를 관리할 수 있다.
Connect a container to a user-defined bridge
새 컨테이너를 작성할 때 하나 이상의 --network flag를 지정할 수 있다. 이 예에서는 Nginx 컨테이너를 my-net 네트워크에 연결한다. 또한 외부 클라이언트가 해당 포트에 액세스 할 수 있도록 컨테이너의 포트 80을 Docker 호스트의 포트 8080에 게시한다. my-net 네트워크에 연결된 다른 모든 컨테이너는 my-nginx 컨테이너의 모든 포트에 엑세스 할 수 있으며 반대의 경우에도 마찬가지이다.
$ docker create --name my-nginx \
--network my-net \
--publish 8080:80 \
nginx:latest
실행 중인 컨테이너를 기존 사용자 정의 bridge에 연결하려면 docker netwrok connect 명령을 사용한다. 다음 명령은 이미 실해 중인 my-nginx 컨테이너를 이미 존재하는 my-net 네트워크에 연결한다.
$ docker network connect my-net my-nginx
Disconnect a container from a user-defined bridge
실행 중인 컨테이너를 사용자 정의 bridge에서 분리하려면 docker netwrok disconnect 명령을 사용한다. 다음 명령은 my-nginx 컨테이너를 my-net 네트워크에서 분리한다.
$ docker network disconnect my-net my-nginx
Use IPv6
Docker 컨테이너에 대한 IPv6 지원이 필요한 경우 IPv6 네트워크를 만들거나 컨테이너 IPv6 주소를 할당하기 전에 Docker 데몬에서 옵션을 활성화하고 구성을 다시 로드해야 한다. 네트워크를 만들 때 --ipv6 플래그를 지정하여 IPv6를 활성화할 수 있습니다. 기본 브리지 네트워크에서 IPv6 지원을 선택적으로 비활성화할 수 없다.
Enable forwarding from Docker containers to the outside world
기본적으로 기본 bridge 네트워크에 연결된 컨테이너의 트래픽은 외부로 전달되지 않는다. 전달을 사용하려면 두 가지 설정을 변경해야 한다. 이것들은 Docker 명령어가 아니며 도커 호스트의 커널에 영향을 미친다.
1. IP 전달을 허용하도록 Linux 커널을 구성한다.
$ sysctl net.ipv4.conf.all.forwarding=1
2. iptables FORWARD 정책의 정책을 DROP에서 ACCEPT로 변경합니다.
$ sudo iptables -P FORWARD ACCEPT
Use the default bridge network
기본 bridge 네트워크는 Docker의 레거시 세부 정보로 간주되며 프로덕션에 사용하지 않는 것이 좋다. 구성은 수동 작업이며 기술적인 단점이 있다.
Connect a container to the default bridge network
--network 플래그를 사용하여 네트워크를 지정하지 않으면 컨테이너는 기본적으로 기본 bridge 네트워크에 연결된다. 기본 브리지 네트워크에 연결된 컨테이너는 레거시 --link flag를 사용하여 연결되지 않는 한 IP 주소로만 통신할 수 있다.(DNS 사용 못한다.)
Configure the default bridge network
기본 브리지 네트워크를 구성하려면 daemon.json에서 옵션을 지정한다. 다음은 몇 가지 옵션이 지정된 daemon.json 예제이다. 사용자 정의에 필요한 설정만 지정하자.
{
"bip": "192.168.1.1/24",
"fixed-cidr": "192.168.1.0/25",
"fixed-cidr-v6": "2001:db8::/64",
"mtu": 1500,
"default-gateway": "192.168.1.254",
"default-gateway-v6": "2001:db8:abcd::89",
"dns": ["10.20.1.2","10.20.1.3"]
}
Dokcer를 재시작하면 변경된다.
Use IPv6 with the default bridge network
IPv6 지원을 위한 도커를 구성하는 경우(IPv6 사용 참조) 기본 브리지 네트워크도 IPv6에 대해 자동으로 구성된다. 사용자 정의 bridge와 달리 기본 bridge에서 IPv6을 선택적으로 사용하지 않도록 설정할 수 없다.