5. Docker Compose 네트워크
1. Docker Network
1) Docker 네트워크 인터페이스 - docker0
- Docker 네트워크 인터페이스의 정보는 다음과 같다.
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
- 위의 내용을 확인하기 위해 컨테이너
test1
과test2
를 생성해 보자.
sudo docker run -d -p 1234:80 --name test1 nginx:latest
sudo docker run -d -p 1235:80 --name test2 nginx:latest
- 먼저, 컨테이너
test1
의ifconfig
과route
명령어를 실행한 결과이다.
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
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
- 그 다음, 컨테이너
test2
의ifconfig
과route
의 결과이다.
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
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 네트워크 인터페이스 결과 정리
- 컨테이너
test1
과test2
의 네트워크를 확인한 결과 모두 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를 이용하여 네트워크를 구성하는 경우를 보자.
- 먼저,
compose1
과compose2
라는 디렉터리를 생성한다.
- 각 디렉터리에 Docker Compose를 위한
docker-compose.yml
파일을 동일하게 생성한다. - 이때
docker-compose.yml
의version
은3.8
이다.
1) Docker Compose compose1
- 먼저
compose1
의docker-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
디렉터리에서 다음 명령어를 실행한다.
2) Docker Compose compose2
- 그 다음,
compose2
의docker-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
디렉터리에서 다음 명령어를 실행한다.
3) Docker Network 확인
- Docker Network가 어떻게 생성되었는지 확인하기 위해 다음 명령어를 실행한다.
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
의 상세 내용을 확인해 보자.
[
{
"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
의 상세 내용을 확인해 보자.
[
{
"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 확인
- 이런 상황에서 각 컨테이너의 정보는 다음과 같이 확인된다.
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
- 먼저
compose1
의docker-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
디렉터리에서 다음 명령어를 실행한다.
2) Docker Compose compose2
- 그 다음,
compose2
의docker-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
디렉터리에서 다음 명령어를 실행한다.
3) Docker Network 확인
- Docker Network가 어떻게 생성되었는지 확인하기 위해 다음 명령어를 실행한다.
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
의 상세 내용을 확인해 보자.
[
{
"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
의 상세 내용을 확인해 보자.
[
{
"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_net
의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_net
의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.yml
의gateway
속성을 추가하는 것이 좋다.