使用 IPv6 网络

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

创建一个 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 池从一个前缀长度为 `/56` 的 IPv6 池中提供了多达 256 个大小为 `/64` 的 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 池来自私有地址范围,类似于默认的 IPv6 ULA 网络。

Docker in Docker

在使用 `xtables` (旧版 `iptables`) 而非 `nftables` 的主机上,必须先加载内核模块 `ip6_tables`,然后才能创建 IPv6 Docker 网络。它通常在 Docker 启动时自动加载。

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

后续步骤

© . This site is unofficial and not affiliated with Kubernetes or Docker Inc.