概述

Docker 对 IPv6 的支持已经很久了,但默认仍未启用。本文记录在 Debian 13 下通过 NAT ULA,让容器获得 IPv6 出网能力。这种方式无需配置复杂的路由广播,使用体验与 IPv4 几乎完全一致。

修改配置

编辑 Docker 守护进程配置文件

sudo vim /etc/docker/daemon.json

写入以下配置:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "20m",
    "max-file": "3"
  },
  // 全局启用 IPv6
  "ipv6": true,
  // 分配 ULA 地址块
  "fixed-cidr-v6": "fd00:dead:beef::/64",
  "experimental": true,
  // 启用 NAT 转换
  "ip6tables": true,
  // 私有地址池
  "default-address-pools": [
    {
      "base": "172.17.0.0/16",
      "size": 24
    },
    {
      "base": "fd00:dead:beef:100::/80",
      "size": 112
    }
  ]
}

重启 Docker 服务使配置生效:

sudo systemctl restart docker

使用

验证容器现在是否具有 IPv6 出网能力

# HTTP/2 200
sudo docker run --rm curlimages/curl curl -s -I -6 https://blog.zsh.moe

对于 Compose 编排的容器服务,使用也很简单,以 Warp Docker 为例:

services:
  warp:
    image: caomingjun/warp:slim-latest
    container_name: warp
    restart: unless-stopped
    networks:
      - warp-tunnel
    device_cgroup_rules:
      - 'c 10:200 rwm'
    environment:
      - WARP_SLEEP=2
      - GOST_ARGS=-L socks5://:1080?udp=true -L http://:1081
    cap_add:
      - MKNOD
      - AUDIT_WRITE
      - NET_ADMIN
    sysctls:
      - net.ipv6.conf.all.disable_ipv6=0
      - net.ipv4.conf.all.src_valid_mark=1
      # 开启 IPv6 转发
      - net.ipv6.conf.all.forwarding=1
      # 接受 Docker 网桥路由公告
      - net.ipv6.conf.all.accept_ra=2
      - net.ipv4.ip_forward=1
    volumes:
      - ./data:/var/lib/cloudflare-warp

networks:
  warp-tunnel:
    name: warp-tunnel
    driver: bridge
    # 显式指定启用 IPv6 支持
    enable_ipv6: true

启动服务

sudo docker compose up -d

检查容器内网络接口,可以看到已成功获取私有地址

sudo docker exec warp ip -6 addr show
# 输出示例
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 state UNKNOWN qlen 1000
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0@if60: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP
    # IPv6 ULA 池划分的 IP
    inet6 fd00:dead:beef:100::2/112 scope global nodad
       valid_lft forever preferred_lft forever
    inet6 fe80::3cc7:aaff:fed1:1680/64 scope link
       valid_lft forever preferred_lft forever
3: CloudflareWARP: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1280 state UNKNOWN qlen 500
    inet6 2606:4700:cf1:1000::3/128 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::6594:3a07:3299:4dbe/64 scope link stable-privacy
       valid_lft forever preferred_lft forever

测试 Warp IPv6 代理的出网能力

# HTTP/2 200
sudo docker exec warp curl -x socks5h://[::1]:1080 -6 https://blog.zsh.moe -v

结论

我们预先定义了一个巨大的私有地址池,Docker 会自动给容器分配私有 IPv6,再经过宿主机 NAT 出网。无需手动划分子网,即可赋予容器无感知的双栈出网能力。

参考资料: