在 Docker 环境中,网络是一个非常重要的抽象层。每个容器都可以连接到一个或多个网络,以实现灵活的网络配置。Docker 安装完成后,会自动创建三个网络:bridge
、host
和 none
。本文将详细介绍如何在 Docker 中配置和使用 IPv6 网络,包括默认 bridge
网络和自定义 bridge
网络的支持。
背景知识:Docker 网络
通过 docker network ls
命令,可以查看 Docker 中现有的网络:
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
7f1f7db5b7b1 bridge bridge local
3d504a8db83a host host local
9f9f87d75e03 none null local
其中,bridge
网络是 Docker 的默认网络,容器在没有指定网络的情况下会连接到这个网络。默认 bridge
网络在宿主机上创建了一个名为 docker0
的 bridge 设备,并为其配置了一个私有网段的网关 IP 地址。
$ ip addr show docker0
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP ...
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
默认 bridge
网络支持 IPv6
前置条件
确保你的设备被分配了一个 IPv6 地址。通过 ip addr show
查看当前设备的 IPv6 地址:
$ ip addr show
...
inet6 2001:db8::1/64 scope global
valid_lft forever preferred_lft forever
输出的物理网卡包含 inet6
和 scope global
的行时,表示该网卡支持 IPv6。需要注意的是,IPv6 地址的前缀不能是 /128
,否则建议通过 IPv6 NAT 方式支持 IPv6。
配置步骤
-
修改
/etc/docker/daemon.json
:添加
fixed-cidr-v6
配置,使用你获取到的 IPv6 网段的子网(前缀长度最大为/80
):{ "fixed-cidr-v6": "2001:db8:1::/80" }
-
重新加载 Docker 配置:
$ sudo systemctl reload docker
-
验证配置:
通过
docker network inspect bridge
命令检查是否生效。若生效,则EnableIPv6
值为true
,IPAM.Config[1].Subnet
是配置的fixed-cidr-v6
。$ docker network inspect bridge [ { ... "EnableIPv6": true, "IPAM": { ... "Config": [ { "Subnet": "172.17.0.0/16" }, { "Subnet": "2001:db8:1::/80" } ] } } ]
注意:在某些情况下,配置可能不会生效,例如 /etc/docker/daemon.json
存在 "live-restore": true
字段,或 reload 时有容器仍然存在。
额外配置
可能需要以下两步来确保 NDP proxy 支持:
-
修改
/etc/sysctl.conf
并执行sysctl -p
:net.ipv6.conf.all.proxy_ndp=1 net.ipv6.conf.docker0.proxy_ndp=1
-
安装并配置
ndppd
服务:安装
ndppd
服务以转发邻居发现消息,并修改配置文件:# Example configuration for /etc/ndppd.conf proxy eth0 { rule 2001:db8:1::/80 { exclusive } }
更改
proxy eth0
到宿主机绑定 IPv6 的网卡,例如proxy ens3
。然后执行:$ sudo systemctl restart ndppd
注意:本方法仅针对新装 Docker 场景,且容器的 IPv6 地址不是私有网段,而是宿主机网络的一个子网,因此所有端口对于 IPv6 都是公开的。
自定义网络支持 IPv6
前置条件
确保设备支持 IPv6,步骤与上文相同。
创建支持 IPv6 的自定义 bridge
网络
-
创建网络:
使用
--ipv6
和--subnet
参数创建支持 IPv6 的bridge
网络:$ docker network create my-net-ipv6 --ipv6 --subnet="2001:db8:2::/80"
-
验证网络:
通过
docker network inspect my-net-ipv6
命令检查是否生效。$ docker network inspect my-net-ipv6 [ { ... "EnableIPv6": true, "IPAM": { ... "Config": [ { "Subnet": "2001:db8:2::/80" } ] } } ]
-
运行容器:
创建容器时,通过
--network
参数指定自定义网络:$ docker run --network my-net-ipv6 -it busybox ip addr show ... inet6 2001:db8:2::2/80 scope global eth0 valid_lft forever preferred_lft forever
通过 IPv6 NAT 方式支持 IPv6
在某些场景下,直接使用公开的 IPv6 地址可能不满足安全性或网段限制的要求。此时,可以使用 IPv6 NAT。
实施步骤
-
启动 IPv6 NAT 容器:
使用
robbertkl/ipv6nat
镜像启动 IPv6 NAT 服务:$ docker run -d --name ipv6nat --privileged --network host --restart always -v /var/run/docker.sock:/var/run/docker.sock:ro -v /lib/modules:/lib/modules:ro robbertkl/ipv6nat
-
创建支持 IPv6 的
bridge
网络:创建一个带有私有 IPv6 网段的
bridge
网络:$ docker network create my-net-ipv6 --ipv6 --subnet="fd00:1::1/80" --gateway="fd00:1::1"
-
验证网络:
通过
docker network inspect my-net-ipv6
命令检查是否生效。 -
运行容器:
创建容器并连接到自定义网络:
$ docker run --network my-net-ipv6 -it busybox sh / # ip addr show ... inet6 fd00:1::2/80 scope global eth0 valid_lft forever preferred_lft forever / # wget https://ipv6.icanhazip.com -O /dev/stdout 2>/dev/null Your IPv6 address is: xxxx:xxxx:xxxx:xxxx::xxxx
通过以上步骤,你可以在 Docker 中成功配置和使用 IPv6 网络,无论是默认的 bridge
网络还是自定义的 bridge
网络,甚至是通过 IPv6 NAT 方式。希望这些详细的步骤和示例代码能帮助你在 Docker 环境中顺利开启 IPv6 支持。