Docker network create macvlan with DHCP possible?

Hello.

I am running 3 dockers using a macvlan network but the way I am doing it is:

# Get IPv4 for Gateway, Subnet Mask and IP Addresses
while [ -z “$ip4” ]

do
ip4=“$(ip -o -4 addr list eth0 | awk ‘{print $4}’ | cut -d. -f1,2,3)”
done

# Create docker network
docker network create -d macvlan --subnet=“$ip4.0/24” --gateway=“$ip4.1” -o parent=eth0 \
-o macvlan_mode=bridge eth0

# Start dockers
docker run -d --name=‘alpine1’ --net=‘eth0’ --ip=“$ip4.101” ‘alpine’ tail -f /dev/null
docker run -d --name=‘alpine2’ --net=‘eth0’ --ip=“$ip4.102” ‘alpine’ tail -f /dev/null
docker run -d --name=‘alpine3’ --net=‘eth0’ --ip=“$ip4.103” ‘alpine’ tail -f /dev/null

And everything is fine… BUT if I want to run this on a network that uses a different subnet mask and/or gateway and/or IP addresses 101 thru 103 being used, it will not work. Is there a way for me to create the macvlan network using DHCP and avoid having to get the IP and assume gateway is .1 and subnet mask is 0/24?

Thanks! :+1:

1 Like

I have the same question.
Cheers

The --ip option is not mandatory so your container can get its IP address dynamically, but it will not be from DHCP. I don’t think you could do that. As far as I know, Docker just assigns a new IP address from the configured subnet. If you have existing IP addresses in the subnet, Docker can assign those existing IPs to containers. If you want to avoid that, you can use the --aux-address option or --ip-range to use a subset of the available IP addresses in the configured subnet or as the documentation mentions, use a dedicated subnet just for containers on macvlan. The gateway is optional too, but you need to define at least the subnet.

If you have a server, that is not likely to move frequently to different subnets. If you have a laptop, that is not for long-running containers and you can always use a script to regenerate your Docker networks and and recreate your containers without manually modifying anything except the subnet.

If you setup the macvlan network without subnet, docker will automatically assign one to it. As we are going to obtain an ip from DHCP, we actually don’t care what subnet it is.

docker network create -d macvlan -o parent=eth0 macvlan0

Since docker assigns the container a non exisiting subnet, the container will have no internet access initially. You will need to make sure that your container has the dhcp client.

For debian, a image with dhcp could be created by

docker run -itd --name debian debian
docker exec debian bash -c 'apt-get update && apt-get install -y isc-dhcp-client'
docker commit debian debian_with_dhcp
docker rm -f debian

Then we want to flush the current assigned ip and obtain one from DHCP server via eth0
It could be done by ip addr flush dev eth0 && dhclient eth0 before running the entrypoint of your image.

docker run -it \
    --network macvlan0 \
    --cap-add=NET_ADMIN \
    --mac-address=00:11:22:33:44:55 \
    --entrypoint /bin/bash \
    debian_with_dhcp \
    -c "ip addr flush dev eth0 && dhclient eth0 && /bin/bash"

That doesn’t look right. Surely it should be dhclient macvlan0. There isn’t going to be an eth0 in the container.

Seems like its neither one of both:

$ docker run -ti --rm --network macvlan0 alpine ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN qlen 1
    link/sit 0.0.0.0 brd 0.0.0.0
14: eth0@sit0: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UNKNOWN
    link/ether 02:42:c0:a8:c8:60 brd ff:ff:ff:ff:ff:ff
    inet 192.168.200.96/24 brd 192.168.200.255 scope global eth0
       valid_lft forever preferred_lft forever

Update
it indeed looks eth0 is also correct:

$ docker run -ti --rm --network macvlan0 --cap-add NET_ADMIN alpine ip address show eth0
22: eth0@sit0: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UNKNOWN
    link/ether 02:42:c0:a8:c8:60 brd ff:ff:ff:ff:ff:ff
    inet 192.168.200.96/24 brd 192.168.200.255 scope global eth0
       valid_lft forever preferred_lft forever
1 Like