docker macvlan - no route to host (container)

14.9k views Asked by At

Im trying to understand the "macvlan" network from docker. I create a new network:

docker network create -d macvlan \
  --subnet=192.168.2.0/24 \
  --gateway=192.168.2.1 \
  -o parent=eno1 \
  pub_net

And start new container with the new network:

docker run --rm -d --net=pub_net --ip=192.168.2.74 --name=whoami -t jwilder/whoami

When i try to access the service from the container or ping it i get:

curl: (7) Failed to connect to 192.168.2.74 port 8000: no route to host

Tested with Ubuntu 16.04, Ubuntu 18.04 & CentOS 7. Neither from the docker host itself or other clients on the network can reach the container.

I followed the example fromt he docker site: https://docs.docker.com/network/network-tutorial-macvlan/#bridge-example

What im missing ?

I read here Bind address in Docker macvlan to execute these commands (no clue what they do):

sudo ip link add pub_net link eno1 type macvlan mode bridge
sudo ip addr add 192.168.2.22/24 dev pub_net

But this does nothing on my machine(s)

2

There are 2 answers

3
Christoph On BEST ANSWER

I believe it is by design that host cannot reach its own containers through a macvlan network. I leave it to others to explain why exactly this is so, but to verify that this is where your problem lies, you can try to ping your container at 192.168.2.74 from another host on the network or even from another container or vm on the same host. If you can reach the container from other machines but not from the host, everything is working as it should.

According to this blog post, you can nevertheless allow for host-container communication by creating a macvlan interface on the host sub-interface and then create a macvlan interface in host in order to let it access the macvlan that the container is in.

I have not tried this myself yet and I'm not sure about the exact consequences, so I quote the instructions from the blog post here so that others can add to it where necessary:

Create a macvlan interface on host sub-interface:

docker network create -d macvlan \
–subnet=192.168.0.0/16 \
–ip-range=192.168.2.0/24 \
-o macvlan_mode=bridge \
-o parent=eth2.70 macvlan70

Create container on that macvlan interface:

docker run -d –net=macvlan70 –name nginx nginx

Find ip address of Container:

docker inspect nginx | grep IPAddress
“SecondaryIPAddresses”: null,
“IPAddress”: “”,
“IPAddress”: “192.168.2.1”,

At this point, we cannot ping container IP “192.168.2.1” from host machine.

Now, let’s create macvlan interface in host with address “192.168.2.10” in same network.

sudo ip link add mymacvlan70 link eth2.70 type macvlan mode bridge
sudo ip addr add 192.168.2.10/24 dev mymacvlan70
sudo ifconfig mymacvlan70 up

Now, we should be able to ping the Container IP as well as access “nginx” container from host machine.

$ ping -c1 192.168.2.1
PING 192.168.2.1 (192.168.2.1): 56 data bytes
64 bytes from 192.168.2.1: seq=0 ttl=64 time=0.112 ms

— 192.168.2.1 ping statistics —
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.112/0.112/0.112 ms
2
Panagiotis Drakatos On

In case someone wants to run docker-compose to bring the macvlan network alive this simple thing worked for me.

Assuming you have Docker Compose version v2.18.1 or latest here is my docker-compose.yamlfile

services:
  web:
    build: .
    image: java_app2
    command:
       - "arg1"
       - "arg2"
    networks:
      network:
        ipv4_address: 192.168.1.119

networks:
  network:
    driver: macvlan
    driver_opts:
      macvlan_mode: bridge
      parent: enp3s0
    ipam:
      config:
        - subnet: "192.168.1.0/24"
          ip_range: "192.168.1.71/32"
          gateway: "192.168.1.1"

Make sure the parent: enp3s0 is replaced with your interface:

panos@panos-H610M-H-DDR4:~$ 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:c2ff:fe26:24fd  prefixlen 64  scopeid 0x20<link>
        ether 02:42:c2:26:24:fd  txqueuelen 0  (Ethernet)
        RX packets 1579810  bytes 114639135 (114.6 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3040511  bytes 4334700689 (4.3 GB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

enp3s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.114  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 fe80::8255:fbf1:86f6:dc04  prefixlen 64  scopeid 0x20<link>
        ether 74:56:3c:25:5a:d6  txqueuelen 1000  (Ethernet)
        RX packets 3610477  bytes 4436452141 (4.4 GB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2088246  bytes 420196401 (420.1 MB)
        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 14948617  bytes 967576446 (967.5 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 14948617  bytes 967576446 (967.5 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0