(Docker) 도커 컨테이너의 네트워킹 스택 관리하기

도커 컨테이너마다 자체적으로 네트워크 스택을 갖추고 있다.
이는 리눅스 커널의 네트워크 네임스페이스를 통해 제공되는 곳으로, 컨테이너 마다 net 네임스페이스에 대한 인스턴스가 새로 생성되기 때문에 다른 컨테이너나 외부에는 드러나지 않고 해당 컨테이너 내부에서만 사용된다.

1. docker0 브릿지

docker0 브릿지는 도커 네트워킹에서 가장 기본적인 기능을 제공한다.
도커서비스가 구동할 때마다 호스트 머신에 리눅스 브릿지가 생성된다. 이렇게 생성된 브릿지는 컨테이너의 인터페이스를 통해 통신하며, 외부에 대한 프록시 역할도 한다. 
한 호스트에서 구동하는 여러 컨테이너는 리눅스 브릿지를 통해 서로 통신한다.

docker0는 네가지 모드를 제공하며, 다음과 같이 --net 플래그를 통해 설정한다.

  • --net=default: 컨테이너 끼리 연결하기 위한 브릿지로 디폴트 브릿지를 사용한다.
  • --net=nonde: 컨테이너를 완전히 격리된 형태로 구동하며 네트워크에 연결하지 않는다.
  • --net=container:$container2: $container2라는 이름의 컨테이너에서 사용하는 네트워크 네임스페이스를 공유하도록 컨테이너를 생성한다.

1-1. 도커 브릿지 설정 관련 문제의 해결 방법

컨테이너 포트를 호스트의 포트와 매핑하는 방법을 살펴보고, 컨테이너를 외부와 연결할 때 발생할 수 있는 문제를 보자


두 컨테이너 모두 상대방에게 핑(ping)을 보낼 수 있을 뿐만 아니라 외부 네트워크에도 연결 할 수 있다.
외부와 연결하기 위해서는 컨테이너의 포트를 호스트의 포트와 매핑해야 한다.
앞서 설명한 바와 같이 컨테이너마다 네트워크 네임스페이스를 갖고 있다.
컨테이너가 생성될 때, 그 컨테이너에 대한 네트워크 네임스페이스도 새로 생성된다.


컨테이너와 리눅스 브릿지는 가상 이더넷(Virtual Ethernet)=veth 링크를 통해 연결한다.
컨테이너의 eth0 포트에서 보낸 트래픽은 vEth 인터페이스를 통해 브릿지에 도달한 후 스위칭을 거친다.

#리눅스 브릿지 상태보기
$ sudo brctl show



1-2. 컨테이너를 외부에 연결하기

호스트에서 iptables의 NAT테이블을 이용하면 외부에대한 모든 연결을 마스커레이팅 할 수 있다.
$sudo iptables -t nat -L -n

* docker0 브릿지에 연결된 interface보기

$apt-get install bridge-utils
$brctl show

1-3. 디폴트 브릿지를 br0로 바꾸기


$ sudo service docker stop
$ sudo ip link set dev docker0 down
$ sudo brctl delbr docker0
$ sudo iptables -t nat -F POSTROUTING
$ echo 'DOCKER_OPTS="-b=br0" ' >> /etc/default/docker
$ sudo brctl addbr br
$ sudo ip addr add 192.168.10.1/24 dev br0
$ sudo service docker start



<컨테이너와 외부 네트워크 통신에 관련된 문제해결법>

ip_forward가 1로 설정된 경우에만 컨테이너 사이에서 패킷을 주고받을 수 있다.
일반적으로 서버가 구동할 때 알아서 ip_forward 파라미터를 1로 설정한다.
확인하는 방법은

$ cat /proc/sys/net/ipv4/ip_forward

ip_forward를 true로 설정하면 컨테이너끼리 그리고 컨테이너와 외부 네트워크 사이에서 통신 할 수 있다.


ip_forward를 false로 설정하면 컨테이너와 외부 네트워크 사이에 오가는 패킷을 모두 드롭한다.



예를들어, 외부에서 들어온 패킷 중에서 출발지 IP가 10.10.10.10인 것만 컨테이너에 접근하게 하려면 다음과 같이 한다.

$ iptables -I DOCKER -i ext_if ! -s 10.10.10.10 -j DROP


댓글

이 블로그의 인기 게시물

(네트워크)폴링방식 vs 롱 폴링방식

(ElasticSearch) 결과에서 순서 정렬

(18장) WebSocekt과 STOMP를 사용하여 메시징하기