环境

环境

我在 docker 中启用 IPv6 时遇到了严重的问题。

环境

  • 主机正在运行 Debian Jessie。
  • 它是一个虚拟服务器(KVM)。
  • eth0 具有静态配置的地址,例如 w:x:y:z::1,位于 w:xy:z::/64 之类的网络中,由我的托管公司分配给我。
  • 我的主机能够毫无问题地使用 IPv6:可以 Ping 外部世界,在容器上运行的网站(端口 80 绑定到主机:80)可以通过 ipv6 访问。

问题

但是我无法从容器内部访问外部世界!使用以下参数重新启动 docker 后,我的 docker0 网桥没有 IPv6 地址。没有路由,也没有网关(没有 ipv6 地址就没有意义)。

我的 Docker 设置:Docker 使用 DOCKER_OPTS 中的这些参数启动

DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4 --ipv6 --fixed-cidr-v6=w:x:y:z:a::/80"

一些 ipv6 主机配置参数:

net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.default.forwarding = 1

这是我自己创建的网络之一:

root@wopr:~# docker network inspect wopr6
[
    {
        "Name": "wopr6",
        "Id": "ddc192d4af2a8edc809975e84cf3e4cb82c24d4cfe970dd8e3fc7d6ff31e20ee",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": true,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.23.0.0/16",
                    "Gateway": "172.23.0.1/16"
                },
                {
                    "Subnet": "w:x:y:z:a:0:0:0/80",
                    "Gateway": "w:x:y:z:a::1"
                }
            ]
        },
        "Internal": false,
        "Containers": {
            "dff30ab1496a4c3689ad6da0837fdb6cf7ea1a5b32312116214313b5b14ed07e": {
                "Name": "happy_varahamihira",
                "EndpointID": "8cd4ed4b91d8421171ec8cc771bbe7b7d81f05dc9f4679f20c642c2e828ec475",
                "MacAddress": "02:42:ac:17:00:02",
                "IPv4Address": "172.23.0.2/16",
                "IPv6Address": "w:x:y:z:a::2/80"
            }
        },
        "Options": {},
        "Labels": {}
    }
]

以下是上面提到的容器内部的一些信息:

地址

root@dff30ab1496a:/# ip -6 a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
332: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500
    inet6 2a03:4000:6:2158:a::2/80 scope global nodad
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe17:2/64 scope link
       valid_lft forever preferred_lft forever

航线

root@dff30ab1496a:/# ip -6 r
2a03:4000:6:2158:a::/80 dev eth0  proto kernel  metric 256
fe80::/64 dev eth0  proto kernel  metric 256
default via 2a03:4000:6:2158:a::1 dev eth0  metric 1024

PING ipv6.l.google.com (2a00:1450:4001:811::200e): 56 data bytes, id 0x0011 = 17
--- ipv6.l.google.com ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss

我错过了什么?

答案1

因此,在等待了两周的答案并在开启赏金后又研究了几个小时后,我找到了解决方案。

  1. 设置一个新的启用 IPv6 的网络并分配一个可用的子网(我的 /64 中的 /80)

    docker network create --ipv6 --subnet=w:x:y:z:aaaa::/80 myfancynetwork
    

    现在启动一个容器并将其连接到新网络。找出它的 IP 地址。在本例中,我们假设它是 w:x:y:z:aaaa::5。

  2. 启用 proxy_ndp

    sysctl net.ipv6.conf.eth0.proxy_ndp=1
    

    您也可以通过 /etc/sysctl.conf 配置此设置,以使其持久。

  3. 添加代理以使我的主机(启用 IPv6)使用邻居广告消息(“那就是我!”)响应来自我的路由器的邻居请求消息(例如:“嘿,谁托管 w:x:y:z:aaaa::5?”)。

    ip -6 neigh add proxy w:x:y:z:aaaa::5 dev eth0
    

    ndppd 可以帮助您自动宣传您网络上的任何主机。

巴姆,就是这样。

答案2

有关 Docker IPv6 网络的完整且详尽的解释可在此处找到使用 Docker 的 IPv6 @ gdevillele.github.io

根据这篇文章,NDP 代理的替代方法是允许在面向公众的网络接口上添加多个 IPv6 路由:

检测面向公众的网络接口:

default_interface="$(command ip route show 'default' |
    command head --lines=1 |
    command cut --delimiter=' ' --fields=5)"

sysctl在默认网络接口上创建允许 2 个 IPv6 路由的配置:

sudo tee "/etc/sysctl.d/99-net-ipv6-conf-${default_interface}-accept_ra.conf" << EOF
# Allow two IPv6 routes on ${default_interface}
net.ipv6.conf.${default_interface}.accept_ra=2
EOF

加载配置:

sudo systemctl 'force-reload' 'procps'

一旦正确配置了 Docker 守护进程 IPv6 功能,这将允许 Docker 中的传出 IPv6 路由正常工作。

相关内容