ㅍㅍㅋㄷ

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

IT/Docker

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

클쏭 2016. 5. 20. 14:30

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






Container 를 생성할때 지원되는 network 방식은 크게 4가지 이다. 

아래 명령으로 지원되는 network 방식을 확인해 볼 수 있다. 

(아래는 driver로 구분하기 때문에 3개만 확인된다)


root@~~# docker network ls

NETWORK ID          NAME                DRIVER

d67644abcd92        bridge              bridge              

edde2591745c        host                host                

614813065d4b        none                null 


default 설정은 bridge 방식이다. 

만약 다른 방식으로 컨테이너를 생성하고 싶다면 --net 을 이용하여 option을 주면 된다.


root@~~# docker run --net=NETWORK_TYPE .....


이제, network 방식에 대해 하나하나 자세히 알아보자. 







1. bridge


docker의 기본 network 방식은 bridge 이다. 

docker daemon을 실행하면 먼저 docker0 라는 bridge가 생성된다. 

컨테이너 생성하게 되면, 각 컨테이너 마다 고유한 network namespace 영역이 하나씩 생성되며, 

이때 docker0 bridge에 container의 인터페이스들이 하나씩 binding 되는 구조이다. 


bridge 모드에 대한 자세한 정보를 보고 싶다면 아래와 같이 확인이 가능하다. 


root@~~# docker network inspect bridge

[

    {

        "Name": "bridge",

        "Id": "d67644abcd92863f099e4fcb093b35c29a72a539aaa690c4feeed5cd01d6e5d5",

        "Scope": "local",

        "Driver": "bridge",

        "EnableIPv6": false,

        "IPAM": {

            "Driver": "default",

            "Options": null,

            "Config": [

                {

                    "Subnet": "172.17.0.0/16"

                }

            ]

        },

        "Internal": false,

        "Containers": {

            "8aadfb1607f5065070b96cbe5e4259312038cc0e53b2ba62e4ea9da805691574": {

                "Name": "desperate_volhard",

                "EndpointID": "3d6f1fa5dbfe95e02d461decc8b05cbce4cba30a902db04f43c1b5579902f2dd",

                "MacAddress": "02:42:ac:11:00:02",

                "IPv4Address": "172.17.0.2/16",

                "IPv6Address": ""

            }

        },

        "Options": {

            "com.docker.network.bridge.default_bridge": "true",

            "com.docker.network.bridge.enable_icc": "true",

            "com.docker.network.bridge.enable_ip_masquerade": "true",

            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",

            "com.docker.network.bridge.name": "docker0",

            "com.docker.network.driver.mtu": "1500"

        },

        "Labels": {}

    }

]

    

자세한 설명은 이전 포스팅을 참고 하면 된다. 

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



2. host


host 방식으로 컨테이너를 생성하면, 컨테이너가 독립적인 네트워크 영역을 갖지 않고 host와 네트워크를 함께 사용하게 된다. 

(네트워크 외 다른 환경은 기존과 동일하다)


컨테이너 생성시 --net=host 옵션을 이용하면 된다. 


root@~~# docker run --net=host httpd web01

CONTAINER ID        IMAGE               COMMAND               CREATED                    STATUS                PORTS              NAMES

a2141f8e7fe8           httpd                "httpd-foreground"   About a minute ago   Up 7 seconds                                  web01



컨테이너의 ip 와 interface 정보를 확인해 보면 아래와 같이 host의 네트워크 정보와 동일하다.


root@~~# docker exec web01 ip addr show

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

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

    inet 127.0.0.1/8 scope host lo

       valid_lft forever preferred_lft forever

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

    link/ether fa:16:3e:ee:2e:ef brd ff:ff:ff:ff:ff:ff

    inet 192.168.2.58/24 brd 192.168.2.255 scope global eth0

       valid_lft forever preferred_lft forever

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

    link/ether 02:42:1d:b1:77:69 brd ff:ff:ff:ff:ff:ff

    inet 172.17.0.1/16 scope global docker0

       valid_lft forever preferred_lft forever


host 옵션으로 생성된 컨테이너의 경우는 bridge 를 사용하지 않으므로 아래와 같이 docker0 에 바인딩 되지 않는다. 


root@~~# brctl show

bridge name      bridge id                          STP    enabled    interfaces

docker0              8000.02421db17769      no



참고로 docker network inspect 명령어로 살펴보면 아래와 같다. 


root@~~# docker network inspect host

[

    {

        "Name": "host",

        "Id": "edde2591745c661ba8f2b22622d290aaa496027d89904867079a5b882587f388",

        "Scope": "local",

        "Driver": "host",

        "EnableIPv6": false,

        "IPAM": {

            "Driver": "default",

            "Options": null,

            "Config": []

        },

        "Internal": false,

        "Containers": {

            "a2141f8e7fe8fa160546bb3a5e2f7b75febd466088666725577ce80e82e6ae5e": {

                "Name": "web01",

                "EndpointID": "bfac2ade635bf3ac5f5c10e0b548788c4dd7fa91d864c75497127a88eaab619f",

                "MacAddress": "",

                "IPv4Address": "",

                "IPv6Address": ""

            }

        },

        "Options": {},

        "Labels": {}

    }

]


Containers 에 web01 정보가 있지만 네트워크 환경을 따로 가지고 있지 않기 때문에 IP 정보는 없다. 





3. container


이 방식으로 생성된 컨테이너는 기존에 존재하는 다른 컨테이너의 network 환경을 공유하게 된다. 

아래의 예를 보자. 


먼저 web02 라는 이름으로 httpd 컨테이너를 생성 했다. 


root@~~# docker run --name web02 -d httpd

e1b4a085348ec8084b1c32d106eb66383a1fe18aa80b821d30181064d704574a

root@~~#

root@~~#

root@~~# docker ps -a

CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS               NAMES

e1b4a085348e        httpd               "httpd-foreground"   3 seconds ago       Up 2 seconds        80/tcp              web02


그리고 여기에 web03 이라는 컨테이너를 생성할때 web02 컨테이너의 network 환경과 공유하게 만들어 보자. 

옵션으로 --net=container:CONTAINER_ID 를 주면 된다. 


root@~~# docker run --name web03 --net=container:e1b4a085348e -d httpd

9571bc692f5d1143f8f97da229b6cc4850477209b168cf7e5d5f43165b08f250

root@~~#

root@~~#

root@~~# docker ps -a

CONTAINER ID        IMAGE               COMMAND              CREATED              STATUS              PORTS               NAMES

9571bc692f5d        httpd               "httpd-foreground"   51 seconds ago       Up 50 seconds                           web03

e1b4a085348e        httpd               "httpd-foreground"   About a minute ago   Up About a minute   80/tcp              web02


위와 같이 web03 컨테이너가 생성되었다. 

하지만 web03 컨테이너는 따로 IP를 갖지 않으며 web02와 같은 IP와 MAC 주소를 볼 수 있다.


root@~~# docker exec web02 ip addr show

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

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

    inet 127.0.0.1/8 scope host lo

       valid_lft forever preferred_lft forever

    inet6 ::1/128 scope host 

       valid_lft forever preferred_lft forever

26: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 

    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff

    inet 172.17.0.2/16 scope global eth0

       valid_lft forever preferred_lft forever

    inet6 fe80::42:acff:fe11:2/64 scope link 

       valid_lft forever preferred_lft forever




root@~~# docker exec web03 ip addr show

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

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

    inet 127.0.0.1/8 scope host lo

       valid_lft forever preferred_lft forever

    inet6 ::1/128 scope host 

       valid_lft forever preferred_lft forever

26: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 

    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff

    inet 172.17.0.2/16 scope global eth0

       valid_lft forever preferred_lft forever

    inet6 fe80::42:acff:fe11:2/64 scope link 

       valid_lft forever preferred_lft forever



bridge 를 확인해 봐도 web03 인터페이스는 찾아볼 수 없다. web03은 따로 네트워크 환경을 할당하지 않았기 때문이다. 

아래 brctl 명령으로 확인되는 interface는 web02의 interface 이다. 

web03의 interface는 없다는 것을 알 수 있다. 


root@~~# brctl show

bridge name bridge id STP enabled interfaces

docker0 8000.02421db17769 no vetha561199


network inspect 도 마찬가지다. 


root@~~# docker network inspect bridge

[

    {

        "Name": "bridge",

        "Id": "d67644abcd92863f099e4fcb093b35c29a72a539aaa690c4feeed5cd01d6e5d5",

        "Scope": "local",

        "Driver": "bridge",

        "EnableIPv6": false,

        "IPAM": {

            "Driver": "default",

            "Options": null,

            "Config": [

                {

                    "Subnet": "172.17.0.0/16"

                }

            ]

        },

        "Internal": false,

        "Containers": {

            "e1b4a085348ec8084b1c32d106eb66383a1fe18aa80b821d30181064d704574a": {

                "Name": "web02",

                "EndpointID": "dea21451989fffec57a040c8223e15cec52c6482e116177fe590e0de455f549a",

                "MacAddress": "02:42:ac:11:00:02",

                "IPv4Address": "172.17.0.2/16",

                "IPv6Address": ""

            }

        },

        "Options": {

            "com.docker.network.bridge.default_bridge": "true",

            "com.docker.network.bridge.enable_icc": "true",

            "com.docker.network.bridge.enable_ip_masquerade": "true",

            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",

            "com.docker.network.bridge.name": "docker0",

            "com.docker.network.driver.mtu": "1500"

        },

        "Labels": {}

    }

]




4. none


--net=none 옵션으로 컨테이너를 생성하면 격리된 네트워크 영역을 갖긴 하지만, 인터페이스가 없는 상태로 컨테이너를 생성하게 된다. 


root@~~# docker run --name web04 --net=none -d httpd

8b7108a18ff2f95798a912e70eee7c3e1ab910d4f3a5a20a45b192d34cf8e147


생성된 컨테이너의 인터페이스 정보를 보자. 


root@~~# docker exec web04 ip addr show

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

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

    inet 127.0.0.1/8 scope host lo

       valid_lft forever preferred_lft forever

    inet6 ::1/128 scope host 

       valid_lft forever preferred_lft forever


위처럼 loopback 인터페이스만 있고, 통신을 위한 eth0 인터페이스는 없다. 

당연히 bridge에도 연결되지 않은 상태이며, 이 상태로는 외부 통신이 불가하다. 


이 옵션을 만든 이유는, 아마도 인터페이스를 직접 커스터마이징 할 수 있도록 네트워크 환경이 clear 한 상태로 만들 수 있도록 한 것 같다. 








Comments