如何为Docker容器分配IPv6地址

使容器中的服务支持IPv6

其实不需要特别分配IPv6地址。只要把相应的端口映射上,Docker会把外部的IPv6地址端口也映射到容器的IPv4端口上。所以,只要访问主机的IPv6相应端口即可。

可喜可贺。

可是,端口映射本来就是IPv4地址不够时的一种妥协方案,IPv6地址那么充足,所有容器共用一个IPv6地址简直是暴殄天物。如何给每个容器都分配一个IPv6地址呢?

为Docker网络分配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

查看分配的IPv6地址(以Debian/Ubuntu为例)

使用下面的命令查看分配到Docker网络的IPv6地址段。

ifconfig

如果提示找不到命令,请使用下面的命令安装网络工具。

apt-get install net-tools

输出结果应当包含下列内容。

如何为Docker容器分配IPv6地址_第1张图片

此处2001:470开头的地址就是Docker自动分配的网关地址,80是前缀长度。实际显示的内容取决于你分配给Docker的子网。

为Docker容器分配IPv6地址

完成了上面的配置之后,无需特意配置,只需正常建立容器,即可为容器分配IPv6地址。

建立之后,可以使用“docker inspect 容器名”查看容器的IP地址。

如何为Docker容器分配IPv6地址_第2张图片

为 Docker 容器分配固定 IPv6 地址

通过以上方法为容器默认网络分配 IPv6 地址段后,在容器启动时会分配到 IPv6 地址。但是,地址是在每次启动时分配的,每次分到的地址都不相同,在使用上很不方便。那么,如何固定容器的 IPv6 地址呢?

方法一、建立网络,使用 --ip6 参数

待完成。

方法二、指定容器的 MAC 地址

由于容器的 IPv6 地址是通过 MAC 地址和网络前缀确定的,而网络前缀固定不变,所以我们可以通过指定 MAC 地址来使容器获得固定的 IPv6 地址。

docker run [your-arguments] --mac-address [some-mac-address] [image-name]

创建完毕之后,可以使用 docker inspect 命令查看容器的 MAC 地址和 IPv6 地址。

NDP 代理(有时需要)

如果建立容器后,从本机能访问,但是无法从外部用 IPv6 地址访问,则可能需要使用 NDP(邻居发现协议)代理。关于这部分内容,请参见 Using NDP proxying。我会在未来详细补充。

变通方法:使用 IPv6 NAT

Docker 对 IPv6 支持不完善之处

Docker 对 IPv6 的支持有待完善(老实说,是很差)。虽然可以使用本文前面提到的方法给容器提供 IPv6 地址,但是以下问题难以解决:

  • 通过上述方式分配的 IPv6 地址开放了所有端口,可能存在安全问题。
  • 必须为每个容器指定 IPv6 地址,非常麻烦,否则每次运行都可能变化。
  • 当使用 -p 开放端口,又访问主机 IPv6 地址的该端口时,容器无法获取访问的源地址。
  • 必须在配置文件或参数中写入固定的 IPv6 前缀。如果你的 IPv6 地址段经常变化(例如:使用家庭宽带),上述方法将完全无效。

为了解决这些问题,可以使用 IPv6 NAT 变通解决。

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

你可能感兴趣的:(Docker,IPv6,容器,NAT)