docker macvlan 네트워크를 호스트에서 접근하기
안녕하세요? 도정진입니다.
이전에 아래의 글을 올려드린적이 있습니다.
macvlan 으로 컨테이너에 IP가 할당되어서 단독 머신처럼 구성하여 PLEX 서버를 여러개 구동하는 방법입니다.
https://blog.djjproject.com/785
그러나 이 방법으로는 호스트에서 PLEX 서버로 통신을 할 수가 없습니다.
이 드라이버 자체가 바로 phy로 바로 패킷이 떨어져 나가기 때문에 호스트에서는 확인할 수 없습니다.
따라서 호스트 머신에서 컨테이너로 접근하기 위해서 접근용 macvlan 컨테이너를 만들거나 해야하는 불편함이 생기는데요. 아래의 방법으로 간단하게 해결이 가능합니다.
1. 상황
vmbr0 네트워크를 기준으로 macvlan docker 네트워크 생성하였습니다.
그리고 vmbr0 네트워크는 192.168.0.0/24 대역을 가지고 있으며, 게이트웨이는 192.168.0.1 이고 IP할당은 192.168.0.17 입니다.
root@debian:/opt/hass/config# docker network ls NETWORK ID NAME DRIVER SCOPE 575297fda5c5 bridge bridge local 22b04175052d host host local c9bfc45128f1 macvlan macvlan local 0b2d5ee07744 none null local root@debian:/opt/hass/config# docker network inspect macvlan [ { "Name": "macvlan", "Id": "c9bfc45128f1331268a2727c3cc20e319596cb3fed59493f43f3a969996c1faf", "Created": "2022-05-19T14:45:31.437506629+09:00", "Scope": "local", "Driver": "macvlan", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "192.168.0.0/24", "Gateway": "192.168.0.1" } ] }, |
다음으로 nginx docker 를 하나 생성해봅니다. 아이피를 192.168.1.1 로 주어 생성합니다.
root@debian:/opt/hass/config# docker run -dit --network macvlan --ip=192.168.0.101 --name nginx nginx:latest |
이 상황에서 호스트 ip 192.168.0.17 에서 192.168.0.101 로의 접근이 되지 않습니다.
root@debian:/opt/hass/config# ping 192.168.0.101 PING 192.168.0.101 (192.168.0.101) 56(84) bytes of data. From 192.168.0.17 icmp_seq=1 Destination Host Unreachable From 192.168.0.17 icmp_seq=2 Destination Host Unreachable From 192.168.0.17 icmp_seq=3 Destination Host Unreachable From 192.168.0.17 icmp_seq=4 Destination Host Unreachable |
root@debian:~# curl http://192.168.0.101/ curl: (7) Failed to connect to 192.168.0.101 port 80: No route to host |
그러나 동일 대역의 다른 PC (윈도우) 에서는 아래와 같이 접근에 문제가 없습니다.
2. 해결 방안
따로 vmbr0 네트워크와 브릿지하는 가상 어댑터를 하나 생성하고,
컨테이너 아이피에 대해 라우팅을 추가하면 해결이 됩니다.
이떄, DHCP 환경이면 서브넷을 잘 분리하여 사용할 수 있겠지만, 가정용 홈서버 레벨에서는 그 정도까지는 신경 쓸 필요가 없어서 서브넷에 대해서는 설정하지 않을 예정입니다.
3. 가상 어댑터 생성 및 route 추가
일단 아래와 같이 vmbr0 네트워크와 브릿지 하는 어댑터를 하나 생성합니다.
root@debian:~# ip link add macvlan-shim link vmbr0 type macvlan mode bridge root@debian:~# ip addr | grep macvlan 51: macvlan-shim@vmbr0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 |
그리고 주소를 할당하고 네트워크를 up 합니다.
이때 192.168.0.200 에 대해서는 DHCP 서버가 IP를 다른 기기에 할당하지 않아야 합니다.
root@debian:~# ip addr add 192.168.0.200/24 dev macvlan-shim root@debian:~# ip addr show macvlan-shim 51: macvlan-shim@vmbr0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether a2:0f:33:d8:1c:ed brd ff:ff:ff:ff:ff:ff inet 192.168.0.200/24 scope global macvlan-shim valid_lft forever preferred_lft forever root@debian:~# ip link set macvlan-shim up |
그리고 macvlan-shim 가상 어댑터에 route 를 추가합니다.
root@debian:~# ip route add 192.168.0.101 dev macvlan-shim |
4. 결과
결과적으로 아래와 같이 잘 작동합니다.
root@debian:~# curl http://192.168.0.101/ <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> html { color-scheme: light dark; } body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html> root@debian:~# ping 192.168.0.100 PING 192.168.0.100 (192.168.0.100) 56(84) bytes of data. 64 bytes from 192.168.0.100: icmp_seq=1 ttl=64 time=0.127 ms 64 bytes from 192.168.0.100: icmp_seq=2 ttl=64 time=0.100 ms 64 bytes from 192.168.0.100: icmp_seq=3 ttl=64 time=0.192 ms 64 bytes from 192.168.0.100: icmp_seq=4 ttl=64 time=0.072 ms |
그럼 컨테이너에서 호스트로의 통신은 어떨까요?
문제 없습니다.
root@5eabcd0dfa93:/# ping 192.168.0.17 PING 192.168.0.17 (192.168.0.17) 56(84) bytes of data. 64 bytes from 192.168.0.17: icmp_seq=1 ttl=64 time=0.140 ms 64 bytes from 192.168.0.17: icmp_seq=2 ttl=64 time=0.120 ms 64 bytes from 192.168.0.17: icmp_seq=3 ttl=64 time=0.118 ms |
이 부분을 영구적용하려면 rc.local 이나 /etc/network/interfaces 에 post-up을 적용하여 사용하시면 됩니다.
감사합니다.