As posted earlier I have IPv6 Prefix Delegation working at our office to test with Docker.
One of the missing links was to automatically configure Docker to use the prefix obtained through DHCPv6+PD. I manually configured the prefix in Docker, but I also had to run dhclient manually.
I figured this could be automated so I gave it a try.
Ubuntu Networking
At first I tried to figure out if Ubuntu’s networking was somehow able to request a prefix through DHCPv6. Long story short: Neither Ubuntu nor CentOS are able to do so. You have to script this manually.
dhclient
To obtain a prefix I had to run dhclient manually. That wasn’t to hard. Simply run:
dhclient -6 -P -d -v eth0
This resulted in obtaining a prefix:
Bound to *:546 Listening on Socket/eth0 Sending on Socket/eth0 PRC: Confirming active lease (INIT-REBOOT). XMT: Forming Rebind, 0 ms elapsed. XMT: X-- IA_PD d5:68:28:08 XMT: | X-- Requested renew +3600 XMT: | X-- Requested rebind +5400 XMT: | | X-- IAPREFIX 2001:980:XXXX:140::/60 XMT: | | | X-- Preferred lifetime +7200 XMT: | | | X-- Max lifetime +7500 XMT: V IA_PD appended. XMT: Rebind on eth0, interval 940ms. RCV: Reply message on eth0 from fe80::da67:d9ff:fe81:bcec. RCV: X-- IA_PD d5:68:28:08 RCV: | X-- starts 1457617054 RCV: | X-- t1 - renew +604800 RCV: | X-- t2 - rebind +967680 RCV: | X-- [Options] RCV: | | X-- IAPREFIX 2001:980:XXXX:140::/60 RCV: | | | X-- Preferred lifetime 1209600. RCV: | | | X-- Max lifetime 2592000. RCV: X-- Server ID: 00:03:00:01:d8:67:d9:81:bc:f0 PRC: Bound to lease 00:03:00:01:d8:67:d9:81:bc:f0. PRC: Renewal event scheduled in 604800 seconds, to run for 362880 seconds. PRC: Depreference scheduled in 1209600 seconds. PRC: Expiration scheduled in 2592000 seconds.
As you can see, I got a /60 prefix. Now I had to somehow get this automated and configure Docker to use it.
Upstart
Since I was testing with Docker 1.10 under Ubuntu 14.04 I had to use Upstart to run dhclient.
The /etc/init/dhclient6-pd.conf Upstart script I created was rather simple:
description "DHCPv6 Prefix Delegation client" start on runlevel [2345] stop on runlevel [!2345] respawn respawn limit 30 3 umask 022 console log exec dhclient -6 -P -d eth0
DHCP hook
dhclient has hooks which it can execute when something happens. I wrote a hook which extracted the delegated IPv6 prefix and restarted Docker.
I placed the hook in the default location for DHCP hooks: /etc/dhcp/dhclient-enter-hooks.d/docker-ipv6:
#!/bin/bash SUBNET_SIZE=80 DOCKER_ETC_DIR="/etc/docker" DOCKER_PREFIX_FILE="${DOCKER_ETC_DIR}/ipv6.prefix" if [ ! -z "$new_ip6_prefix" ]; then SUBNET=$(sipcalc -S $SUBNET_SIZE $new_ip6_prefix|grep Network|head -n 1|awk '{print $3}') echo "${SUBNET}/${SUBNET_SIZE}" > $DOCKER_PREFIX_FILE if [ "$old_ip6_prefix" != "$new_ip6_prefix" ]; then service docker restart fi fi
For this to work you need to modify /etc/default/docker so that this line reads:
DOCKER_OPTS="--ipv6 --fixed-cidr-v6=`cat /etc/docker/ipv6.prefix`"
The result
Docker was now running properly with a IPv6 subnet configured and my containers have a IPv6 address as well.
wido@wido-desktop:~$ docker exec -ti 94c8f02 ip addr show dev eth0 13: eth0:mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 scope global eth0 valid_lft forever preferred_lft forever inet6 2001:980:XXXX:140:0:242:ac11:2/80 scope global valid_lft forever preferred_lft forever inet6 fe80::42:acff:fe11:2/64 scope link valid_lft forever preferred_lft forever wido@wido-desktop:~$
Native IPv6 in my Docker containers fully automated and dynamic!
All the scripts I used can be found on Github.