Skip to content

Instantly share code, notes, and snippets.

@troykelly
Last active May 13, 2023 05:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save troykelly/749b48712d0d777030e7dd5d64916744 to your computer and use it in GitHub Desktop.
Save troykelly/749b48712d0d777030e7dd5d64916744 to your computer and use it in GitHub Desktop.
Docker IPv6 Support with DHCP-PD
net.ipv6.conf.all.forwarding=1
net.ipv6.conf.default.forwarding=1
net.ipv6.route.max_size=16384
net.ipv6.conf.eth0.accept_ra=2

Guide to Docker IPv6 Support

Note

Docker doesn't really support IPv6. You can sort of get it to work in very specific circumstances, but on the whole, the support for IPv6 is non-existent or in it's infancy.

Docker Swarm

Docker swarm does not support IPv6.

Docker overlay networks do not support IPv6.

Save yourself some time. It's not going to happen.

Caveat Following these instructions will end up with a jerry rigged swarm with some support for IPv6.

Docker IPv6 Reference Issues / Further Reading

Requirements

Docker to be installed.

No Swarm (yet)

If you have created your swarm, uncreate it. Your servers should have docker installed and running - but no containers or networks defined. Seriously.

Steps

sudo DEBIAN_FRONTEND=noninteractive apt-get -y install sipcalc && \
sudo curl -L "https://gist.githubusercontent.com/troykelly/749b48712d0d777030e7dd5d64916744/raw/docker-ipv6" -o /etc/dhcp/dhclient-enter-hooks.d/docker-ipv6 && \
sudo chmod +x /etc/dhcp/dhclient-enter-hooks.d/docker-ipv6 && \
sudo curl -L "https://gist.githubusercontent.com/troykelly/749b48712d0d777030e7dd5d64916744/raw/99-ipv6.conf" -o /etc/sysctl.d/99-ipv6.conf && \
sudo curl -L "https://gist.githubusercontent.com/troykelly/749b48712d0d777030e7dd5d64916744/raw/dhclient6-pd.service" -o "/etc/systemd/system/dhclient6-pd.service" && \
sudo mkdir -p /etc/systemd/system/docker.service.d && \
sudo curl -L "https://gist.githubusercontent.com/troykelly/749b48712d0d777030e7dd5d64916744/raw/ipv6.conf" -o /etc/systemd/system/docker.service.d/ipv6.conf && \
iface=$(ip -o -4 route show to default | awk '{print $5}' | head -n1) && sudo sed -i "s/\(Environment=NETWORK_INTERFACE=\).*/\1${iface}/" /etc/systemd/system/dhclient6-pd.service && sudo sed -i "s/\.eth0\./.${iface}./g" /etc/sysctl.d/99-ipv6.conf && \
sudo sysctl -p /etc/sysctl.d/99-ipv6.conf && \
sudo systemctl daemon-reload && \
sudo systemctl enable dhclient6-pd && \
sudo systemctl start dhclient6-pd && \
sleep 10 && \
cat /etc/docker/ipv6.prefix && \
docker network create \
 --ipv6 \
 --subnet 172.20.0.0/20 \
 --gateway 172.20.0.1 \
 --gateway fd00:3984:3989::1 \
 --subnet fd00:3984:3989::/64 \
 --opt com.docker.network.bridge.name=docker_gwbridge \
 --opt com.docker.network.bridge.enable_icc=true \
 --opt com.docker.network.bridge.enable_ip_forwarding=true \
 --opt com.docker.network.bridge.enable_ip_masquerade=true \
 docker_gwbridge

Now create your swarm

...if you need

Testing

Check containters have IPv6

docker run --rm -it alpine ash -c "ip -6 addr show dev eth0; ip -6 route show"
[Unit]
Description=DHCPv6 Prefix Delegation client
Wants=network.target network-online.target
After=network.target network-online.target
[Service]
Type=simple
Environment=NETWORK_INTERFACE=ens161
ExecStart=/sbin/dhclient -6 -P -d ${NETWORK_INTERFACE}
Restart=always
RestartSec=10s
[Install]
WantedBy=multi-user.target
#!/usr/bin/env bash
#
# DHCPv6 hook for Docker
#
# This hook will configure Docker to use the first /80 IPv6 subnet
# from the Prefix we got through DHCPv6 Prefix Delegation
#
# A /80 subnet is large enough for Docker. 80 + 48 bits (MAC) equals 128-bits.
#
# dhclient will run this hook after it obtains the lease
#
# Make sure you can dhclient in a way that it requests a prefix, eg:
#
# dhclient -6 -P -d eth0
#
# With the new prefix we can reconfigure Docker and restart it
#
# Make sure /etc/default/docker contains:
#
# DOCKER_OPTS="--ipv6 --fixed-cidr-v6=`cat /etc/docker/ipv6.prefix`"
#
# This script requires sipcalc to function
command -v sipcalc >/dev/null 2>&1 || exit 0
SUBNET_SIZE=64
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
[Service]
ExecStart=
ExecStart=/bin/bash -c "/usr/bin/dockerd --experimental --ip6tables --ipv6 --fixed-cidr-v6=`cat /etc/docker/ipv6.prefix` -H fd:// --containerd=/run/containerd/containerd.sock"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment