호스트 입장에서의 컨테이너



호스트에 도커를 설치하고 컨테이너를 생성하는 경우 네트워크 구조는 대략 위와 같이 docker0 인터페이스가 생성됩니다.

docker0 인터페이스는 가상 인터페이스이며, 172.17.~/8 의 ip를 할당받게 됩니다.  또한 docker0 인터페이스는 bridge 네트워크로 컨테이너가 하나씩 생성될때마다 바인딩 되는 형식이므로 컨테이너가 통신할 때에는 무조건 docker0 인터페이스를 거치게 됩니다. 브릿지에 대한 정보는 brctl show 명령어로 확인 가능합니다.




컨테이너의 네트워크 대역
컨테이너는 NAT를 통해 IP주소를 할당받는다. 기본적으로 설정이 따로 없다면 컨테이너에는 172.17.0.x/8 의 IP를 순차적으로 할당합니다. 이를 확인하기 위해 우분투 컨테이너를 하나 띄웁니다.
root@ubuntua:~# docker run -i -t --name myubuntu ubuntu:14.04                                
cs


컨테이너가 만들어지고 내부로 들어왔습니다. ifconfig 명령을 통해 네트워크를 확인해보면 eth0에 172.17.0.2 ip를 할당받은것을 알 수 있습니다.
root@e3c90672a2b1:/# ifconfig    
eth0      Link encap:Ethernet  HWaddr 02:42:ac:11:00:02  
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0                        
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:23 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:2847 (2.8 KB)  TX bytes:0 (0.0 B)
 
 
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
cs


그러나 기본적으로는 외부에서는 호스트 내부에 설치된 컨테이너에 접근할 수 없으며, 호스트만 접근이 가능합니다. 외부에서 컨테이너에 접근하기 위해서는 외부에서 호스트로 보내온 데이터를 호스트가 다시 컨테이너에 포워딩 해줘야 합니다. 이때 포워딩 하기위해 호스트의 특정 포트와 컨테이너의 특정 포트를 바인딩 해줍니다.



아파치 웹서버 컨테이너 외부 네트워크에서 접근 설정하기
간단하게 우분투와 아파치 웹서버를 띄워 외부 네트워크 개방(?) 설정을 알아보도록 하겠습니다. 이미지로 컨테이너를 생성함과 동시에 포트포워딩 설정을 추가합니다. 글 처음에 만들었던 우분투 컨테이너와는 다르게 -p(또는 --publish)옵션을 추가했는데, 컨테이너의 포트를 호스트의 포트와 바인딩해 연결할 수 있게 한 것입니다.
옵션값 형식은 [호스트포트]:[컨테이너포트] 과 같이 사용합니다. 만약 호스트의 특정 아이피를 사용하고 싶은 경우에는 [호트스IP]:[호스트포트]:[컨테이너의 연결할 포트] 형식으로 사용할 수 있습니다.
root@ubuntua:~# docker run -i -t --name mywebserver -p 80:80 ubuntu:14.04                    
cs

또한 여러개의 포트를 한꺼번에 바인딩 하는 경우 -p 포트지정 -p 포트지정 과 같이 옵션을 여러 번 사용할 수 있습니다. 만약 -p 옵션만 사용하는 경우 호스트의 포트중 웰노운 포트를 제외하고 사용 가능한 임의의 포트를 자동으로 할당합니다.

  • 추가적으로 바인딩 된 포트는 docker ps 명령어를 통해 확인이 가능합니다.

그럼 이어서 생성한 우분투 컨테이너에서 아파치 웹서버를 설치하고 서비스를 시작합니다.
# apt-get update
# apt-get install apache2 -y                                                                
# service apache2 start    
cs


이제 브라우저를 띄우고 외부에서 접근해봅니다. 호스트와 컨테이너를 바인딩한것이므로, 접속은 호스트의 IP:80으로 접근해야 합니다. 그럼 호스트가 요청을 받아 설정 내용대로 내부의 컨테이너로 포워딩 할것입니다.





외부에서 컨테이너로 접근하는 경우 구조
아직 이해가 가지 않을 수 있으므로 부가적으로 설명을 해볼까 합니다.


브라우저를 통해 외부에서 호스트로 http 요청(80번 포트)를 전송합니다. 저의 경우는 브라우저를 띄운 테스트 컴퓨터와 도커 서버 호스트 컴퓨터(192.168.111.100)가 같은 내부망에 있었습니다. 따라서 테스트를 위해 위와 같이 요청했습니다.
호스트는 컨테이너 설정에 따라 80번이 들어오면 우분투 컨테이너에 포워딩하도록 되어 있었으므로 이를 docker0 인터페이스를 통해 포워딩합니다. 우분투 컨테이너는 이를 자신의 eth0 인터페이스로 받습니다.

여기서부터는 도커의 네트워크 구성과는 관계가 없습니다. 컨테이너 내부에 80번 포트를 사용(리스닝)하는 서비스가 있다면 데이터를 전달할 것입니다. 아파치 웹서버는 특별한 설정이 없다면 80번 포트를 사용하기에 eth0으로 들어온 데이터를 받아 지금까지의 과정을 역순으로 처리할 것입니다.

만약 컨테이너 내부에 설치된 아파치 웹서버가 8080포트를 사용중이라면 -p 80:8080 과 같이 설정해 주어야 합니다.


참고글 링크

블로그 이미지

도로락

IT, 프로그래밍, 컴퓨터 활용 정보 등을 위한 블로그

,