도커 네트워크 사용하기

업데이트: Link

Docker 네트워크 사용법

기본적으로 Docker 컨테이너(container)는 격리된 환경에서 돌아간다. 즉 다른 컨테이너와의 통신이 안된다.

이때 컨테이너끼리 서로 통신하기 위해 Docker 네트워크(network)가 존재한다.

네트워크 조회

docker network ls 커맨드를 사용하면 현재 생성되어 있는 Docker 네트워크 목록을 조회할 수 있다.

$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
2a3aaf5788fe        bridge              bridge              local
cb46a99f11a3        host                host                local
1868884fe808        none                null                local

bridge, host, none 세가지 네트워크는 Docker가 실행되면서 기본으로 생성하는 네트워크 이다. 하지만 프로젝트별 관리를 위해서 사용자가 직접 네트워크를 생성해서 사용하는 것이 권장된다.

네트워크 종류

Docker 네트워크는 bridge, host, overlay 등 목적에 따라 다양한 종류의 네트워크 드라이버(driver)를 지원한다.

  • bridge: 하나의 호스트 컴퓨터 내에서 컨테이너들간 소통할 수 있도록 한다.
  • host: 컨터이너를 호스트 컴퓨터와 동일한 네트워크 상에 올린다.
  • overlay: 여러 호스트에 분산되어 있는 컨테이너들 간에 연결을 위해 사용한다.

기본값은 bridge 네트워크이다.

네트워크 생성

먼저 docker network create 커맨드를 사용해서 새로운 네트워크를 생성할 수 있다.

$ docker network create test-net
f48becefa800d60700b79d6cf8e5f0c5b63b5aa7c872c0d96fe31c487e4e4d8a
$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
2a3aaf5788fe        bridge              bridge              local
cb46a99f11a3        host                host                local
1868884fe808        none                null                local
4202b83c1e48        test-net            bridge              local

추가된 네트워크는 docker network ls 커맨드로 확인할 수 있다. -d 옵션을 지정하지 않았기 때문에 기본값인 bridge 네트워크로 생성된 것을 볼 수 있다.

네트워크 상세 정보

방금 추가한 네트워크의 상세 정보를 docker network inspect 커맨드로 확인해보도록 하겠습니다.

$ docker network inspect test-net
[
    {
        "Name": "test-net",
        "Id": "8cbd714e8f0d6ba1f34cc3aa017326a2c1160c2937e09c19e1bc965695580127",
        "Created": "2023-01-29T03:37:48.785060344Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.20.0.0/16",
                    "Gateway": "172.20.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

Containers 항목에 연결된 컨테이너 정보를 볼 수 있지만 현재는 아무 것도 연결되어 있지 않다.

네트워크에 컨테이너 연결

먼저 컨테이너 하나를 test-1라는 이름으로 실행해보도록 하겠습니다.

$ docker run -itd --name test-1 busybox
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
205dae5015e7: Pull complete 
Digest: sha256:7b3ccabffc97de872a30dfd234fd972a66d247c8cfc69b0550f276481852627c
Status: Downloaded newer image for busybox:latest
9c1229d89daf963329d9bd28cf54c075db87ca59881c5c41b2954a67d94322b0

컨테이너 실행시 --network 옵션을 명시하지 않으면, bride 네트워크가 기본값으로 적용된다.

$ docker network inspect bridge
[
    {
        (... 생략)
        "Containers": {
            "9c1229d89daf963329d9bd28cf54c075db87ca59881c5c41b2954a67d94322b0": {
                "Name": "test-1",
                "EndpointID": "fd1017e6eed1a72a4edc14d63120eb7ecdbadb39afc8b30002cdefe676b18527",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
        (... 생략)
    }
]

도커 실행시 네트워크 옵션을 지정하지 않거나 잘못 지정한 경우 docker network connect 명령을 통해 연결할 수 있다.

$ docker network connect test-net test-1
$ docker network inspect test-net
[
    {
        {... 생략}
        "ConfigOnly": false,
        "Containers": {
            "9c1229d89daf963329d9bd28cf54c075db87ca59881c5c41b2954a67d94322b0": {
                "Name": "test-1",
                "EndpointID": "9ea271db68aef938f9e49a9082c287a6b8fe98bd2f4938dd341c3f55918be34c",
                "MacAddress": "02:42:ac:14:00:02",
                "IPv4Address": "172.20.0.2/16",
                "IPv6Address": ""
            }
        },
        {... 생략}
    }
]

test-net 네트워크의 정보를 다시 확인해보면 Containers 항목에 test-1 컨테이너가 추가되고 test-1 컨테이너에 IP 172.20.0.2가 할당된 것도 확인된다.

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

하나의 컨테이너는 여러 네트워크에 동시 연결이 가능하다. 처음 test-1 컨테이너를 생성할 때 bridge 네트워크에 연결되었기에, 현재 test-1 컨테이너는 test-net 네트워크와 bridge 네트워크에 동시에 연결된 상태다.

test-1 컨테이너를 bridge 네트워크로부터 연결 해제하려면 docker network disconnect 명령을 사용한다.

$ docker network disconnect bridge test-1

두번째 컨테이너 연결

네트워크에 홀로 있는 컨테이너는 큰 의미가 없을 것입니다. 하나의 컨테이너를 더 test-net 네트워크에 연결해보도록 하겠습니다.

이번에는 --network 옵션을 사용해서 컨테이너를 실행하면서 바로 연결할 네트워크를 지정해주도록 하겠습니다.

$ docker run -itd --name test-2 --network test-net busybox
69be1f129ef9847d31041c29e1c8cea3edcf7d424c187d675cc42f099c7647b3

test-net 네트워크의 상세 정보를 확인해보면 test-2 컨테이너에 IP 172.20.0.3가 할당되어 연결되어 있는 것을 확인할 수 있습니다.

$ docker network inspect test-net
[
    {
        {... 생략}
        "Containers": {
            "69be1f129ef9847d31041c29e1c8cea3edcf7d424c187d675cc42f099c7647b3": {
                "Name": "test-2",
                "EndpointID": "b3f0713705662ec7729cde73610a502c27fd11ab8ac218e646718d070c58e0e9",
                "MacAddress": "02:42:ac:14:00:03",
                "IPv4Address": "172.20.0.3/16",
                "IPv6Address": ""
            },
            "9c1229d89daf963329d9bd28cf54c075db87ca59881c5c41b2954a67d94322b0": {
                "Name": "test-1",
                "EndpointID": "9ea271db68aef938f9e49a9082c287a6b8fe98bd2f4938dd341c3f55918be34c",
                "MacAddress": "02:42:ac:14:00:02",
                "IPv4Address": "172.20.0.2/16",
                "IPv6Address": ""
            }
        },
        {... 생략}
    }
]

컨테이너 간 네트워킹

같은 bridge 안의 컨테이너들 끼리는 컨테이너명을 호스트네임처럼 사용하거나 bridge에서 할당받은 IP를 통해 접근이 가능하다.

컨테이명을 사용하여 ping 테스트를 해본다.

$ docker exec test-1 ping test-2
PING test-2 (172.20.0.3): 56 data bytes
64 bytes from 172.20.0.3: seq=0 ttl=64 time=0.117 ms
64 bytes from 172.20.0.3: seq=1 ttl=64 time=0.261 ms
64 bytes from 172.20.0.3: seq=2 ttl=64 time=0.065 ms
64 bytes from 172.20.0.3: seq=3 ttl=64 time=0.066 ms
64 bytes from 172.20.0.3: seq=4 ttl=64 time=0.095 ms
64 bytes from 172.20.0.3: seq=5 ttl=64 time=0.092 ms
64 bytes from 172.20.0.3: seq=6 ttl=64 time=0.063 ms
64 bytes from 172.20.0.3: seq=7 ttl=64 time=0.068 ms
(... 생략 ...)

bridge에서 할당받은 IP를 사용하여 ping 테스트를 해본다.

$ docker exec test-2 ping 172.20.0.2
PING 172.20.0.2 (172.20.0.2): 56 data bytes
64 bytes from 172.20.0.2: seq=0 ttl=64 time=0.102 ms
64 bytes from 172.20.0.2: seq=1 ttl=64 time=0.099 ms
64 bytes from 172.20.0.2: seq=2 ttl=64 time=0.115 ms
64 bytes from 172.20.0.2: seq=3 ttl=64 time=0.125 ms
64 bytes from 172.20.0.2: seq=4 ttl=64 time=0.105 ms
64 bytes from 172.20.0.2: seq=5 ttl=64 time=0.144 ms
64 bytes from 172.20.0.2: seq=6 ttl=64 time=0.126 ms
64 bytes from 172.20.0.2: seq=7 ttl=64 time=0.104 ms
(... 생략 ...)

네트워크 제거

docker network rm 명령어로 test-net 네트워크를 제거해보자.

$ docker network rm test-net
Error response from daemon: error while removing network: network test-net id 8cbd714e8f0d6ba1f34cc3aa017326a2c1160c2937e09c19e1bc965695580127 has active endpoints

활성화된 연결(active endpoints)이 있어 제거하는 동안 오류가 발생했다고 한다. 이 때는 네트워크에 연결된 모든 컨테이너를 먼저 중지 시키고, 네트워크를 삭제해야 한다.

$ docker stop test-1 test-2
test-1
test-2
$ docker network rm test-net
test-net

네트워크 청소

여러번의 프로젝트를 비롯한 여러 작업을 하다보면 아무 컨테이너도 연결되지 않은 불필요한 네트워크가 생기게 된다. 이때 docker network prune 명령어로 이러한 네트워크를 모두 제거할 수 있다.

$ docker network prune
WARNING! This will remove all networks not used by at least one container.
Are you sure you want to continue? [y/N] y

마무리

먼저 테스트를 위해 만든 컨테이너를 삭제하자.

$ docker rm test-1 test-2
test-1
test-1

이상으로 Docker 네트워크의 전반적인 라이프사이클에 대해서 살펴보았다. 각 커맨드에 대한 좀 더 자세한 내용은 아래 Docekr CLI 레퍼런스를 참고하기 바란다.

댓글남기기