使用 IPv6 网络

IPv6仅支持在Linux主机上运行的Docker守护进程。

创建IPv6网络

  • 使用docker network create

    $ docker network create --ipv6 ip6net
    
  • 使用docker network create,指定IPv6子网

    $ docker network create --ipv6 --subnet 2001:db8::/64 ip6net
    
  • 使用Docker Compose文件

     networks:
       ip6net:
         enable_ipv6: true
         ipam:
           config:
             - subnet: 2001:db8::/64

您现在可以运行连接到ip6net网络的容器。

$ docker run --rm --network ip6net -p 80:80 traefik/whoami

这在IPv6和IPv4上都发布了80端口。您可以通过运行curl,连接到IPv6环回地址上的80端口来验证IPv6连接。

$ curl http://[::1]:80
Hostname: ea1cfde18196
IP: 127.0.0.1
IP: ::1
IP: 172.17.0.2
IP: 2001:db8::2
IP: fe80::42:acff:fe11:2
RemoteAddr: [2001:db8::1]:37574
GET / HTTP/1.1
Host: [::1]
User-Agent: curl/8.1.2
Accept: */*

对默认桥接网络使用IPv6

以下步骤将向您展示如何在默认桥接网络上使用IPv6。

  1. 编辑Docker守护进程配置文件,位于/etc/docker/daemon.json。配置以下参数

    {
      "ipv6": true,
      "fixed-cidr-v6": "2001:db8:1::/64"
    }
    • ipv6在默认网络上启用IPv6网络。
    • fixed-cidr-v6为默认桥接网络分配子网,启用动态IPv6地址分配。
    • ip6tables启用额外的IPv6数据包过滤器规则,提供网络隔离和端口映射。它默认启用,但可以禁用。
  2. 保存配置文件。

  3. 重新启动Docker守护进程以使更改生效。

    $ sudo systemctl restart docker
    

您现在可以在默认桥接网络上运行容器。

$ docker run --rm -p 80:80 traefik/whoami

这在IPv6和IPv4上都发布了80端口。您可以通过向IPv6环回地址上的80端口发出请求来验证IPv6连接。

$ curl http://[::1]:80
Hostname: ea1cfde18196
IP: 127.0.0.1
IP: ::1
IP: 172.17.0.2
IP: 2001:db8:1::242:ac12:2
IP: fe80::42:acff:fe12:2
RemoteAddr: [2001:db8:1::1]:35558
GET / HTTP/1.1
Host: [::1]
User-Agent: curl/8.1.2
Accept: */*

动态IPv6子网分配

如果您没有显式配置用户定义网络的子网(使用docker network create --subnet=<your-subnet>),则这些网络使用守护进程的默认地址池作为回退。这也适用于从Docker Compose文件创建的网络,其中enable_ipv6设置为true

如果Docker Engine的default-address-pools中不包含任何IPv6池,并且没有给出--subnet选项,则启用IPv6时将使用唯一本地地址(ULA)。这些/64子网包括一个基于Docker Engine随机生成的ID的40位全局ID,以获得很高的唯一性概率。

要使用不同的IPv6子网池进行动态地址分配,您必须手动配置守护进程的地址池,使其包含:

  • 默认IPv4地址池
  • 一个或多个您自己的IPv6池

默认地址池配置为:

{
  "default-address-pools": [
    { "base": "172.17.0.0/16", "size": 16 },
    { "base": "172.18.0.0/16", "size": 16 },
    { "base": "172.19.0.0/16", "size": 16 },
    { "base": "172.20.0.0/14", "size": 16 },
    { "base": "172.24.0.0/14", "size": 16 },
    { "base": "172.28.0.0/14", "size": 16 },
    { "base": "192.168.0.0/16", "size": 20 }
  ]
}

以下示例显示了具有默认值和IPv6池的有效配置。示例中的IPv6池提供了最多256个大小为/64的IPv6子网,来自前缀长度为/56的IPv6池。

{
  "default-address-pools": [
    { "base": "172.17.0.0/16", "size": 16 },
    { "base": "172.18.0.0/16", "size": 16 },
    { "base": "172.19.0.0/16", "size": 16 },
    { "base": "172.20.0.0/14", "size": 16 },
    { "base": "172.24.0.0/14", "size": 16 },
    { "base": "172.28.0.0/14", "size": 16 },
    { "base": "192.168.0.0/16", "size": 20 },
    { "base": "2001:db8::/56", "size": 64 }
  ]
}

注意

此示例中的地址2001:db8::为文档使用而保留的。请将其替换为有效的IPv6网络。

默认IPv4池来自专用地址范围,类似于默认IPv6ULA网络。

Docker in Docker

在使用xtables(旧版iptables)而不是nftables的主机上,必须先加载内核模块ip6_tables才能创建 IPv6 Docker 网络。通常情况下,Docker 启动时会自动加载该模块。

但是,如果您在未基于最新版本的官方docker镜像 的Docker in Docker环境中运行 Docker,则可能需要在主机上运行modprobe ip6_tables。或者,使用守护进程选项--ip6tables=false来禁用容器化 Docker Engine 的ip6tables

后续步骤