Host Networking
host networking을 사용할 경우 컨테이너가 도커 호스트의 네트워크를 사용하게 됩니다. 격리되지 않은 네트워크(도커 호스트의 네트워킹 네임스페이스를 사용함)기 때문에 컨테이너에 따로 ip 주소가 붙지는 않습니다. 때문에 NAT(network address translation)을 거치지 않고 사용할 수 있으며, 포트마다 userland-proxy가 생성되지 않습니다.
$ docker run --network host --rm -d --name nginx -p 80:80 nginx tail -f /dev/null
WARNING: Published ports are discarded when using host network mode
d806a666142f93ede292b20b0e821f2ed312c998d90f2ff41e6eab04f99b6645
해서, network mode를 host로 사용할 때는 -p 옵션을 붙일 시 WARNING : Published ports are discarded when using host network mode와 같은 메시지와 함께 포트 맵핑이 적용되지 않는 모습을 볼 수 있습니다. network isolation이 안 되는 만큼 nginx 프로세스를 도커 호스트에서 돌리고 있는 것과 비슷합니다.
userland-proxy feat. iptables
userland-proxy는 -p 옵션으로 컨테이너를 생성할 때 동작하여 프로세스를 생성합니다. iptables가 해당 포트를 통해 들어오는 외부로부터의 패킷을 컨테이너로 보내준다면, userland-proxy는 내부의 트래픽을 해당 컨테이너로 라우팅해주는 역할을 맡습니다.
Host network 간단히 사용해보기
호스트 네트워크를 사용해보기 위해 아래와 같이 nginx 컨테이너를 생성해줍니다.
$ docker run --rm -d --network host --name nginx nginx
046c85c9d57a8cd55d8ef81494dcfcebec5f254c56d6a0c0e7b2a61d1b1e58f3
그렇게 생성된 컨테이너는 host network에 붙어 ip 주소가 할당되지 않는 모습을 볼 수 있습니다.
$ docker network inspect host
[
{
"Name": "host",
"Id": "51dd05e266e77e785eed5715f020de682d34fd3184fd8c552c39ae6b677875d0",
"Created": "2022-11-24T08:02:25.930289119Z",
"Scope": "local",
"Driver": "host",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": []
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"046c85c9d57a8cd55d8ef81494dcfcebec5f254c56d6a0c0e7b2a61d1b1e58f3": {
"Name": "nginx-test",
"EndpointID": "f231ae1c100696a35a700b062d305c3a5a4963b37cefbb1216fd8ee47d1675bd",
"MacAddress": "",
"IPv4Address": "",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
그리고 이는 호스트 네트워크의 특성상 바로 외부에서 액세스할 수 있습니다.
또한, 새 네트워크 인터페이스도 생성되지 않은 모습을 볼 수 있습니다
$ ifconfig
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:5ff:fee9:40ad prefixlen 64 scopeid 0x20<link>
ether 02:42:05:e9:40:ad txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 4 bytes 440 (440.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 9001
inet 10.0.44.65 netmask 255.255.240.0 broadcast 10.0.47.255
inet6 fe80::8a2:d4ff:fee2:f7a2 prefixlen 64 scopeid 0x20<link>
ether 0a:a2:d4:e2:f7:a2 txqueuelen 1000 (Ethernet)
RX packets 170000 bytes 225856709 (215.3 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 22750 bytes 2226054 (2.1 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 96 bytes 7670 (7.4 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 96 bytes 7670 (7.4 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
도커 호스트의 80번 포트에는 위에서 생성한 프로세스(nginx 컨테이너)가 바인딩돼있는 모습을 확인할 수 있습니다.
$ netstat -tulpn | grep :80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 2497/nginx: master
tcp6 0 0 :::80 :::* LISTEN 2497/nginx: master
해당 프로세스가 보이지 않는다면 권한 이슈일 확률이 높습니다. docker에 대한 권한이 사용자에 없으면 해당 프로세스를 볼 수 없기 때문입니다. sudo를 붙이거나 권한을 주어 해결하도록 합니다.