ㅍㅍㅋㄷ

Docker Network 구조(1) - docker0와 container network 구조 본문

IT/Docker

Docker Network 구조(1) - docker0와 container network 구조

물과같이 2015.07.13 18:33

Docker Network 구조(1) - docker0와 container network 구조










  Docker 의 network 구조를 간단히 도식화 하면 위와 같은 형상이다. 

  이번 포스팅에는 Docker를 설치하면 가장 먼저 볼 수 있는 docker0 인터페이스와 container network 에 대해 알아보자.

  


  Docker0 inteface


  docker host를 설치 한 후 host의 network interface 를 살펴 보면, docker0 라는 virtual interface가 있는 것을 볼 수 있다. 아래는 docker를 설치한 host의 interface를 확인한 정보이다. 아래와 같이 docker0 라는 interface를 확인할 수 있다.


 docker0   Link encap:Ethernet  HWaddr XX:XX:7a:fe:97:XX  

          inet addr:172.17.42.1  Bcast:0.0.0.0  Mask:255.255.0.0

          inet6 addr: fe80::5484:7aff:fefe:9799/64 Scope:Link

          UP BROADCAST MULTICAST  MTU:1500  Metric:1

          RX packets:9918 errors:0 dropped:0 overruns:0 frame:0

          TX packets:36261 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:0 

          RX bytes:662534 (662.5 KB)  TX bytes:52918471 (52.9 MB)


  먼저 docker0 interface의 특징을 살펴 보면, 



  • IP 는 자동으로 172.17.42.1 로 설정 되며 16 bit netmask(255.255.0.0) 로 설정된다. 
  • 이 IP는 DHCP를 통해 할당 받는 것은 아니며, docker 내부 로직에 의해 자동 할당 받는 것이다.
  • docker0 는 일반적인 interface가 아니며, virtual ethernet bridge 이다.


 이 중 마지막 특징을 자세히 알아보자. 
 docker0는 container가 통신하기 위한 가상 linux bridge 이다. bridge는 기본적으로 L2 통신 기반이며, 만약 container가 하나 생성되면 이 bridge에 container의 interface가 하나씩 binding 되는 형태이다. 따라서 container가 외부로 통신할 때는 무조건 docker0 interface를 지나야 한다. 
아래는 brctl 로 확인해 본 docker0 인터페이스이다. 

root@~~:# brctl show docker0

bridge name      bridge id                         STP    enabled   interfaces

docker0             8000.d67973326669    no                      veth0e580ab

                                                                                            veth77faee0


 위에서 보이는데로 docker가 설치되면 이름이 docker0 라는 bridge가 하나 생성 되며, container가 running 될때마다 vethXXXX 라는 이름의 interface가 attach되는 형태이다. ( 위 brctl의 예에서는 vethXX 가 두개인걸 보니, 현재 두개의 container가 running 중임을 유추 할 수 있다.)


 또한, docker0 의 IP는 자동으로 172.17.42.1로 설정되며, subnet mask는 255.255.0.0 즉, 172.17.0.0/16 으로 설정된다. 

이 subnet 정보는 앞으로 container가 생성될때 마다 할당 받게 될 IP의 range를 결정하게 된다. 즉, 모든 container는 172.17.XX.YY 대역에서 IP를 하나씩 할당 받도록 될 것이다. 


 만약 이 IP range를 변경하고 싶다면 다음 포스트를 참조하면 된다. 

 

 docker0 IP 및 CIDR 변경하기 


 그리고 만약 설치할때 자동으로 할당된 docker0 bridge 가 아닌, 내가 원하는 bridge를 새로 만들고 그것으로 대신 사용하고 싶다면? 

 이것도 설정이 가능하다. 설정 방법은 링크 참조. (https://docs.docker.com/articles/networking/#bridge-building)

 

  


Container의 network 구조


 지금까지는 host에 docker를 설치하면 생기는 기본적인 network interface에 대한 설명이었다. 

 그렇다면 여기에 container를 하나씩 생성하게 되면 network에는 어떤 일이 일어나게 될까. 


 먼저, container는 각자만의 격리된 network 공간을 할당받게 된다. 이는 linux namespace 라는 기술을 이용하여 구현된 가상화 기법을 사용하여 각자 독립된 network 공간을 할당 받는 것이다. 


 그렇다면 이 container 마다 독립된 공간은 어떻게 외부로(또는 다른 container로) 통신을 주고 받게 될까. 


 먼저, container가 생성되면, 해당 container 에는 pair interface 라고 하는 한 쌍의 interface들이 생성되게 된다.  


[참고를 위해 위 그림을 다시..]


 pair(peer) inferface는 두개의 interface 가 한 쌍 으로 구성되는데, 이 둘은 마치 직접 direct 로 cable을 연결한 두 대의 PC와 같이 서로의 packet을 주고 받는 형태이다.

 

 container가 생성되면, 이 pair interface 의 한 쪽은 container 내부 namespace에 할당되며 우리에게 친숙한 이름인 eth0 라는 이름으로 할당된다. 그리고 나머지 하나는 vethXXXX 라는 이름으로 docker0 bridge에 binding되는 형태이다.   


 해당 내용은 namespace 와 veth interface에 대한 내용인데, 자세한 포스팅은 아래를 참고


 ( Linux namespace - NET )



 container를 하나 올린 상태에서 host의 인터페이스 상태를 보자. 


 root@~~# ip link

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default 

    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000

    link/ether 06:7a:4f:1b:ce:ad brd ff:ff:ff:ff:ff:ff

3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP mode DEFAULT group default 

    link/ether 9e:89:98:9e:9f:77 brd ff:ff:ff:ff:ff:ff

5: vethfd06149: <BROADCAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast master docker0 state UP mode DEFAULT group default qlen 1000

    link/ether 9e:89:98:9e:9f:77 brd ff:ff:ff:ff:ff:ff


root@~~# brctl show docker0

bridge name       bridge id                          STP    enabled     interfaces

docker0              8000.9e89989e9f77      no                       vethfd06149 


 위와 같이 vethXXXX 형태의 interface가 docker0 bridge 에 binding 된 상태로 생성된 것을 볼 수 있다. 

 그렇다면 container 내부에 할당된 eth0 인터페이스는 왜 안보일까?

 그것은  해당 namespace에서만 보이도록 격리되어있기 때문이다. 


 container 내부의 interface를 확인해 보려면 아래와 같은 방법을 사용하면 된다. 


 root@~~# docker exec c456623003b1 ifconfig eth0

eth0      Link encap:Ethernet  HWaddr 02:42:ac:11:00:01  

              inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0

              inet6 addr: fe80::42:acff:fe11:1/64 Scope:Link

              UP BROADCAST RUNNING  MTU:9001  Metric:1

              RX packets:8 errors:0 dropped:0 overruns:0 frame:0

              TX packets:9 errors:0 dropped:0 overruns:0 carrier:0

              collisions:0 txqueuelen:0 

              RX bytes:648 (648.0 B)  TX bytes:738 (738.0 B)


 [ docker exec 는 container 내부에 명령을 내리는 명령어이다.. ]


 보이는 것 처럼 container 안에는 외부 통신을 위한 eth0 interface가 있음을 확인할 수 있다. 

 그리고 이 interface에는 위에서 설명한 대로 172.17.0.0/16 IP대역에 해당되는 172.17.0.1 이라는 IP 가 할당되어 있으며, netmask도 255.255.0.0 으로 설정되어 있음을 확인할 수 있다. 


 그럼 container의 gateway는 무엇으로 설정될까. 

 바로 docker0 에 설정된 IP인 172.17.42.1 로 설정된다. 


root@~~# docker exec c456623003b1 route

Kernel IP routing table

Destination     Gateway              Genmask         Flags Metric  Ref    Use   Iface

default            ip-172-17-42-1.    0.0.0.0           UG     0         0        0     eth0

172.17.0.0       *                           255.255.0.0     U       0        0        0      eth0


 보이는 것처럼 container 내부의 모든 패킷은 default인 172.17.42.1 로 가게된다. 위에 설명했듯이 172.17.42.1 은 docker0의 IP이다. 







위에서 설명한 Docker의 네트워크 구조는 docker가 지원하는 방식 중 bridge 모드에 대한 설명이다. 

bridge 모드는 dokcer 네트워크의 default 설정이자 가장 많이 쓰이는 방식이다. 


만약 컨테이너의 네트워크 중 다른 방식에 대해 궁금하다면 아래 링크를 확인 하면 된다. 


( Docker Network 구조(2) - container network 방식 4가지 )



[ 참고 ] 

  • https://docs.docker.com/engine/userguide/networking/dockernetworks/


저작자 표시
신고
1 Comments
  • 프로필사진 문성호 2017.05.15 11:09 신고 좋은 글 감사합니다. 현재 버전과 맞지 않는 부분이 있어 공유를 위해 조심히 말씀드리면 docker0의 ip는 더 이상 172.17.42.1이 아닙니다.
    제 테스트환경에서는 172.17.0.1 이네요.
    https://github.com/moby/moby/issues/17305
댓글쓰기 폼