Enable IPv6 for Docker

This article will introduce how to enable IPv6 support for Docker.

Allocating Existing Addresses

This is the officially supported method by Docker. If you have an IPv6 address longer than 128 bits, you can assign it to a container. You can enable IPv6 for Docker’s default bridge network by modifying the /etc/docker/daemon.json file or Docker startup command parameters:

1
2
3
4
{
  "ipv6": true,
  "fixed-cidr-v6": "2001:db8:1::/64"
}

Alternatively, you can create an IPv6-supporting bridge network with the following command:

1
docker network create --ipv6 --subnet 2001:db8:1::/64 <name>

However, this approach brings a significant problem. Assigning a public IPv6 address to a container makes the container’s port mappings outside Docker’s control, potentially exposing some services to the public network. Additionally, some cloud service providers (such as Azure) allocate only a 128-bit public IPv6 address to virtual machines, leaving no additional addresses for containers.

Using IPv6 NAT

Docker has experimentally introduced support for IPv6 NAT. This feature easily solves the issues mentioned above by assigning Unique Local Address (ULA) addresses to containers. You can enable this feature by modifying the /etc/docker/daemon.json file or command parameters (since this feature is experimental, you need to enable experimental):

1
2
3
4
{
  "ip6tables": true,
  "experimental": true
}

Now, you only need to allocate ULA addresses for Docker networks. RFC 4193 recommends using a randomly generated approach to avoid address conflicts during network merging. (You can use this ULA Generator, which generates ULA based on MAC address and timestamp.)

Similarly, you can enable IPv6 support for the default bridge network and create an IPv6-supporting Docker network using the same approach in the /etc/docker/daemon.json file or Docker startup command parameters:

1
2
3
4
5
6
{
  "ipv6": true,
  "fixed-cidr-v6": "fd00::/64",
  "ip6tables": true,
  "experimental": true
}
1
docker network create --ipv6 --subnet fd00::/64 <name>

It’s important to note that by default, in gai.conf, the ULA has lower priority than IPv4, so some programs using libc may prefer IPv4 over IPv6. You can modify the /etc/gai.conf file to change the priority.

Docker Compose Configuration

As Docker Swarm currently does not support IPv6, Docker Compose configurations with version 3 do not support creating networks using IPv6. This can be addressed by using configurations with version 2 or by using external Docker networks. Here’s an example configuration:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
version: '2.4'

networks:
  bridge:
    driver: bridge
    enable_ipv6: true
    ipam:
      config:
        - subnet: 2001:db8:1::/64
          gateway: 2001:db8:1::1

Troubleshooting

If your IPv6 network is not functioning correctly after these operations, it may be because IPv6 forwarding is not enabled. You can enable IPv6 forwarding by modifying /etc/sysctl.conf, files under the /etc/sysctl.d/ folder, or using the sysctl command:

1
2
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.default.forwarding = 1

After modifying the file, you can use the sysctl -p command to apply the changes immediately.

If you use Router Advertisements, enabling IPv6 forwarding may cause them not to work. Setting net.ipv6.conf.eth0.accept_ra can make them work properly when IPv6 forwarding is enabled. Here, eth0 is the name of the network interface that accepts router advertisements.

1
net.ipv6.conf.eth0.accept_ra = 2
Built with Hugo
Theme Stack designed by Jimmy