Featured image of post IPv6 Only服务器配置Docker双栈网络教程

IPv6 Only服务器配置Docker双栈网络教程

IPv6-only 服务器 + WARP IPv4

环境背景

网络拓扑

第一步:确认网络环境

查看当前网络配置

1
2
3
4
5
6
7
# 查看 IPv6 地址和路由
ip -6 addr show
ip -6 route show

# 查看 IPv4 接口(WARP)
ip addr show warp
ip route show table all

示例输出

1
2
3
4
5
6
7
8
9
# ip -6 addr show
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
    inet6 ace:ceb:deca:deed::4/128 scope global dynamic noprefixroute 
       valid_lft 17220508sec preferred_lft 8580508sec
    inet6 fe80::222:48ff:fe18:e45b/64 scope link 
       valid_lft forever preferred_lft forever

# ip route show table all
default dev warp table 51820 scope link (WARP 路由在 table 51820)

上述输出中,inet6 ace:ceb:deca:deed::4/128 这一行显示的即为主机的公网 IPv6 地址(由 scope global 标识)。实际配置时,应优先选用带有 global 标记的 IPv6 地址作为 Docker 网络的外部通信地址。以 fe80 开头且标记为 scope link 的 IPv6 地址属于链路本地地址,仅限本地链路通信,通常不用于公网访问或 Docker 网络配置。

第二步:配置 Docker 支持 IPv6

创建 Docker 配置文件

1
2
3
4
5
6
7
8
9
cat > /etc/docker/daemon.json << EOF
{
  "ipv6": true,
  "fixed-cidr-v6": "ace:ceb:deca:deed:1::/80",
  "experimental": true,
  "ip6tables": true,
  "dns": ["2001:4860:4860::8888", "2001:4860:4860::8844"]
}
EOF

配置说明

  • fixed-cidr-v6: 应改为你的主 IPv6 地址的子网
  • experimental: 启用实验性功能
  • ip6tables: 启用 IPv6 防火墙规则

重启 Docker

1
2
systemctl restart docker
systemctl status docker

验证 IPv6 配置

1
docker network inspect bridge

应该看到:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
"IPAM": {
    "Config": [
        {
            "Subnet": "172.17.0.0/16",
            "Gateway": "172.17.0.1"
        },
        {
            "Subnet": "ace:ceb:deca:deed:1::/80",
            "IPRange": "ace:ceb:deca:deed:1::/80",
            "Gateway": "ace:ceb:deca:deed:1::1"
        }
    ]
}

第三步:配置 IPv4 流量路由

Docker 默认 IPv4 流量走主机默认路由(eth0),但 WARP 路由在独立的路由表 51820 中。

添加 iptables 规则

1
2
3
4
5
6
# NAT 规则:让容器流量伪装成主机流量
iptables -t nat -A POSTROUTING -s 172.17.0.0/16 -o warp -j MASQUERADE

# FORWARD 规则:允许流量转发
iptables -A FORWARD -i docker0 -o warp -j ACCEPT
iptables -A FORWARD -i warp -o docker0 -j ACCEPT

添加策略路由规则

1
2
3
4
5
# 让 Docker 子网流量使用 WARP 路由表
ip rule add from 172.17.0.0/16 table 51820 priority 100

# 在 WARP 路由表中添加返回路由
ip route add 172.17.0.0/16 dev docker0 table 51820

重启 Docker 使配置生效

1
systemctl restart docker

第四步:验证双栈网络

启动测试容器

1
docker run --rm -it ubuntu:latest bash

在容器内测试网络

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# 安装网络工具
apt update && apt install -y iputils-ping curl

# 查看容器网络接口
ip addr show

# 测试 IPv4 连接
ping -c 3 8.8.8.8
curl -4 http://ipv4.icanhazip.com

# 测试 IPv6 连接
ping6 -c 3 2001:4860:4860::8888
curl -6 http://ipv6.icanhazip.com

# 测试域名解析(自动选择协议)
curl https://google.com

预期结果

  • ✅ IPv4 ping 和 curl 成功
  • ✅ IPv6 ping 和 curl 成功
  • ✅ 双栈域名访问正常

第五步:持久化配置

保存 iptables 规则

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# Ubuntu/Debian
apt install iptables-persistent
iptables-save > /etc/iptables/rules.v4

# 或者添加到启动脚本
cat > /etc/systemd/system/docker-ipv4-routing.service << EOF
[Unit]
Description=Docker IPv4 routing via WARP
After=docker.service
Requires=docker.service

[Service]
Type=oneshot
ExecStart=/bin/bash -c 'iptables -t nat -A POSTROUTING -s 172.17.0.0/16 -o warp -j MASQUERADE; iptables -A FORWARD -i docker0 -o warp -j ACCEPT; iptables -A FORWARD -i warp -o docker0 -j ACCEPT; ip rule add from 172.17.0.0/16 table 51820 priority 100; ip route add 172.17.0.0/16 dev docker0 table 51820'
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF

systemctl enable docker-ipv4-routing.service

至此,Docker 容器已可以在 IPv6-only 服务器上正常使用双栈网络。

故障排除

常见问题

1. Docker 启动失败

1
2
# 查看日志
journalctl -xeu docker.service

2. IPv4 连接失败

1
2
3
4
5
6
# 检查路由规则
ip rule show
ip route show table 51820

# 检查 iptables 规则
iptables -t nat -L -n | grep 172.17

3. IPv6 连接失败

1
2
3
# 检查 IPv6 路由
ip -6 route show
docker network inspect bridge

调试命令

1
2
3
4
5
6
7
# 抓包调试
tcpdump -i docker0 icmp
tcpdump -i warp icmp

# 路由追踪
ip route get 8.8.8.8 from 172.17.0.2
traceroute 8.8.8.8

高级配置

创建自定义双栈网络

1
2
3
4
5
6
7
8
docker network create --driver bridge \
  --ipv6 \
  --subnet=172.20.0.0/16 \
  --subnet=ace:ceb:deca:deed:2::/80 \
  mynetwork

# 使用自定义网络
docker run --rm -it --network mynetwork ubuntu:24.04

强制使用特定协议

1
2
3
4
5
# 只使用 IPv4
docker run --rm -it --sysctl net.ipv6.conf.all.disable_ipv6=1 ubuntu:24.04

# 优先使用 IPv6
docker run --rm -it --sysctl net.ipv6.conf.all.forwarding=1 ubuntu:24.04