Default Bridge Network
Network bridge는 link layer로 대표적인 link layer로는 NIC(Network Interface Card)가 있습니다. 실제로 전 글에서 ifconfig로 Docker default network를 조회하였을 때 NIC와 같이 조회되는 모습을 확인할 수 있습니다.
먼저 아래와 같이 alpine 컨테이너 두 개를 만들어줍니다.
$ docker run -d --name alpine1 alpine:latest tail -f /dev/null
3d8cd78a27f8aa1703ed78e8592bd074e2aea487141c8b1eec878d92c3217a3a
$ docker run -d --name alpine2 alpine:latest tail -f /dev/null
31e4fe14de0560744d73a76751cf1f566ad9f73a5e69cb13ff185ae6361f2e8b
위 컨테이너들은 따로 네트워크 설정을 해주지 않았기 때문에 아래와 같이 기본 브리지 네트워크에 붙게 됩니다.
$ docker network inspect bridge
[
{
"Name": "bridge",
"Id": "ee5030326ef98cbdbe866144b45b25d291e36ef279e6b338afaabffabf68d51f",
"Created": "2022-11-10T09:30:58.516776372Z",
"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": {
"31e4fe14de0560744d73a76751cf1f566ad9f73a5e69cb13ff185ae6361f2e8b": {
"Name": "alpine2",
"EndpointID": "7cdb19f78a19a3bf986994170f8f377d15077e3d9d57a1423e0bb50e20156204",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
},
"3d8cd78a27f8aa1703ed78e8592bd074e2aea487141c8b1eec878d92c3217a3a": {
"Name": "alpine1",
"EndpointID": "14b09e08276f08b579a106058fbcbac996a8b209ba166c2bdecd4fa3e888ed62",
"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": {}
}
]
alpine1 컨테이너에 접근해 핑을 찍어보면 alpine2 컨테이너나 외부와 원활하게 통신할 수 있는 걸 알 수 있습니다.
$ ping -c 5 google.com
PING google.com (142.251.42.174): 56 data bytes
64 bytes from 142.251.42.174: seq=0 ttl=103 time=33.715 ms
64 bytes from 142.251.42.174: seq=1 ttl=103 time=33.773 ms
64 bytes from 142.251.42.174: seq=2 ttl=103 time=33.778 ms
64 bytes from 142.251.42.174: seq=3 ttl=103 time=33.806 ms
64 bytes from 142.251.42.174: seq=4 ttl=103 time=33.776 ms
--- google.com ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max = 33.715/33.769/33.806 ms
$ ping -c 3 172.17.0.3
PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.093 ms
64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.086 ms
64 bytes from 172.17.0.3: seq=2 ttl=64 time=0.078 ms
--- 172.17.0.3 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.078/0.085/0.093 ms
마지막으로 만든 컨테이너들을 삭제해줍니다.
$ docker rm -f alpine1
alpine1
$ docker rm -f alpine2
alpine2
User-defined network
그런데 User-defined bridge network가 많은 면에서 Default bridge network보다 낫다고 말합니다. isolation이 더 간편하거나, 자동으로 --link 옵션을 쓴 것과 같이 alias로 연결되기도 합니다.
먼저 다음과 같이 브리지 네트워크를 만들어줍니다.
$ docker network create test-bridge # --driver [network] 옵션으로 네트워크 타입 지정
ea170a22306277a1172f17640d9ff3d7ccaf022321c4b81fdbbbeaafc49c6c5e
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
ee5030326ef9 bridge bridge local
d08d819aeb7f host host local
e1cf6408e31b none null local
ea170a223062 test-bridge bridge local
그리고 --network 옵션을 통해 test-bridge에 연결된 두 개의 컨테이너를 만들어줍니다
$ docker run -d --name alpine1 --network test-bridge alpine:latest tail -f /dev/null
dd4fee7b3abc99752299f6d40accc9315b8f368054b4e8be4d5474b9194c8d16
$ docker run -d --name alpine2 --network test-bridge alpine:latest tail -f /dev/null
e12731a1332b2155e869300a3426cebbf49cb8ed24b8a525fd7c90ac3a7a4be1
$ docker network inspect test-bridge
[
{
"Name": "test-bridge",
"Id": "ea170a22306277a1172f17640d9ff3d7ccaf022321c4b81fdbbbeaafc49c6c5e",
"Created": "2022-11-22T09:00:00.522574101Z",
"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": {
"dd4fee7b3abc99752299f6d40accc9315b8f368054b4e8be4d5474b9194c8d16": {
"Name": "alpine1",
"EndpointID": "1d7a4deeb11a30547f5bd080a9e767a7399cd6f28d49fce7991505ad3799bdaf",
"MacAddress": "02:42:ac:15:00:02",
"IPv4Address": "172.21.0.2/16",
"IPv6Address": ""
},
"e12731a1332b2155e869300a3426cebbf49cb8ed24b8a525fd7c90ac3a7a4be1": {
"Name": "alpine2",
"EndpointID": "625192f35c18933233f2e5ac8c1d0f70c3c892c3dee81fa0ee3e7188115532f3",
"MacAddress": "02:42:ac:15:00:03",
"IPv4Address": "172.21.0.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
컨테이너들이 test-bridge 네트워크에 연결된 걸 확인했다면, alpine1 컨테이너에 접속해 alpine2 컨테이너로 핑을 보내봅니다.
# ping -c 2 alpine2
PING alpine2 (172.21.0.3): 56 data bytes
64 bytes from 172.21.0.3: seq=0 ttl=64 time=0.089 ms
64 bytes from 172.21.0.3: seq=1 ttl=64 time=0.077 ms
--- alpine2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.077/0.083/0.089 ms
alias로도 제대로 dns resolution이 이루어진 모습을 볼 수 있습니다.
이렇듯 도커에서는 default network보다 User-defined bridge network의 사용을 권장하고 있습니다.
Default Bridge Network
Network bridge는 link layer로 대표적인 link layer로는 NIC(Network Interface Card)가 있습니다. 실제로 전 글에서 ifconfig로 Docker default network를 조회하였을 때 NIC와 같이 조회되는 모습을 확인할 수 있습니다.
먼저 아래와 같이 alpine 컨테이너 두 개를 만들어줍니다.
$ docker run -d --name alpine1 alpine:latest tail -f /dev/null
3d8cd78a27f8aa1703ed78e8592bd074e2aea487141c8b1eec878d92c3217a3a
$ docker run -d --name alpine2 alpine:latest tail -f /dev/null
31e4fe14de0560744d73a76751cf1f566ad9f73a5e69cb13ff185ae6361f2e8b
위 컨테이너들은 따로 네트워크 설정을 해주지 않았기 때문에 아래와 같이 기본 브리지 네트워크에 붙게 됩니다.
$ docker network inspect bridge
[
{
"Name": "bridge",
"Id": "ee5030326ef98cbdbe866144b45b25d291e36ef279e6b338afaabffabf68d51f",
"Created": "2022-11-10T09:30:58.516776372Z",
"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": {
"31e4fe14de0560744d73a76751cf1f566ad9f73a5e69cb13ff185ae6361f2e8b": {
"Name": "alpine2",
"EndpointID": "7cdb19f78a19a3bf986994170f8f377d15077e3d9d57a1423e0bb50e20156204",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
},
"3d8cd78a27f8aa1703ed78e8592bd074e2aea487141c8b1eec878d92c3217a3a": {
"Name": "alpine1",
"EndpointID": "14b09e08276f08b579a106058fbcbac996a8b209ba166c2bdecd4fa3e888ed62",
"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": {}
}
]
alpine1 컨테이너에 접근해 핑을 찍어보면 alpine2 컨테이너나 외부와 원활하게 통신할 수 있는 걸 알 수 있습니다.
$ ping -c 5 google.com
PING google.com (142.251.42.174): 56 data bytes
64 bytes from 142.251.42.174: seq=0 ttl=103 time=33.715 ms
64 bytes from 142.251.42.174: seq=1 ttl=103 time=33.773 ms
64 bytes from 142.251.42.174: seq=2 ttl=103 time=33.778 ms
64 bytes from 142.251.42.174: seq=3 ttl=103 time=33.806 ms
64 bytes from 142.251.42.174: seq=4 ttl=103 time=33.776 ms
--- google.com ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max = 33.715/33.769/33.806 ms
$ ping -c 3 172.17.0.3
PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.093 ms
64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.086 ms
64 bytes from 172.17.0.3: seq=2 ttl=64 time=0.078 ms
--- 172.17.0.3 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.078/0.085/0.093 ms
마지막으로 만든 컨테이너들을 삭제해줍니다.
$ docker rm -f alpine1
alpine1
$ docker rm -f alpine2
alpine2
User-defined network
그런데 User-defined bridge network가 많은 면에서 Default bridge network보다 낫다고 말합니다. isolation이 더 간편하거나, 자동으로 --link 옵션을 쓴 것과 같이 alias로 연결되기도 합니다.
먼저 다음과 같이 브리지 네트워크를 만들어줍니다.
$ docker network create test-bridge # --driver [network] 옵션으로 네트워크 타입 지정
ea170a22306277a1172f17640d9ff3d7ccaf022321c4b81fdbbbeaafc49c6c5e
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
ee5030326ef9 bridge bridge local
d08d819aeb7f host host local
e1cf6408e31b none null local
ea170a223062 test-bridge bridge local
그리고 --network 옵션을 통해 test-bridge에 연결된 두 개의 컨테이너를 만들어줍니다
$ docker run -d --name alpine1 --network test-bridge alpine:latest tail -f /dev/null
dd4fee7b3abc99752299f6d40accc9315b8f368054b4e8be4d5474b9194c8d16
$ docker run -d --name alpine2 --network test-bridge alpine:latest tail -f /dev/null
e12731a1332b2155e869300a3426cebbf49cb8ed24b8a525fd7c90ac3a7a4be1
$ docker network inspect test-bridge
[
{
"Name": "test-bridge",
"Id": "ea170a22306277a1172f17640d9ff3d7ccaf022321c4b81fdbbbeaafc49c6c5e",
"Created": "2022-11-22T09:00:00.522574101Z",
"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": {
"dd4fee7b3abc99752299f6d40accc9315b8f368054b4e8be4d5474b9194c8d16": {
"Name": "alpine1",
"EndpointID": "1d7a4deeb11a30547f5bd080a9e767a7399cd6f28d49fce7991505ad3799bdaf",
"MacAddress": "02:42:ac:15:00:02",
"IPv4Address": "172.21.0.2/16",
"IPv6Address": ""
},
"e12731a1332b2155e869300a3426cebbf49cb8ed24b8a525fd7c90ac3a7a4be1": {
"Name": "alpine2",
"EndpointID": "625192f35c18933233f2e5ac8c1d0f70c3c892c3dee81fa0ee3e7188115532f3",
"MacAddress": "02:42:ac:15:00:03",
"IPv4Address": "172.21.0.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
컨테이너들이 test-bridge 네트워크에 연결된 걸 확인했다면, alpine1 컨테이너에 접속해 alpine2 컨테이너로 핑을 보내봅니다.
# ping -c 2 alpine2
PING alpine2 (172.21.0.3): 56 data bytes
64 bytes from 172.21.0.3: seq=0 ttl=64 time=0.089 ms
64 bytes from 172.21.0.3: seq=1 ttl=64 time=0.077 ms
--- alpine2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.077/0.083/0.089 ms
alias로도 제대로 dns resolution이 이루어진 모습을 볼 수 있습니다.
이렇듯 도커에서는 default network보다 User-defined bridge network의 사용을 권장하고 있습니다.