如何使用 docker-compose 分配 IPv6 地址
How to assign IPv6 address with docker-compose
我在 Ubuntu 16.04 上使用 docker 1.12.1,并且 docker-compose 1.8.1。我正在尝试将 Compose 文件从 https://docs.docker.com/compose/compose-file/#ipv4-address-ipv6-address 获取到 运行。作为参考,我创建了 docker-compose.yml
,内容如下:
version: '2'
services:
app:
image: busybox
command: ifconfig
networks:
app_net:
ipv4_address: 172.16.238.10
ipv6_address: 2001:3984:3989::10
networks:
app_net:
driver: bridge
driver_opts:
com.docker.network.enable_ipv6: "true"
ipam:
driver: default
config:
- subnet: 172.16.238.0/24
gateway: 172.16.238.1
- subnet: 2001:3984:3989::/64
gateway: 2001:3984:3989::1
现在,运行宁docker-compose up
生产
Creating network "tmp_app_net" with driver "bridge"
Creating tmp_app_1
Attaching to tmp_app_1
app_1 | eth0 Link encap:Ethernet HWaddr 02:42:AC:10:EE:0A
app_1 | inet addr:172.16.238.10 Bcast:0.0.0.0 Mask:255.255.255.0
app_1 | inet6 addr: fe80::42:acff:fe10:ee0a/64 Scope:Link
app_1 | UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
app_1 | RX packets:4 errors:0 dropped:0 overruns:0 frame:0
app_1 | TX packets:1 errors:0 dropped:0 overruns:0 carrier:0
app_1 | collisions:0 txqueuelen:0
app_1 | RX bytes:520 (520.0 B) TX bytes:90 (90.0 B)
app_1 |
app_1 | lo Link encap:Local Loopback
app_1 | inet addr:127.0.0.1 Mask:255.0.0.0
app_1 | inet6 addr: ::1/128 Scope:Host
app_1 | UP LOOPBACK RUNNING MTU:65536 Metric:1
app_1 | RX packets:0 errors:0 dropped:0 overruns:0 frame:0
app_1 | TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
app_1 | collisions:0 txqueuelen:1
app_1 | RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
app_1 |
tmp_app_1 exited with code 0
未分配 IPv6 地址。
我已经试过了:
- 使用
--ipv6
启动 docker 守护进程
- 用
--ipv6 --fixed-cidr-v6="2001:3984:3989::/64"
启动 docker 守护进程
- 请注意
docker run -it busybox ifconfig
实际上在这里给了我一个 IPv6 地址(来自分配给默认 bridge
网络的 --fixed-cidr
子网)
- 使用我的实际 IPv6 子网而不是代码示例中的子网,并使用此子网重复 2.
没有成功。有什么想法吗?
事实证明这确实是一个 docker-compose bug,将在 1.9.0 中修复。
同时,通过使用 docker network
命令创建自定义网络有一个解决方法:
docker network create --subnet=172.16.2.0/24 --gateway=172.16.2.1 --ipv6 --subnet=<myV6Network/subnet> dockerbridge
... 然后可以通过编写
在 docker-composed.yml
中提供
networks:
dockerbridge:
external:
name: dockerbridge
是的。 Docker compose 支持 IPv6 协议,它被引入到 docker engine 1.5 之后。还有issue with latest compose file format 3.3
所以你可以使用 2.1 格式。仍然 docker swarm 在高级网络配置方面还不够成熟,并且它不支持 IPv6,因此它不包含在 3.3 fil 格式中。
这是文件示例,
docker-compose.yml
version: ‘2.1’
services:
app:
image: busybox
command: ping www.google.com
networks:
app_net:
ipv6_address: 2001:3200:3200::20
networks:
app_net:
enable_ipv6: true
driver: bridge
ipam:
driver: default
config:
- subnet: 2001:3200:3200::/64
gateway: 2001:3200:3200::1
此 docker 组合文件将基于子网 2001:3200:3200::/64 下的 IPv6 网络创建一个名为 testping_app_net 的新网络并且容器应该自动分配 IPv6 地址。
让我们使用 docker 启动服务-组合并查看服务是否通过 IPv6 协议进行通信:
docker-compose up -d
您可以使用
验证每个容器的 IPv6 地址
docker exec -it 905 ip addr
您会看到一个新容器获得了 IPv6 地址 – 2001:3200:3200::20,因此它们能够相互通信。
注意: 如果你想在主机上启用 IPv6,默认情况下使用 IPv4 地址,你需要将这两行添加到 daemon.json /etc/docker目录下:
{
"ipv6": true,
"fixed-cidr-v6": "2001:db8:1::/64"
}
并通过命令重新启动 docker 守护程序:
$ sudo systemctl restart docker
简答:
在您的 docker-compose.yml
文件中添加 (3) 个指令,(1) 到 daemon.json 然后重新构建您的容器并将 Docker 主机的 SLAAC 地址接口放到 docker-组成网桥,容器本身将收到一个 IPV6 SLAAC 地址。
此解决方案被证明与以下版本兼容:
- docker-compose v. 2.1.1 和
- docker-撰写文件格式 v. 3.9.
如果您不知道如何实现上述目标,请阅读下面较长的答案。其实并不难,也不费时。
简介:
(请随意跳过这个介绍 - 只是关于我正在尝试解决的问题的上下文)。
像访问此问题的其他人一样,我也遇到了 docker-compose 中的 IPv6 网络问题。据我所知,某些 IPV6 指令仅适用于更旧的 docker-compose 文件版本。我猜这可能会导致较旧的 docker-compose 文件版本不支持较新的指令。有些解决方案不适用于 swarm。
许多人似乎能够在他们的 docker-compose 配置中获得 IPV6 连接的唯一方法是使用一些沮丧的 Docker 用户编码的“IPV6 NAT”。顺便说一句,这不是批评:我们需要不会被打败的人,他们顽强地想方设法绕过 problems/limitations。但是 IPv6 应该可以解决 NAT 的问题 ;-)
我想:必须有更简单的方法!
还有……
我的设置:
如果您 运行 遇到困难,我将描述我的设置以启用比较分析:
为 IPv6 SLAAC 寻址配置的 MikroTik 路由器连接到双栈 IPV4/V6 交换机。
A Raspberry Pi 4 运行ning 64bit Ubuntu 20.04 LTS 通过 eth0 连接到交换机,从中获得其 IPv6 全球单播地址(“GUA ") 来自路由器。
Docker 使用的版本 = Docker Engine Community v. 20.10.11
docker-compose = v.2.1.1
docker-撰写文件格式=v.3.9
docker-编写 IPv6 配置:
docker-compose.yml
我的 networks
部分:
networks:
my-custom-network:
name: my-custom-network
enable_ipv6: true
ipam:
driver: default
config:
- subnet: 192.168.XX.0/24
gateway: 192.168.xx.1
请注意,唯一特定于 IPv6 的指令只是 enable_ipv6: true
接下来,我的 docker-compose.yml
文件的相关部分包含 services
部分中的其他 (2) IPv6 特定指令,用于我想要 IPV6 地址的容器是:
sysctls:
- net.ipv6.conf.all.disable_ipv6=0
- net.ipv6.conf.eth0.proxy_ndp=1
显然是 YAML,请注意使用正确的前导空格将该部分放入,否则当唯一的问题是指令的缩进时,它会产生误导性错误。
/etc/docker/daemon.json
我在这里添加了 (1) 特定于 IPv6 的指令:
"ipv6": true, "fixed-cidr-v6": "2001:470:1d3f:8::/64",
此步骤是为我们的容器分配 IPv6 全球可路由 IPv6 地址所必需的。
最后,在完成调整后剪切一组新的容器(但先不要启动它们):
docker-compose build --no-cache
Docker 主机网络配置:
在执行 IPv6 Docker 配置之前,通过从您的 Docker 主机使用 ping6
ping 某些内容来验证路由器的 IPv6 配置是否正确:
ping6 ipv6.google.com
如果成功返回响应,则表明 Docker 主机和路由器都可以解析和路由 IPv6 数据包。问题现在减少到只解决容器 IPV6 问题。
- 由于 Pi 的 eth0 接口本身是 IPv6 地址,并且很高兴地与我们的路由器对话 IPv6,我们将把它加入 docker-compose 桥:
找到docker-compose bridge name "br-series-of-random-chars":
ip addr list
将 eth0 添加到网桥:
ip link set dev eth0 master br-ckkde30ff0g
注意:上面的命令是NON-Persistent-它不会在重启后继续存在。添加eth0的过程可以完全自动化..
检查 eth0 现已加入:
ip link | grep "master br-ckkde30ff0g"
启动您的容器:
docker-compose start
现在将容器验证为 IPv6 GUA:
docker exec -it containerName bash
然后:
hostname -I
您现在应该会看到 SLAAC 配置的 IPv6 GUA 地址。
- 在您的 IPv6 防火墙上打个洞以根据需要定制访问
安全:
谢天谢地,您看不到的内容:接收 IPv6 GUA 地址的任何其他容器。
只有在其配置中包含上述 sysctls
指令的容器才会收到 SLAAC IPv6 地址 - 没有其他地址。就我而言,我只想在 WordPress 站点前面公开代理容器,而不是其他容器、网络服务器和后备数据库。所以只有代理可以通过IPv6访问。
配置验证:
以下站点是使用上述过程配置的 100% docker-compose 装置,因此可以证明此处概述的过程可以正常工作:
http://[2001:470:1d3f:8:42:c0ff:fea8:1504]/
请注意:我将在下周更改 ISP,因此在配置新的 link 时可能会有一些停机时间。
您还可以使用 IPv6 测试站点验证容器 IPv6 寻址的 IPV6 配置:
https://ipv6-test.com/validate.php
如果为裸域设置了 AAAA DNS 记录- domain.com- 然后将其作为 url 输入检查器。
如果为子域 www 设置了 AAAA 记录,则输入 www.domain.com进入检查器。
结论:
就是这样:只有 docker-compose
中的 (3) IPv6 特定指令,daemon.json
中的 (1),一些桥接和正确配置 IPv6 的路由器。完毕。并且不需要 NATing。
同样,这不是一个完美的解决方案,也不是理想的解决方案,但它是解决 IPv6 连接问题的另一种方法。如果我错过了某个地方的步骤,请给我评论。
我在 Ubuntu 16.04 上使用 docker 1.12.1,并且 docker-compose 1.8.1。我正在尝试将 Compose 文件从 https://docs.docker.com/compose/compose-file/#ipv4-address-ipv6-address 获取到 运行。作为参考,我创建了 docker-compose.yml
,内容如下:
version: '2'
services:
app:
image: busybox
command: ifconfig
networks:
app_net:
ipv4_address: 172.16.238.10
ipv6_address: 2001:3984:3989::10
networks:
app_net:
driver: bridge
driver_opts:
com.docker.network.enable_ipv6: "true"
ipam:
driver: default
config:
- subnet: 172.16.238.0/24
gateway: 172.16.238.1
- subnet: 2001:3984:3989::/64
gateway: 2001:3984:3989::1
现在,运行宁docker-compose up
生产
Creating network "tmp_app_net" with driver "bridge"
Creating tmp_app_1
Attaching to tmp_app_1
app_1 | eth0 Link encap:Ethernet HWaddr 02:42:AC:10:EE:0A
app_1 | inet addr:172.16.238.10 Bcast:0.0.0.0 Mask:255.255.255.0
app_1 | inet6 addr: fe80::42:acff:fe10:ee0a/64 Scope:Link
app_1 | UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
app_1 | RX packets:4 errors:0 dropped:0 overruns:0 frame:0
app_1 | TX packets:1 errors:0 dropped:0 overruns:0 carrier:0
app_1 | collisions:0 txqueuelen:0
app_1 | RX bytes:520 (520.0 B) TX bytes:90 (90.0 B)
app_1 |
app_1 | lo Link encap:Local Loopback
app_1 | inet addr:127.0.0.1 Mask:255.0.0.0
app_1 | inet6 addr: ::1/128 Scope:Host
app_1 | UP LOOPBACK RUNNING MTU:65536 Metric:1
app_1 | RX packets:0 errors:0 dropped:0 overruns:0 frame:0
app_1 | TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
app_1 | collisions:0 txqueuelen:1
app_1 | RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
app_1 |
tmp_app_1 exited with code 0
未分配 IPv6 地址。
我已经试过了:
- 使用
--ipv6
启动 docker 守护进程
- 用
--ipv6 --fixed-cidr-v6="2001:3984:3989::/64"
启动 docker 守护进程- 请注意
docker run -it busybox ifconfig
实际上在这里给了我一个 IPv6 地址(来自分配给默认bridge
网络的--fixed-cidr
子网)
- 请注意
- 使用我的实际 IPv6 子网而不是代码示例中的子网,并使用此子网重复 2.
没有成功。有什么想法吗?
事实证明这确实是一个 docker-compose bug,将在 1.9.0 中修复。
同时,通过使用 docker network
命令创建自定义网络有一个解决方法:
docker network create --subnet=172.16.2.0/24 --gateway=172.16.2.1 --ipv6 --subnet=<myV6Network/subnet> dockerbridge
... 然后可以通过编写
在docker-composed.yml
中提供
networks:
dockerbridge:
external:
name: dockerbridge
是的。 Docker compose 支持 IPv6 协议,它被引入到 docker engine 1.5 之后。还有issue with latest compose file format 3.3 所以你可以使用 2.1 格式。仍然 docker swarm 在高级网络配置方面还不够成熟,并且它不支持 IPv6,因此它不包含在 3.3 fil 格式中。 这是文件示例,
docker-compose.yml
version: ‘2.1’
services:
app:
image: busybox
command: ping www.google.com
networks:
app_net:
ipv6_address: 2001:3200:3200::20
networks:
app_net:
enable_ipv6: true
driver: bridge
ipam:
driver: default
config:
- subnet: 2001:3200:3200::/64
gateway: 2001:3200:3200::1
此 docker 组合文件将基于子网 2001:3200:3200::/64 下的 IPv6 网络创建一个名为 testping_app_net 的新网络并且容器应该自动分配 IPv6 地址。
让我们使用 docker 启动服务-组合并查看服务是否通过 IPv6 协议进行通信:
docker-compose up -d
您可以使用
验证每个容器的 IPv6 地址docker exec -it 905 ip addr
您会看到一个新容器获得了 IPv6 地址 – 2001:3200:3200::20,因此它们能够相互通信。
注意: 如果你想在主机上启用 IPv6,默认情况下使用 IPv4 地址,你需要将这两行添加到 daemon.json /etc/docker目录下:
{
"ipv6": true,
"fixed-cidr-v6": "2001:db8:1::/64"
}
并通过命令重新启动 docker 守护程序:
$ sudo systemctl restart docker
简答:
在您的 docker-compose.yml
文件中添加 (3) 个指令,(1) 到 daemon.json 然后重新构建您的容器并将 Docker 主机的 SLAAC 地址接口放到 docker-组成网桥,容器本身将收到一个 IPV6 SLAAC 地址。
此解决方案被证明与以下版本兼容:
- docker-compose v. 2.1.1 和
- docker-撰写文件格式 v. 3.9.
如果您不知道如何实现上述目标,请阅读下面较长的答案。其实并不难,也不费时。
简介:
(请随意跳过这个介绍 - 只是关于我正在尝试解决的问题的上下文)。
像访问此问题的其他人一样,我也遇到了 docker-compose 中的 IPv6 网络问题。据我所知,某些 IPV6 指令仅适用于更旧的 docker-compose 文件版本。我猜这可能会导致较旧的 docker-compose 文件版本不支持较新的指令。有些解决方案不适用于 swarm。
许多人似乎能够在他们的 docker-compose 配置中获得 IPV6 连接的唯一方法是使用一些沮丧的 Docker 用户编码的“IPV6 NAT”。顺便说一句,这不是批评:我们需要不会被打败的人,他们顽强地想方设法绕过 problems/limitations。但是 IPv6 应该可以解决 NAT 的问题 ;-)
我想:必须有更简单的方法!
还有……
我的设置:
如果您 运行 遇到困难,我将描述我的设置以启用比较分析:
为 IPv6 SLAAC 寻址配置的 MikroTik 路由器连接到双栈 IPV4/V6 交换机。
A Raspberry Pi 4 运行ning 64bit Ubuntu 20.04 LTS 通过 eth0 连接到交换机,从中获得其 IPv6 全球单播地址(“GUA ") 来自路由器。
Docker 使用的版本 = Docker Engine Community v. 20.10.11
docker-compose = v.2.1.1
docker-撰写文件格式=v.3.9
docker-编写 IPv6 配置:
docker-compose.yml
我的 networks
部分:
networks:
my-custom-network:
name: my-custom-network
enable_ipv6: true
ipam:
driver: default
config:
- subnet: 192.168.XX.0/24
gateway: 192.168.xx.1
请注意,唯一特定于 IPv6 的指令只是 enable_ipv6: true
接下来,我的 docker-compose.yml
文件的相关部分包含 services
部分中的其他 (2) IPv6 特定指令,用于我想要 IPV6 地址的容器是:
sysctls:
- net.ipv6.conf.all.disable_ipv6=0
- net.ipv6.conf.eth0.proxy_ndp=1
显然是 YAML,请注意使用正确的前导空格将该部分放入,否则当唯一的问题是指令的缩进时,它会产生误导性错误。
/etc/docker/daemon.json
我在这里添加了 (1) 特定于 IPv6 的指令:
"ipv6": true, "fixed-cidr-v6": "2001:470:1d3f:8::/64",
此步骤是为我们的容器分配 IPv6 全球可路由 IPv6 地址所必需的。
最后,在完成调整后剪切一组新的容器(但先不要启动它们):
docker-compose build --no-cache
Docker 主机网络配置:
在执行 IPv6 Docker 配置之前,通过从您的 Docker 主机使用
ping6
ping 某些内容来验证路由器的 IPv6 配置是否正确:ping6 ipv6.google.com
如果成功返回响应,则表明 Docker 主机和路由器都可以解析和路由 IPv6 数据包。问题现在减少到只解决容器 IPV6 问题。
- 由于 Pi 的 eth0 接口本身是 IPv6 地址,并且很高兴地与我们的路由器对话 IPv6,我们将把它加入 docker-compose 桥:
找到docker-compose bridge name "br-series-of-random-chars":
ip addr list
将 eth0 添加到网桥:
ip link set dev eth0 master br-ckkde30ff0g
注意:上面的命令是NON-Persistent-它不会在重启后继续存在。添加eth0的过程可以完全自动化..
检查 eth0 现已加入:
ip link | grep "master br-ckkde30ff0g"
启动您的容器:
docker-compose start
现在将容器验证为 IPv6 GUA:
docker exec -it containerName bash
然后:hostname -I
您现在应该会看到 SLAAC 配置的 IPv6 GUA 地址。
- 在您的 IPv6 防火墙上打个洞以根据需要定制访问
安全:
谢天谢地,您看不到的内容:接收 IPv6 GUA 地址的任何其他容器。
只有在其配置中包含上述 sysctls
指令的容器才会收到 SLAAC IPv6 地址 - 没有其他地址。就我而言,我只想在 WordPress 站点前面公开代理容器,而不是其他容器、网络服务器和后备数据库。所以只有代理可以通过IPv6访问。
配置验证:
以下站点是使用上述过程配置的 100% docker-compose 装置,因此可以证明此处概述的过程可以正常工作:
http://[2001:470:1d3f:8:42:c0ff:fea8:1504]/
请注意:我将在下周更改 ISP,因此在配置新的 link 时可能会有一些停机时间。
您还可以使用 IPv6 测试站点验证容器 IPv6 寻址的 IPV6 配置:
https://ipv6-test.com/validate.php
如果为裸域设置了 AAAA DNS 记录- domain.com- 然后将其作为 url 输入检查器。
如果为子域 www 设置了 AAAA 记录,则输入 www.domain.com进入检查器。
结论:
就是这样:只有 docker-compose
中的 (3) IPv6 特定指令,daemon.json
中的 (1),一些桥接和正确配置 IPv6 的路由器。完毕。并且不需要 NATing。
同样,这不是一个完美的解决方案,也不是理想的解决方案,但它是解决 IPv6 连接问题的另一种方法。如果我错过了某个地方的步骤,请给我评论。