折腾一天快把我逼疯了
本来 Docker 对 IPv6 的支持就不好,再来个 rootless,雪上加霜
首先,我们要区分 Docker Engine 和 里面的 Image。
拉取映像是 Docker Engine 在工作,也就是那个 Daemon 本身,而不是某个 container 或 image。
Rootless Docker 使用 RootlessKit 来管理用户命名空间、网络命名空间等,而 RootlessKit 内部使用 slirp4netns 来虚拟化网络栈。
开启虚拟网络的 IPv6 支持
准备工作
将 docker-ce 和一系列 rootless 工具全部升级到最新版:
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras
特别地,将 slirp4netns 升级到 1.2 以上。
如果用 Ubuntu 22.04 或更早版本的,可以去下载 Debian Bookworm 的 deb 包安装。
修改服务参数
编辑 systemd 服务配置。
将以下内容写入 ~/.config/systemd/user/docker.service.d/override.conf
:
[Service]
Environment=DOCKERD_ROOTLESS_ROOTLESSKIT_FLAGS=--ipv6
重载 systemd 并重启 docker 服务:
systemctl --user daemon-reload
systemctl --user restart docker
添加 IPv6 路由
到这里如果尝试拉取映像,应该还是不走 IPv6。如果走了,忽略本步。
进入虚拟网络空间:
dockerd-rootless-setuptool.sh nsenter
查看当前路由:
输入 route -6
,路由表可能长下面这样
# route -6
Kernel IPv6 routing table
Destination Next Hop Flag Met Ref Use If
fd40:200::/64 [::] U 256 2 0 br-3fba6095d8f6
fd80:100:1::/64 [::] U 256 1 0 docker0
fd80:100:1::/64 [::] U 1024 1 0 docker0
fe80::/64 [::] U 256 2 0 tap0
ip6-localhost/128 [::] Un 0 2 0 lo
fe80::/128 [::] Un 0 3 0 tap0
fe80::7c5b:bbff:fed4:1747/128 [::] Un 0 5 0 tap0
ip6-mcastprefix/8 [::] U 256 5 0 tap0
ip6-mcastprefix/8 [::] U 256 1 0 docker0
[::]/0 [::] !n -1 1 0 lo
路由表的问题就是没有一个往 tap0 的 [::]/0
路由,所以我们要添加出来。
在此之前,我们要先找默认网关。
# ip -6 neigh show dev tap0
fe80::2 lladdr 52:56:00:00:00:02 router STALE
这里我的默认网关就是 fe80::2
,接下来我们添加路由。
ip -6 route add default via fe80::2 dev tap0 metric 100
via 后面就写刚才找到的默认网关。
metric 是跃点数,越小越优先,我这里设成路由表里的最小值。
注意事项
重启 docker 服务之后需要重新添加路由表。