This post details how I enabled IPv6 addresses in docker containers on DigitalOcean.
DigitalOcean supports IPv6 in its London 1 and Singapore 1 data centers as of July 2014. Create a droplet using the Ubuntu 14.04 image and DO’s docker installation under Applications in the “Create VM” screen. Make sure to check “IPv6″.
DO provides a VM with 20 addresses within a /64. docker0 gets assigned 0x1 as the last hex character. I give the docker0 interface 0x4. This leaves 0x5 to 0xf for my containers.
Let’s take an example. DO gives me 2a03:b0c0:1:d0::18:d000 to 2a03:b0c0:1:d0::18:d00f. docker0 gets 2a03:b0c0:1:d0::18:d004. The last double octet for containers ranges from 0xd005 to 0xd00f.
To break up the 20 addresses provided by DO, we need a way for containers to respond to IPv6 neighbor discovery on the host’s eth0 interface. This could be performed using a ND proxy daemon (see here for one implementation). For most docker use cases, a static ND proxy entry should do.
docker does not natively support IPv6. LXC, the foundation of docker, can handle IPv6 in containers. As of docker 1, the software uses libcontainer by default instead of LXC. We’ll have to configure /etc/default/docker to use the LXC driver.
See below for example for one time set-up of the droplet.
#!/bin/bash # enable IPv6 forwarding and ND proxying echo net.ipv6.conf.all.proxy_ndp=1 >> /etc/sysctl.conf echo net.ipv6.conf.all.forwarding=1 >> /etc/sysctl.conf sudo sysctl -p /etc/sysctl.conf # install LXC sudo apt-get install -y lxc # use the LXC driver echo DOCKER_OPTS=\"--exec-driver=lxc\" >> /etc/default/docker service docker restart
The script below demonstrates how to set-up the static ND proxy entries. Make sure to change the V6_START variable.
#!/bin/bash # This script provides an example of setting up IPv6 static # ND proxy entries. Edit the V6_START to match # what you see in the DO control panel V6_START=2a03:b0c0:1:d0::18:d000 # strip the last hex character V6_MINUS_LAST_HEX_CHAR=`echo $V6_START|sed s/.$//` ip addr add ${V6_MINUS_LAST_HEX_CHAR}4/124 dev docker0 echo "adding ND proxy entries..." for character in 4 5 6 7 8 9 a b c d e f; do echo "ip -6 neigh add proxy ${V6_MINUS_LAST_HEX_CHAR}${character} dev eth0" ip -6 neigh add proxy ${V6_MINUS_LAST_HEX_CHAR}${character} dev eth0 done
Now we’re ready to bring up the container. The first argument must be an IPv6 address in your assigned
range with the last double octet between 0xXXX5 and 0xXXXF. For me, this is 0xd005 to 0xd00f.
#!/bin/bash # first argument to script must be IPv6 address from DO-allocated # space that is not part of the first /126 (e.g. 0x4 to 0xF as last # hex character IPV6_ADDRESS=$1 if [ -z "$IPV6_ADDRESS" ]; then echo "please specify IPv6 address for container's eth0" exit 1 fi echo "container eth0: $IPV6_ADDRESS" # run container so that docker0 gets a link local address docker run busybox:ubuntu-14.04 /bin/true docker rm $(docker ps -lq) # get docker0's link local address LINK_LOCAL=$( \ ip addr show docker0 | \ grep "inet6 fe80" | \ awk '{print $2}' | \ sed 's/\/.*//' \ ) if [ -z "$LINK_LOCAL" ]; then echo "unable to find link local address on docker0. something is wrong." exit 1 fi echo "docker0 link local: $LINK_LOCAL" docker run -i -t \ --lxc-conf="lxc.network.flags = up" \ --lxc-conf="lxc.network.ipv6 = $IPV6_ADDRESS/124" \ --lxc-conf="lxc.network.ipv6.gateway = $LINK_LOCAL" busybox:ubuntu-14.04 /bin/sh
Executing the script will put you in interactive mode in a shell in the container. Try ‘ping6 2600::’ to to test connectivity. If you are having trouble, let me know in the comments.
I want to thank Andreas Neuhaus for his IPv6 in Docker Containers post and his suggestion to use static ND proxy when the provider does not route a /64 to your docker host.
Image may be NSFW.
Clik here to view.
Clik here to view.
