본문 바로가기
프로그래밍/도커

도커의 네트워크 (브릿지, 호스트, 논)

by Hwan2 2023. 3. 14.
반응형

 

 

 

 

 

Docker로 Container를 만들면 기본적인 네트워크가 만들어집니다.

각 컨테이너마다 가상 네트워크 인터페이스를 만드는데, 이 인터페이스는 veth로 시작합니다.

그리고 veth로 시작하는 인터페이스는 각 컨테이너마다 생성되게 됩니다.

[root@ip-172-31-11-2 overlay]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED             STATUS             PORTS                 NAMES
9b771db5bd22   mysql     "docker-entrypoint.s…"   About an hour ago   Up About an hour   3306/tcp, 33060/tcp   reverent_hypatia
73d16586cf36   ubuntu    "/bin/bash"              26 hours ago        Up 41 seconds                            awesome_proskuriakova

[root@ip-172-31-11-2 overlay]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    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
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 02:2f:9d:a1:a5:f0 brd ff:ff:ff:ff:ff:ff
    inet 172.31.11.2/20 brd 172.31.15.255 scope global dynamic eth0
       valid_lft 2518sec preferred_lft 2518sec
    inet6 fe80::2f:9dff:fea1:a5f0/64 scope link 
       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:7b:be:21:07 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:7bff:febe:2107/64 scope link 
       valid_lft forever preferred_lft forever
23: veth07288be@if22: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 0e:0f:82:56:84:f3 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::c0f:82ff:fe56:84f3/64 scope link 
       valid_lft forever preferred_lft forever
25: veth3353184@if24: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether ce:b7:eb:57:59:88 brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet6 fe80::ccb7:ebff:fe57:5988/64 scope link 
       valid_lft forever preferred_lft forever

 

그리고 docker0라는 브릿지가 default로 생성되게 되는데,

각 도커의 veth 인터페이스는 해당 브릿지에 연결되어 호스트와 통신하게 됩니다. 정확히는 eth0와 연결되죠.

 

 

그 중 기본적으로 많이 사용되는 bridge, host, none 네트워크 드라이버에 대해 설명해보고자 합니다.

 

1. Bridge

브리지의 특징은 호스트 네트워크와 Port mapping으로 외부와 통신이 가능한 점입니다.

 

docker network create --driver 명령어를 통해 만들 수 있습니다.

만드는 방법과 사용 방법은 다음과 같습니다.

[root@ip-172-31-11-2 overlay]# docker network create --driver bridge hwanBridge
ddda023d4a316908941836b10457f5294e31fe7d15d19a69c7aba78bf8554072
[root@ip-172-31-11-2 overlay]# docker run -it --name hwan_ubuntu --net hwanBridge ubuntu
root@0473a8af6c89:/#

 

적용된 것을 확인해보면 다음과 같습니다.

[root@ip-172-31-11-2 ec2-user]# docker inspect hwan_ubuntu --format '{{json .NetworkSettings.Networks}}' | jq
{
  "hwanBridge": {
    "IPAMConfig": null,
    "Links": null,
    "Aliases": [
      "0473a8af6c89"
    ],
    "NetworkID": "ddda023d4a316908941836b10457f5294e31fe7d15d19a69c7aba78bf8554072",
    "EndpointID": "",
    "Gateway": "",
    "IPAddress": "",
    "IPPrefixLen": 0,
    "IPv6Gateway": "",
    "GlobalIPv6Address": "",
    "GlobalIPv6PrefixLen": 0,
    "MacAddress": "",
    "DriverOpts": null
  }
}

[root@ip-172-31-11-2 ec2-user]# docker network inspect hwanBridge
[
    {
        "Name": "hwanBridge",
        "Id": "ddda023d4a316908941836b10457f5294e31fe7d15d19a69c7aba78bf8554072",
        "Created": "2023-03-13T13:48:24.380347662Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.19.0.0/16",
                    "Gateway": "172.19.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

 

또한 네트워크 인터페이스를 실시간으로 끊고, 다른걸 연결할 수 있습니다.

명령어는 docker network disconnect 입니다.

 

사용법은 다음과 같습니다.

[root@ip-172-31-11-2 ec2-user]# docker network disconnect hwanBridge hwan_ubuntu
[root@ip-172-31-11-2 ec2-user]# docker inspect hwan_ubuntu --format '{{json .NetworkSettings.Networks}}' | jq
{}
[root@ip-172-31-11-2 ec2-user]# docker network create --driver bridge guguBridge
e5af7e82470808f00ca70ab30b83204716014580399a44da229af65c0cac4f8c
[root@ip-172-31-11-2 ec2-user]# docker network connect guguBridge hwan_ubuntu
[root@ip-172-31-11-2 ec2-user]# docker inspect hwan_ubuntu --format '{{json .NetworkSettings.Networks}}' | jq
{
  "guguBridge": {
    "IPAMConfig": {},
    "Links": null,
    "Aliases": [
      "0473a8af6c89"
    ],
    "NetworkID": "",
    "EndpointID": "",
    "Gateway": "",
    "IPAddress": "",
    "IPPrefixLen": 0,
    "IPv6Gateway": "",
    "GlobalIPv6Address": "",
    "GlobalIPv6PrefixLen": 0,
    "MacAddress": "",
    "DriverOpts": {}
  }
}

뿐만 아니라 subnet, ip cidr, gateway를 지정해줄 수 있습니다.

하지만 subnet 대역에 벗어난 ip cidr이나 gateway로 만들경우 브리지 자체가 생성이 안되기 때문에 유의하시기 바랍니다.

 

브리지 모드의 장점은 컨테이너 간의 통신이 용이하고, 격리된 네트워크를 구성할 수 있다는 점입니다.

2. 호스트

호스트 네트워크는 호스트의 네트워크 환경을 그대로 쓸 수 있습니다. 

즉, Port mapping 같은 작업이 필요없고, Network driver도 별도로 생성해줄 필요가 없습니다.

 

사용 방법은 다음과 같습니다.

[root@ip-172-31-11-2 ec2-user]# docker run -it --name hwan_ubuntu --net host ubuntu

[root@ip-172-31-11-2 ec2-user]# docker inspect hwan_ubuntu --format '{{json .NetworkSettings.Networks}}' | jq
{
  "host": {
    "IPAMConfig": null,
    "Links": null,
    "Aliases": null,
    "NetworkID": "2e0366c607fce9927eb06ce64993f2963fbf5e41a2c6d86eef61e56c49b2153b",
    "EndpointID": "",
    "Gateway": "",
    "IPAddress": "",
    "IPPrefixLen": 0,
    "IPv6Gateway": "",
    "GlobalIPv6Address": "",
    "GlobalIPv6PrefixLen": 0,
    "MacAddress": "",
    "DriverOpts": null
  }
}

 

해당 방식은 public하게 공게되도 괜찮은 서버 같은 경우에 사용할 수 있습니다.

하지만 이 방식은 권장하고 있지는 않습니다. 호스트의 네트워크 인터페이스를 그대로 사용하기 때문에 보안적으로 취약할 수 있습니다.

 

하지만 장점은 wireshark같으거로 패킷을 실시간으로 확인할 수 있으며, 특정 상황에서 더 많은 트래픽을 감당할 수 있다고 합니다.

또한 클라이언트로 부터 접속되는, 혹은 컨테이너로부터 나갈 때 포트를 특정할 수 없다면 해당 모드가 유용해 보입니다.

 

3. None

none모드는 외부, 내부의 통신을 모두 차단합니다.

따라서 완벽한 격리모드에서 컨테이너를 실행할 수 있습니다.

 

사용방법은 다음과 같습니다.

docker run --network=none ubuntu

 

ip주소를 확인해보면 다음과 같습니다.

root@7852483a43ea:/# hostname -I


[root@ip-172-31-11-2 ec2-user]# docker inspect hungry_archimedes --format '{{json .NetworkSettings.Networks}}' | jq
{
  "none": {
    "IPAMConfig": null,
    "Links": null,
    "Aliases": null,
    "NetworkID": "4374e1e464bcefc1e5a6acef49f529c352bdd9cf85f27ab46008584f66c4fc5b",
    "EndpointID": "957e28fa7dd6cd8c2c51115590da1e63919e96b67d7508e12426f4b31edeede9",
    "Gateway": "",
    "IPAddress": "",
    "IPPrefixLen": 0,
    "IPv6Gateway": "",
    "GlobalIPv6Address": "",
    "GlobalIPv6PrefixLen": 0,
    "MacAddress": "",
    "DriverOpts": null
  }
}

 

hostname -I 를 했을 때 출력되는 IP주소는 없으며 docker inspect로 확인해도 결과는 같습니다.

 

이 모드는 높은 보안성을 띄지만, 유연하지 못한 단점이 있습니다.

찾아보니 주로 로그나 배치 작업할 때 사용한다고 하는데.... 

가급적 해당 모드를 추천하지 않는다고 합니다.

 

 

반응형

댓글


스킨편집 -> html 편집에서