Skip to content

5. Docker Compose 네트워크


1. Docker Network

1) Docker 네트워크 인터페이스 - docker0

  • Docker 네트워크 인터페이스의 정보는 다음과 같다.


ifconfig docker0
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:9cff:fec7:af31  prefixlen 64  scopeid 0x20<link>
        ether 02:42:9c:c7:af:31  txqueuelen 0  (Ethernet)
        RX packets 21447902  bytes 3811442984 (3.8 GB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 31441811  bytes 63773840015 (63.7 GB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


  • 위의 내용이 의미하는 바를 간단하게 표현하면 다음과 같다.


1] 이름은 docker0이다.

2] IPv4 주소는 172.17.0.1이다.

3] Netmask는 255.255.0.0이며, IPv4 기준 CIDR은 172.17.0.1/16이다.

4] Broadcast는 172.17.255.255이다.


  • IPv4 주소 및 Netmask가 172.17.0.1/16인 것으로 보아 이 네트워크 인터페이스로부터 생성되는 IP의 Gateway는 172.17.0.1인 것을 직관적으로 알 수 있다.
  • 즉, 이 네트워크 인터페이스를 따르는 컨테이너들의 Gateway 주소가 172.17.0.1이 된다는 것이다.


2) Docker 컨테이너 test1

  • 위의 내용을 확인하기 위해 컨테이너 test1test2를 생성해 보자.


sudo docker run -d -p 1234:80 --name test1 nginx:latest
sudo docker run -d -p 1235:80 --name test2 nginx:latest


  • 먼저, 컨테이너 test1ifconfigroute 명령어를 실행한 결과이다.


ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
        RX packets 4252  bytes 9003641 (8.5 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3525  bytes 276495 (270.0 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         172.17.0.1      0.0.0.0         UG    0      0        0 eth0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 eth0


  • 위의 내용이 의미하는 바를 간단하게 표현하면 다음과 같다.


1] 이름은 eth0이다.

2] IPv4 주소는 172.17.0.2이다.

3] Netmask는 255.255.0.0이며, IPv4 기준 CIDR은 172.17.0.2/16이다.

4] Broadcast는 172.17.255.255이다.

5] Gateway는 172.17.0.1이다.


3) Docker 컨테이너 test2

  • 그 다음, 컨테이너 test2ifconfigroute의 결과이다.


ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.3  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:03  txqueuelen 0  (Ethernet)
        RX packets 4908  bytes 9055109 (8.6 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 4264  bytes 352221 (343.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         172.17.0.1      0.0.0.0         UG    0      0        0 eth0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 eth0


  • 위의 내용이 의미하는 바를 간단하게 표현하면 다음과 같다.


1] 이름은 eth0이다.

2] IPv4 주소는 172.17.0.3이다.

3] Netmask는 255.255.0.0이며, IPv4 기준 CIDR은 172.17.0.3/16이다.

4] Broadcast는 172.17.255.255이다.

5] Gateway는 172.17.0.1이다.


4) Docker 네트워크 인터페이스 결과 정리

  • 컨테이너 test1test2의 네트워크를 확인한 결과 모두 Gateway는 172.17.0.1을 공유하며, 각자의 IPv4가 자동으로 할당된 것을 확인할 수 있다.
  • 각자의 IPv4를 가진 이유는 네트워크 docker0의 Netmask가 255.255.0.0(CIDR /16)이기 때문이다.
  • 계산이 맞다면 254번째 컨테이너(172.17.0.255)가 생성된 후 255번 째 컨테이너가 생성되면 172.17.1.0부터 시작된다는 것을 알 수 있다.
  • 물론 하단의 참조 링크를 확인해 보면 알 수 있듯이, Docker 네트워크 드라이버가 host, none 등의 것일 경우 결과는 다를 수 있다.
  • 하지만 기본적으로 별다른 설정을 하지 않으면 bridge 방식으로 네트워크를 할당하기 때문에 크게 신경쓰지 않아도 상관없다.


2. Docker Compose Network

  • Docker Compose를 이용하여 네트워크를 구성하는 경우를 보자.
  • 먼저, compose1compose2라는 디렉터리를 생성한다.


mkdir compose1
mkdir compose2


  • 각 디렉터리에 Docker Compose를 위한 docker-compose.yml 파일을 동일하게 생성한다.
  • 이때 docker-compose.ymlversion3.8이다.


1) Docker Compose compose1

  • 먼저 compose1docker-compose.yml 파일이다.


./compose1/docker-compose.yml
version: "3.8"

services:
  compose1_proxy:
    container_name: "compose1_proxy"
    image: nginx:latest
    restart: always
    ports:
      - "6002:80"
    working_dir: /
    networks:
      net:
        ipv4_address: 172.18.0.2

networks:
  net:
    ipam:
      driver: default
      config:
        - subnet: "172.18.0.0/16"
          gateway: "172.18.0.1"


  • compose1 디렉터리에서 다음 명령어를 실행한다.


sudo docker-compose -p compose1 up -d


2) Docker Compose compose2

  • 그 다음, compose2docker-compose.yml 파일이다.
  • ports는 다르게 지정한다.


./compose2/docker-compose.yml
version: "3.8"

services:
  compose2_proxy:
    container_name: "compose2_proxy"
    image: nginx:latest
    restart: always
    ports:
      - "6003:80"
    working_dir: /
    networks:
      net:
        ipv4_address: 172.19.0.2

networks:
  net:
    ipam:
      driver: default
      config:
        - subnet: "172.19.0.0/16"
          gateway: "172.19.0.1"


  • compose2 디렉터리에서 다음 명령어를 실행한다.


sudo docker-compose -p compose2 up -d


3) Docker Network 확인

  • Docker Network가 어떻게 생성되었는지 확인하기 위해 다음 명령어를 실행한다.


sudo docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
a05b88e95a12        bridge              bridge              local
4c5658ccacf3        compose1_net        bridge              local
b5ffb52b02e9        compose2_net        bridge              local
d664e9b8f859        host                host                local
10135e907436        none                null                local


  • 먼저, compose1_net의 상세 내용을 확인해 보자.


sudo docker network inspect compose1_net
[
    {
        "Name": "compose1_net",
        "Id": "4c5658ccacf32caf095e48506a1e7bb768c317fd9bc0fac14ad55f24b90b38b1",
        "Created": "2022-03-23T01:17:49.113749369+09:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": true,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "bddbb154a4d026f9da5be93863db0758cb5c223a7ba6b73d967dbaacac1a1226": {
                "Name": "compose1_proxy",
                "EndpointID": "ad3d031299dca17df7ba23115d4470894792dba3e588b908c9fd226ada5058c7",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {
            "com.docker.compose.network": "net",
            "com.docker.compose.project": "compose1",
            "com.docker.compose.version": "1.29.2"
        }
    }
]


  • 그 다음, compose2_net의 상세 내용을 확인해 보자.


sudo docker network inspect compose2_net
[
    {
        "Name": "compose2_net",
        "Id": "b5ffb52b02e9303cac4d7da1ee8cfa63443ef784dc651261e51ac40952d2f6c5",
        "Created": "2022-03-23T01:18:01.796268097+09:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.19.0.0/16",
                    "Gateway": "172.19.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": true,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "48c49a0c3d972654604ce46e9f3e9d58332561d4c3e2f428e4f1c6312a60517c": {
                "Name": "compose2_proxy",
                "EndpointID": "f733d82d6ab08b231aedb103be1cbb5792c3084366678a604b9329fa5bee438d",
                "MacAddress": "02:42:ac:13:00:02",
                "IPv4Address": "172.19.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {
            "com.docker.compose.network": "net",
            "com.docker.compose.project": "compose2",
            "com.docker.compose.version": "1.29.2"
        }
    }
]


  • 위의 내용이 의미하는 바를 간단하게 표현하면 다음과 같다.


1] compose1_net

  • 네트워크 드라이버는 bridge이다.
  • IPAM(IP Address Management)의 드라이버 명은 default인데 즉, bridge 네트워크 드라이버를 따라간다.
  • Subnet은 172.18.0.0/16이다.
  • Gateway는 172.18.0.1이다.
  • 현재 네트워크에 존재하는 컨테이너의 이름은 compose1_proxy이다.
  • compose1_proxy의 IPv4는 172.18.0.2/16이다.

2] compose2_net

  • 네트워크 드라이버는 bridge이다.
  • IPAM(IP Address Management)의 드라이버 명은 default인데 즉, bridge 네트워크 드라이버를 따라간다.
  • Subnet은 172.19.0.0/16이다.
  • Gateway는 172.19.0.1이다.
  • 현재 네트워크에 존재하는 컨테이너의 이름은 compose2_proxy이다.
  • compose2_proxy의 IPv4는 172.19.0.2/16이다.


4) Docker 확인

  • 이런 상황에서 각 컨테이너의 정보는 다음과 같이 확인된다.


sudo docker ps -a
CONTAINER ID        IMAGE                            COMMAND                  CREATED             STATUS                       PORTS                                   NAMES
48c49a0c3d97        nginx:latest                     "/docker-entrypoint.…"   17 minutes ago      Up 17 minutes                0.0.0.0:6003->80/tcp, :::6003->80/tcp   compose2_proxy
bddbb154a4d0        nginx:latest                     "/docker-entrypoint.…"   17 minutes ago      Up 17 minutes                0.0.0.0:6002->80/tcp, :::6002->80/tcp   compose1_proxy


3. 추가 테스트

  • 만약 각각의 docker-compose.yml에서 gateway 정보를 지우면 어떻게 되는지 확인해 보자.


1) Docker Compose compose1

  • 먼저 compose1docker-compose.yml 파일이다.


./compose1/docker-compose.yml
version: "3.8"

services:
  compose1_proxy:
    container_name: "compose1_proxy"
    image: nginx:latest
    restart: always
    ports:
      - "6002:80"
    working_dir: /
    networks:
      net:
        ipv4_address: 172.18.0.2

networks:
  net:
    ipam:
      driver: default
      config:
        - subnet: "172.18.0.0/16"


  • compose1 디렉터리에서 다음 명령어를 실행한다.


sudo docker-compose -p compose1 up -d


2) Docker Compose compose2

  • 그 다음, compose2docker-compose.yml 파일이다.
  • ports는 다르게 지정한다.


./compose2/docker-compose.yml
version: "3.8"

services:
  compose2_proxy:
    container_name: "compose2_proxy"
    image: nginx:latest
    restart: always
    ports:
      - "6003:80"
    working_dir: /
    networks:
      net:
        ipv4_address: 172.19.0.2

networks:
  net:
    ipam:
      driver: default
      config:
        - subnet: "172.19.0.0/16"


  • compose2 디렉터리에서 다음 명령어를 실행한다.


sudo docker-compose -p compose2 up -d


3) Docker Network 확인

  • Docker Network가 어떻게 생성되었는지 확인하기 위해 다음 명령어를 실행한다.


sudo docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
a05b88e95a12        bridge              bridge              local
3f78084f2c32        compose1_net        bridge              local
4b8acd58469b        compose2_net        bridge              local
d664e9b8f859        host                host                local
10135e907436        none                null                local


  • 먼저, compose1_net의 상세 내용을 확인해 보자.


sudo docker network inspect compose1_net
[
    {
        "Name": "compose1_net",
        "Id": "3f78084f2c32ef8b558edfd885f444cba8917d4ad04e08fe42b86f633f7dbd84",
        "Created": "2022-03-23T15:06:52.911830139+09:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.18.0.0/16"
                }
            ]
        },
        "Internal": false,
        "Attachable": true,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "f5f0d094e73e13ac5515ce18085f8b016ebd9d662aa2b5b608d2930ca61163d2": {
                "Name": "compose1_proxy",
                "EndpointID": "0839c8b5e6ba86c731b3c049957b84aa51d6b79d8268f8bc26b11503684c469f",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {
            "com.docker.compose.network": "net",
            "com.docker.compose.project": "compose1",
            "com.docker.compose.version": "1.29.2"
        }
    }
]


  • 그 다음, compose2_net의 상세 내용을 확인해 보자.


sudo docker network inspect compose2_net
[
    {
        "Name": "compose2_net",
        "Id": "4b8acd58469b2e3a0e3cc68a30d8bdce660dd05f201a638164ad10d1613c53f7",
        "Created": "2022-03-23T15:07:03.135118195+09:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.19.0.0/16"
                }
            ]
        },
        "Internal": false,
        "Attachable": true,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "d584092202abdece1146ee04fe5b170f1ae2ea39eae325fc32e1b2734c9da60e": {
                "Name": "compose2_proxy",
                "EndpointID": "061bb7524558daea5028e88b6833e0d268042b653e27dd729723891abd63f5ad",
                "MacAddress": "02:42:ac:13:00:02",
                "IPv4Address": "172.19.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {
            "com.docker.compose.network": "net",
            "com.docker.compose.project": "compose2",
            "com.docker.compose.version": "1.29.2"
        }
    }
]


  • 위의 내용이 의미하는 바를 간단하게 표현하면 다음과 같다.


1] compose1_net

  • 네트워크 드라이버는 bridge이다.
  • IPAM(IP Address Management)의 드라이버 이름은 default인데 즉, bridge 네트워크 드라이버를 따라간다.
  • Subnet은 172.18.0.0/16이다.
  • Gateway는 확인되지 않는다.
  • 현재 네트워크에 존재하는 컨테이너의 이름은 compose1_proxy이다.
  • compose1_proxy의 IPv4는 172.18.0.2/16이다.

2] compose2_net

  • 네트워크 드라이버는 bridge이다.
  • IPAM(IP Address Management)의 드라이버 이름은 default인데 즉, bridge 네트워크 드라이버를 따라간다.
  • Subnet은 172.19.0.0/16이다.
  • Gateway는 확인되지 않는다.
  • 현재 네트워크에 존재하는 컨테이너의 이름은 compose2_proxy이다.
  • compose2_proxy의 IPv4는 172.19.0.2/16이다.


4) Docker 확인

  • 다음 명령어를 입력하면 각 컨테이너의 네트워크를 확인할 수 있다.
  • 먼저, compose1_netcompose1_proxy의 네트워크 상세 내용을 확인해 보자.


sudo docker inspect --format='{{json .NetworkSettings.Networks}}' compose1_proxy
{"compose1_net":
    {"IPAMConfig":
        {"IPv4Address":"172.18.0.2"},
        "Links":null,
        "Aliases":["compose1_proxy","f5f0d094e73e"],
        "NetworkID":"3f78084f2c32ef8b558edfd885f444cba8917d4ad04e08fe42b86f633f7dbd84",
        "EndpointID":"0839c8b5e6ba86c731b3c049957b84aa51d6b79d8268f8bc26b11503684c469f",
        "Gateway":"172.18.0.1",
        "IPAddress":"172.18.0.2",
        "IPPrefixLen":16,
        "IPv6Gateway":"",
        "GlobalIPv6Address":"",
        "GlobalIPv6PrefixLen":0,
        "MacAddress":"02:42:ac:12:00:02",
        "DriverOpts":null
    }
}


  • 그 다음, compose2_netcompose2_proxy의 결과이다.


sudo docker inspect --format='{{json .NetworkSettings.Networks}}' compose2_proxy
{"compose2_net":
    {"IPAMConfig":
        {"IPv4Address":"172.19.0.2"},
        "Links":null,
        "Aliases":["d584092202ab","compose2_proxy"],
        "NetworkID":"4b8acd58469b2e3a0e3cc68a30d8bdce660dd05f201a638164ad10d1613c53f7",
        "EndpointID":"061bb7524558daea5028e88b6833e0d268042b653e27dd729723891abd63f5ad",
        "Gateway":"172.19.0.1",
        "IPAddress":"172.19.0.2",
        "IPPrefixLen":16,
        "IPv6Gateway":"",
        "GlobalIPv6Address":"",
        "GlobalIPv6PrefixLen":0,
        "MacAddress":"02:42:ac:13:00:02",
        "DriverOpts":null
    }
}


  • 위의 결과를 통해 확인할 수 있듯이 자동으로 Gateway가 설정되었다.
  • 하지만, 가능하다면 docker-compose.ymlgateway 속성을 추가하는 것이 좋다.

References