关键在于三层协同:宿主机内核需启用IPv6转发与RA接收,Docker守护进程须配置ipv6、fixed-cidr-v6、ip6tables和experimental四项,再配合容器路由与DNS(如指定2001:4860:4860::8888)确保连通。

直接启用 IPv6 并让容器正常访问外网,关键不在“修容器”,而在理清三层依赖:宿主机内核支持、Docker 守护进程配置、网络路由与防火墙协同。多数路由异常其实源于其中某一层被忽略或配置冲突。
确认宿主机 IPv6 路由与转发能力
容器的 IPv6 出口依赖宿主机作为“下一跳路由器”。若宿主机本身没有可用的 IPv6 默认路由,或未开启转发,容器必然无法连通外部。
- 运行 ip -6 route show,检查是否存在以 default via 开头的条目;若无,说明缺少默认网关
- 运行 sysctl net.ipv6.conf.all.forwarding,输出必须为 1;若为 0,执行 sudo sysctl -w net.ipv6.conf.all.forwarding=1 并写入 /etc/sysctl.conf 持久化
- 对物理网卡(如 eth0)也需显式启用 RA 接收:sudo sysctl -w net.ipv6.conf.eth0.accept_ra=2(值为 2 表示无论 forwarding 是否开启都接收路由器通告)
正确配置 Docker daemon 启用 IPv6
Docker 默认禁用 IPv6,仅修改 daemon.json 不够,还需匹配地址段、防火墙和实验性功能。
- 编辑 /etc/docker/daemon.json,确保包含以下四项(缺一不可):
"ipv6": true,
"fixed-cidr-v6": "fc00::/7",
"ip6tables": true,
"experimental": true - fc00::/7 是推荐的私有 IPv6 地址段,避免与公网或 ISP 分配的前缀冲突;不要用 2001:db8::/32 等文档保留地址作生产网段
- 保存后执行 sudo systemctl daemon-reload && sudo systemctl restart docker,再用 docker network inspect bridge 验证输出中 "IPv6Enabled" 为 true
优先使用 host 网络模式验证基础连通性
当桥接网络反复失败时,先绕过所有 Docker 网络栈抽象,用 host 模式快速定位是容器配置问题还是底层环境问题。
- 运行 docker run --network host --rm alpine ping6 -c 3 ifconfig.co
- 若成功,说明宿主机 IPv6 路由、DNS、防火墙均正常,问题出在 bridge 网络配置或容器内部路由表
- 若失败,则问题仍在宿主机层(如 RA 未生效、默认路由丢失、ip6tables DROP 策略拦截),无需继续调试容器网络
排查容器内 IPv6 路由与 DNS
即使 daemon 配置正确,容器仍可能因缺失默认路由或 DNS 解析失败而“看似不通”。
- 进入容器执行 ip -6 route,确认存在类似 default via fe80::1 dev eth0 的条目;若只有 fe80::/10 链路本地路由,说明 Docker 未正确注入网关
- DNS 是高频故障点:容器默认复用宿主机 /etc/resolv.conf,但某些系统(如使用 systemd-resolved)会写入 127.0.0.53(IPv4 only)。建议在 daemon.json 中全局指定 IPv6 可达的 DNS:
"dns": ["2001:4860:4860::8888", "2001:4860:4860::8844"] - 测试解析:docker run --rm alpine nslookup -query=AAAA google.com 2001:4860:4860::8888



















