其实不需要特别分配IPv6地址。只要把相应的端口映射上,Docker会把外部的IPv6地址端口也映射到容器的IPv4端口上。所以,只要访问主机的IPv6相应端口即可。
可喜可贺。
可是,端口映射本来就是IPv4地址不够时的一种妥协方案,IPv6地址那么充足,所有容器共用一个IPv6地址简直是暴殄天物。如何给每个容器都分配一个IPv6地址呢?
首先,如果要启用Docker的IPv6支持功能,你必须确保你的机器有至少/80的地址段。
编辑/etc/docker/daemon.json
文件,加入以下内容:
{
"ipv6": true,
"fixed-cidr-v6": "2001:db8:1::/64"
}
其中2001:db8:1::/64
是IPv6地址段。
使用下面的命令重启Docker。
systemctl restart docker
使用下面的命令查看分配到Docker网络的IPv6地址段。
ifconfig
如果提示找不到命令,请使用下面的命令安装网络工具。
apt-get install net-tools
输出结果应当包含下列内容。
此处2001:470开头的地址就是Docker自动分配的网关地址,80是前缀长度。实际显示的内容取决于你分配给Docker的子网。
完成了上面的配置之后,无需特意配置,只需正常建立容器,即可为容器分配IPv6地址。
建立之后,可以使用“docker inspect
容器名”查看容器的IP地址。
通过以上方法为容器默认网络分配 IPv6 地址段后,在容器启动时会分配到 IPv6 地址。但是,地址是在每次启动时分配的,每次分到的地址都不相同,在使用上很不方便。那么,如何固定容器的 IPv6 地址呢?
--ip6
参数待完成。
由于容器的 IPv6 地址是通过 MAC 地址和网络前缀确定的,而网络前缀固定不变,所以我们可以通过指定 MAC 地址来使容器获得固定的 IPv6 地址。
docker run [your-arguments] --mac-address [some-mac-address] [image-name]
创建完毕之后,可以使用 docker inspect
命令查看容器的 MAC 地址和 IPv6 地址。
如果建立容器后,从本机能访问,但是无法从外部用 IPv6 地址访问,则可能需要使用 NDP(邻居发现协议)代理。关于这部分内容,请参见 Using NDP proxying。我会在未来详细补充。
Docker 对 IPv6 的支持有待完善(老实说,是很差)。虽然可以使用本文前面提到的方法给容器提供 IPv6 地址,但是以下问题难以解决:
-p
开放端口,又访问主机 IPv6 地址的该端口时,容器无法获取访问的源地址。为了解决这些问题,可以使用 IPv6 NAT 变通解决。
我们可以使用 robbertkl/docker-ipv6nat 为 Docker 提供 IPv6 NAT 功能。
首先,编辑 /etc/docker/daemon.json
文件,指定 IPv6 地址段。请注意,尽量使用本地 IPv6 地址段(fc00::/7
),以免与其他地址冲突。
然后,按下面的方式启动镜像
docker run -d --restart=always -v /var/run/docker.sock:/var/run/docker.sock:ro --privileged --net=host robbertkl/ipv6nat
启动镜像之后,你就可以像 IPv4 一样使用 -p
开放容器内的 IPv6 端口。
某些系统可能未启用内核中必要的模块,可以在运行时加入 -v /lib/modules:/lib/modules:ro
,此映像会自动载入。
参考资料
How IPv6 works on Docker
robbertkl/docker-ipv6nat