为 docker 启用 IPv6 会破坏主机 IPv6 连接,导致主机都没有 IPv6 连接

tom*_*ums 5 ipv6 linode arch-linux docker

前言:我在 Docker 和网络方面都是新手,尤其是 IPv6。我是软件开发人员,而不是系统/网络管理员。

我正在 Linode 上运行 Arch,并希望设置支持 IPv6 的 Docker。我可以使用 IPv4,虽然我还没有解决这个问题,但我仍然使用 IPv4,但我真的很期待启用 IPv6。

由于我正在使用systemd-networkd我必须启用IPForward=kernel我已经完成的操作。

如果 Docker 没有运行,显然 IPv6 适用于我的 Arch。

如果我在没有 IPv6 的情况下运行 Docker,Arch 将具有 IPv6 连接。

现在,如果我在启用 IPv6 的情况下运行 Docker:,docker daemon --ipv6 --fixed-cidr-v6="XXXXX/64" -H fd://它会破坏我的 Arch 的 IPv6 连接,并且它在容器内也不起作用。

我发现的一个区别是,如果没有适用于 Docker 的 IPv6,我的 Arch 上有一个 IPv6 的默认路由:

[root@x ~]# ip -6 route show
2a01:7e00::/64 dev enp0s4  proto kernel  metric 256  pref medium
fe80::/64 dev enp0s4  proto kernel  metric 256  pref medium
fe80::/64 dev docker0  proto kernel  metric 256  pref medium
default via fe80::1 dev enp0s4  proto ra  metric 1024  expires 73sec hoplimit 64 pref medium
Run Code Online (Sandbox Code Playgroud)

启用 IPv6 后,我会看到以下内容:

[root@x ~]# ip -6 route show
2a01:7e00::/64 dev enp0s4  proto kernel  metric 256  pref medium
2a01:7e00::/64 dev docker0  metric 1024  pref medium
fe80::/64 dev enp0s4  proto kernel  metric 256  pref medium
fe80::/64 dev docker0  proto kernel  metric 256  pref medium
Run Code Online (Sandbox Code Playgroud)

不过,手动添加默认 IPv6 路由:

ip -6 route add default via fe80::1 dev enp0s4
Run Code Online (Sandbox Code Playgroud)

为我的主机启用 IPv6,但容器仍然没有 IPv6 连接。


信息和我尝试过的

  • 为了测试连接,我正在使用ping6.
  • 充当我的测试虚拟对象的容器是base/archlinux
  • 手动将默认 IPv6 路由添加到主机后,重新启动 docker - 没有成功。
  • 通过设置默认 IPv6 路由docker0会使主机和容器都失去连接。
  • 在任何情况下,我都无法通过容器的 IPv6 地址 ping 我的主机。
  • 我遵循了Docker IPv6 指南,并尝试将我的 docker 守护进程的 IPv6 子网更改为 80,但没有帮助(不过,鉴于我的专业知识,我可能做错了什么)。
  • 我还尝试设置(如指南中所述)sysctl net.ipv6.conf.eth0.accept_ra=2,但在容器上它会出现错误:sysctl: setting key "net.ipv6.conf.eth0.accept_ra": Read-only file system。在主机上,没有任何变化。
  • 事实上,默认情况下主机没有 IPv6 路由,这让我认为这来自 Docker 方面。

启用 IPv6 时主机的 IP 配置:

[root@apitecture ~]# ip addr show dev enp0s4; ip addr show dev docker0; ip -6 route show
3: enp0s4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether f2:3c:91:ae:1a:0a brd ff:ff:ff:ff:ff:ff
    inet xxx.xxx.xxx.xxx/24 brd xxx.xxx.xxx.255 scope global enp0s4
       valid_lft forever preferred_lft forever
    inet6 2a01:7e00::xxxx:xxxx:xxxx:xxxx/64 scope global
       valid_lft 2590589sec preferred_lft 603389sec
    inet6 fe80::f03c:91ff:feae:1a0a/64 scope link
       valid_lft forever preferred_lft forever
13: docker0@NONE: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default
    link/ether 02:42:cd:3d:04:60 brd ff:ff:ff:ff:ff:ff
    inet 172.17.42.1/16 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:cdff:fe3d:460/64 scope link
       valid_lft forever preferred_lft forever
    inet6 fe80::1/64 scope link
       valid_lft forever preferred_lft forever
2a01:7e00::/64 dev enp0s4  proto kernel  metric 256  pref medium
2a01:7e00::/64 dev docker0  metric 1024  pref medium
fe80::/64 dev enp0s4  proto kernel  metric 256  pref medium
fe80::/64 dev docker0  proto kernel  metric 256  pref medium
Run Code Online (Sandbox Code Playgroud)

启用 IPv6 时容器的 IP 配置:

[root@x ~]# docker run -it --rm base/archlinux bash -c "ip -6 addr show dev eth0; ip -6 route show"
24: eth0@if25: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500
    inet6 2a01:7e00::xxx:xxxx:2/64 scope global tentative
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:2/64 scope link tentative
       valid_lft forever preferred_lft forever
2a01:7e00::/64 dev eth0  proto kernel  metric 256
fe80::/64 dev eth0  proto kernel  metric 256
default via fe80::1 dev eth0  metric 1024
Run Code Online (Sandbox Code Playgroud)

xxxx是隐藏的,希望我不必暴露我的公共地址。

我该如何解决为 Docker 启用 IPv6 的问题?

小智 0

我遇到类似的问题。我的设置是在 Debian LXC 中运行 docker 镜像,它又在 Proxmox 上运行。

官方的编辑方式/etc/docker/daemon.json对我来说从来不起作用。更糟糕的是,无论是否编辑此文件,docker 网桥都会中断我主机的 ipv6 连接。

对于我的情况,ip -6 route add default via xxxx dev eth0然后添加network_mode: "host"主机docker-compose.yml和容器的启用 ipv6 访问。

但是,添加 ipv6 路由部分fe80::1对我来说不起作用。当 docker 守护进程关闭时,我必须采用默认的 ipv6 路由。唯一的缺点是每次 LXC 重新启动时,都必须执行该命令。