dockernetwork-programmingroutescontainersmacvlan

docker macvlan - no route to host (container)


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)


Solution

  • 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