서버/리눅스 서버

docker macvlan 네트워크를 호스트에서 접근하기

ㅋㅋ잠자 2022. 5. 20. 16:05
반응형

안녕하세요? 도정진입니다.

 

이전에 아래의 글을 올려드린적이 있습니다.

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을 적용하여 사용하시면 됩니다.

 

감사합니다.

 

반응형