Docker 네트워크 사용법

참조

 

소개

  • Docker 컨테이너(Container) 는 격리된 환경에서 돌아가기 때문에 기본적으로 다른 컨테이너와의 통신이 불가능합니다.
  • 하지만 여러 개의 컨테이너를 하나의 Docker 네트워크(netowrk) 에 연결시키면 서로 통신이 가능해 집니다.

 

컨테이너의 네트워크 구조

  • 만약 외부와 연결을 해야 할 경우에는 호스트에 veth(=virtual eth) 라는 네트워크 인터페이스를 생성하고 컨테이너의 eth와 연결이 됩니다.
  • veth 인터페이스는 사용자가 직접 생성할 필요 없이 도커엔진에 의해 자동으로 생성됩니다.
  • veth 인터페이스 뿐만 아니라 docker() 라는 브리지도 있는데 이는 veth 인터페이스와 바인딩 되어 호스트의 eth 인터페이스와 연결을 해줍니다.

 

네트워크 조회

  • docker network ls 커맨드를 사용하면 현재 생성되어 있는 Docker 네트워크 목록을 조회할 수 있습니다.
> docker network ls
NETWORK ID     NAME                        DRIVER    SCOPE
4a9fdf18b9a8   bridge                      bridge    local
f99ab66f7ec5   desktop_default             bridge    local
78f0ef827542   docker_oracle_default       bridge    local
0102b731df18   host                        host      local
b493c4f3027c   none                        null      local
  • bridge, host, none 은 Docker 데몬(daemon) 이 실행되면서 디폴트로 생성되는 네트워크 입니다.
  • 대부분의 경우에는 이러한 디폴트 네트워크를 이용하는 것 보다는 사용자가 직접 네트워크를 생성해서 사용하는 것을 권장합니다.

 

네트워크 유형

bridge

  • docker() 브리지와 비슷하지만 사용자가 정의한 브리지를 생성해 각 컨테이너에 연결하는 네트워크 구조로 컨테이너는 연결된 브리지를 통해 외부와 통신할 수 있습니다.
  • 보통 컨테이너가 사용하는 네트워크를 추가로 생성할 때에는 bridge 네트워크를 생성합니다.
  • 네트워크 생성 시 별도의 드라이버(bridge, host, none) 을 지정하지 않으면 default 값으로 생성되는 네트워크 입니다.

 

host

  • host 유형의 네트워크는 호스트의 네트워크를 공유합니다.
  • 컨테이너 내부의 어플리케이션을 별도의 포트 포워딩 없이 바로 서비스 할 수 있습니다.

 

none

  • 컨테이너에 어떤 네트워크도 할당하지 않습니다.
  • 외부와 단전됩니다.

 

네트워크 생성

  • docker network create 커맨드 명령을 사용하여 새로운 Docker 네트워크를 생성합니다.
> docker network create our-net
6531dbe9f1eaece4f58afbaf03759b3c7ceb8f960f5ace98a8bd1e2fb78abb00

> docker network ls
NETWORK ID     NAME                        DRIVER    SCOPE
4a9fdf18b9a8   bridge                      bridge    local
f99ab66f7ec5   desktop_default             bridge    local
78f0ef827542   docker_oracle_default       bridge    local
0102b731df18   host                        host      local
786bfdaf9470   jobeomheegithubio_default   bridge    local
b493c4f3027c   none                        null      local
-6531dbe9f1ea   our-net                     bridge    local
  • 추가된 네트워크는 docker network ls 커맨드 명령어를 통해 확인할 수 있습니다.
  • -d 옵션을 사용하지 않았기 때문에 기본값인 bridge 네트워크로 생성된 것을 확인할 수 있습니다.

 

네트워크 상세 정보

  • 앞서 추가한 네트워크의 상세 정보를 확인합니다.
  • docker network inspect 커맨드 명령어를 통해 확인할 수 있습니다.
  • 아래 Containers 항목을 보면 out-net 네트워크에 아무 컨테이너도 아직 연결되지 않은 것을 확인할 수 있습니다.
> docker network inspect our-net
[
    {
        "Name": "our-net",
        "Id": "6531dbe9f1eaece4f58afbaf03759b3c7ceb8f960f5ace98a8bd1e2fb78abb00",
        "Created": "2022-03-31T23:27:43.0542847Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.21.0.0/16",
                    "Gateway": "172.21.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

 

네트워크에 컨테이너 연결

  • 먼저 컨테이너 하나를 one 이라는 이름으로 실행해 보도록 하겠습니다.
> docker run -itd --name one busybox
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
554879bb3004: Pull complete
Digest: sha256:caa382c432891547782ce7140fb3b7304613d3b0438834dce1cad68896ab110a
Status: Downloaded newer image for busybox:latest
afd8bad9cf9e6fb4b1443669e00666093562d00c4416bebccb85715069aba918
  • 컨테이너를 실행할 때 --network 옵션을 명시해주지 않으면, 기본적으로 bridge 라는 이름의 디폴트 네트워크에 붙게 됩니다.
> docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "4a9fdf18b9a8e60730728fedc255285a6d8965b08e1c4cedd7e88ce9aad02914",
        "Created": "2022-03-31T22:05:28.2450003Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "afd8bad9cf9e6fb4b1443669e00666093562d00c4416bebccb85715069aba918": {
                "Name": "one",
                "EndpointID": "0b3908706bb9e4edb9a8e07f784018cbd7a1c3e8d14c845d9f5ce9e3c72eee23",
                "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": {}
    }
]

one 컨테이너 out-net 네트워크에 연결하기

  • one 컨테이너를 위에서 생성한 our-net 네트워크에 연결해 보도록 하겠습니다.
  • DOcker 네트워크에 컨테이너를 연결할 때에는 docker network connect 커맨드 명령어를 사용합니다.
> docker network connect out-net one
  • out-net 네트워크의 상세 정보를 다시 확인해보면 Containers 항목에 one 컨테이너가 추가된 것을 확인할 수 있습니다.
  • one 컨테이너에 IP 172.21.0.2 가 할당된 것을 확인할 수 있습니다.
> docker network inspect our-net
[
    {
        "Name": "our-net",
        "Id": "6531dbe9f1eaece4f58afbaf03759b3c7ceb8f960f5ace98a8bd1e2fb78abb00",
        "Created": "2022-03-31T23:27:43.0542847Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.21.0.0/16",
                    "Gateway": "172.21.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "afd8bad9cf9e6fb4b1443669e00666093562d00c4416bebccb85715069aba918": {
                "Name": "one",
                "EndpointID": "600660015dfd54b9d0ebc9f97f729dd019912d169d807709aaa5c28cf495611c",
                "MacAddress": "02:42:ac:15:00:02",
                "IPv4Address": "172.21.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

 

네트워크로부터 컨테이너 연결 해제

  • 하나의 컨테이너는 여러 개의 네트워크에 동시에 연결할 수 있습니다.
  • 최초에 one 컨테이너를 생성할 때 bridge 네트워크에 붙었기 때문에, 현재 one 컨테이너는 out-net 네트워크와 bridge 네트워크에 동시에 붙어있게 됩니다.
  • one 컨테이너를 bridge 네트워크로부터 때어 내도록 합니다.
  • Docker 네트워크로부터 컨테이너의 연결을 끊을 떄는 docker network disconnect 커맨드 명령을 사용합니다.
> docker network disconnect bridge one

 

두번째 컨테이너 생성 및 연결

  • 네트워크에 홀로 있는 컨테이너는 큰 의미가 없습니다.
  • 하나의 컨테이너를 실행하여 out-net 네트워크에 연결하도록 합니다.
  • 이번에는 --network 옵션을 사용해서 컨테이너를 실행하면서 바로 연결할 네트워크를 지정해 주도록 합니다.
> docker run -itd --name two --network our-net busybox
5f1f0c70ea7bdd6b0b696f340b023b0017751dc10fed9c4b61b220c5a958c59e
  • out-net 네트워크의 상세 정보를 확인해보면 two 컨테이너에 IP 172.21.0.3 이 할당되어 연결되어 있는 것을 확인할 수 있습니다.
> docker network inspect our-net
[
    {
        "Name": "our-net",
        "Id": "6531dbe9f1eaece4f58afbaf03759b3c7ceb8f960f5ace98a8bd1e2fb78abb00",
        "Created": "2022-03-31T23:27:43.0542847Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.21.0.0/16",
                    "Gateway": "172.21.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "5f1f0c70ea7bdd6b0b696f340b023b0017751dc10fed9c4b61b220c5a958c59e": {
                "Name": "two",
                "EndpointID": "fbf880b0ada77c3bdcd87a2e27ed9b8c19f294eeb8ef0adc8ffd4468a892daf3",
                "MacAddress": "02:42:ac:15:00:03",
                "IPv4Address": "172.21.0.3/16",
                "IPv6Address": ""
            },
            "afd8bad9cf9e6fb4b1443669e00666093562d00c4416bebccb85715069aba918": {
                "Name": "one",
                "EndpointID": "600660015dfd54b9d0ebc9f97f729dd019912d169d807709aaa5c28cf495611c",
                "MacAddress": "02:42:ac:15:00:02",
                "IPv4Address": "172.21.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

 

컨테이너간 네트워킹

  • 앞에서 one, two 2개의 컨테이너를 생성하였고, out-net 네트워크에 추가하였습니다.
  • 이제 실제로 2개의 컨테이너가 네트워크를 통해 서로 소통이 가능한지 테스트 진행합니다.
  • 먼저 one 컨테이너에서 two 컨테이너를 상대로 ping 명령어를 날려 보겠습니다.
> docker exec one ping two
PING two (172.21.0.3): 56 data bytes
64 bytes from 172.21.0.3: seq=0 ttl=64 time=0.070 ms
64 bytes from 172.21.0.3: seq=1 ttl=64 time=0.058 ms
64 bytes from 172.21.0.3: seq=2 ttl=64 time=0.042 ms
64 bytes from 172.21.0.3: seq=3 ttl=64 time=0.040 ms
  • 반대로 two 컨테이너에서 one 컨테이너를 상대로 ping 명령어는 날립니다.
PING 172.21.0.2 (172.21.0.2): 56 data bytes
64 bytes from 172.21.0.2: seq=0 ttl=64 time=0.069 ms
64 bytes from 172.21.0.2: seq=1 ttl=64 time=0.068 ms
64 bytes from 172.21.0.2: seq=2 ttl=64 time=0.240 ms
64 bytes from 172.21.0.2: seq=3 ttl=64 time=0.054 ms

 

네트워크 제거

  • docker network rm 커맨드 명령어를 사용해서 네트워크를 제거할 수 있습니다.
> docker network rm our-net
Error response from daemon: error while removing network: network our-net id e6dfe4a9a5ec85abcb484662c30a3a0fc76df217dde76d52fac39fae8412ca68 has active endpoints
  • 현재 위 에러는 네트워크 상에서 실행 중인 컨테이너가 있기 때문에 제거하지 못하는 것입니다.
  • 먼저 해당 네트워크에 연결되어 실행중인 모든 컨테이너를 중지 시키고, 다음으로 네트워크를 삭제 해야 합니다.
$ docker stop one two
one
two
$ docker network rm our-net
our-net
728x90

이 글을 공유하기

댓글

Designed by JB FACTORY