将 RIPE Atlas 探针从树莓派原生环境迁移到 Docker 容器时,默认网络栈只提供 IPv4 NAT,IPv6 完全缺位。作者需要在不暴露入站端口的前提下,让容器使用 ISP 分配的公网 IPv6 前缀(示例 2001:db8::/56)中的特定地址发起出站连接,避免额外 NATv6 层,同时保持镜像可移植。
**方案对比:macvlan 与 NDP 代理**
macvlan 驱动能让容器直接接收路由器的 DHCPv6 与路由通告(RA),像独立主机一样完成地址自动配置。但这要求在镜像内固化目标 IPv6 地址或编写入口脚本从环境变量读取,破坏了 Docker “一次构建、到处运行” 的可移植性,且需在宿主机网卡开启混杂模式,增加运维复杂度。原文未给出具体性能数据,仅指出该路径“笨重且违背 Docker 核心目标”。
**采用方案:docker-compose 定义 IPv6 网络 + 宿主机 NDP 代理**
作者在 `docker-compose.yaml` 中创建仅含 IPv6 ULA 前缀的 `probe-network`,容器获得 `2001:db8::1` 等内部地址。关键步骤在宿主机:
1. 在物理接口(如 `eth0`)上启用 `proxy_ndp` 与 `forwarding`,使内核对目标公网地址(如 `2001:db8::42`)回应邻居请求。
2. 用 `ip -6 neigh add proxy 2001:db8::42 dev eth0` 把容器选用的公网地址注册为代理邻居。
3. 在宿主机加一条 `ip -6 route add 2001:db8::42/128 dev docker0`(或对应网桥),把该 /128 路由指向容器侧网桥。
容器出站包经网桥到达宿主机,宿主机按路由转发至上游;上游回包因 NDP 代理直接送达宿主机再经路由回容器。全程无 NATv6,容器镜像无需感知公网地址,地址仅在编排文件与宿主机命令中声明。原文未给出吞吐量或延迟对比数据。
**工程师落地要点**
该模式适合“仅出站、需固定公网 IPv6、拒绝 NATv6” 的轻量服务(监控探针、日志采集、定时任务)。部署时需确认宿主机内核 ≥ 4.15 支持 `proxy_ndp`,且上游路由器允许该 /56 前缀下任意 /128 由宿主机代理回应。若 ISP 仅下发单个 /64 而非 /56,需改用 NDP 代理全前缀模式或改回 macvlan。排查时优先抓取宿主机 `eth0` 与 `docker0` 的 ICMPv6 邻居请求/通告,确认代理生效与路由回程。
原文: APNIC Blog(2021-07-06)|编译自 APNIC Blog,事实以原文为准。
来源:APNIC Blog