Rootless 模式

无根模式允许以非root用户运行Docker守护进程和容器,以减轻守护进程和容器运行时中的潜在漏洞。

只要满足前提条件,即使在安装 Docker 守护进程期间,Rootless 模式也不需要 root 权限。

工作原理

Rootless 模式在用户命名空间内执行 Docker 守护进程和容器。 这与 userns-remap 模式非常相似,除了 在 userns-remap 模式下,守护进程本身以 root 权限运行, 而在无根模式下,守护进程和容器都在没有 root 权限的情况下运行。

Rootless 模式不使用带有 SETUID 位或文件功能的Binaries, 除了 newuidmap 和 newgidmap,它们是允许在用户命名空间中使用多个 UID/GID 所必需的。

前提条件

  • 您必须在主机上安装 newuidmap 和 newgidmap。这些命令在大多数发行版中由 uidmap 包提供。

  • /etc/subuid 和 /etc/subgid 应该为用户包含至少 65,536 个从属 UID/GID。在以下示例中,用户 testuser 拥有 65,536 个从属 UID/GID(231072-296607)。

$ id -u
1001
$ whoami
testuser
$ grep ^$(whoami): /etc/subuid
testuser:231072:65536
$ grep ^$(whoami): /etc/subgid
testuser:231072:65536

特定于发行版的提示

提示

我们建议您使用 Ubuntu 内核。


  • 如果未安装 dbus-user-session 包,请安装它。运行 sudo apt-get install -y dbus-user-session 并重新登录。

  • 如果未安装 uidmap 包,请安装它。运行 sudo apt-get install -y uidmap。

  • 如果在一个用户未直接登录的终端中运行,您需要使用 systemd-container 安装 sudo apt-get install -y systemd-container,然后使用命令 sudo machinectl shell TheUser@ 切换到 TheUser。

  • overlay2 存储驱动程序默认启用 ( Ubuntu特定的内核补丁)。

  • Ubuntu 24.04 及更高版本默认启用了受限的非特权用户命名空间,这会阻止非特权进程创建用户命名空间,除非配置了 AppArmor 配置文件以允许程序使用非特权用户命名空间。

    如果您使用 deb 软件包 (apt-get install docker-ce-rootless-extras) 安装 docker-ce-rootless-extras,那么 rootlesskit 的 AppArmor 配置文件已随 apparmor deb 软件包一起提供。使用此安装方法,您无需手动添加任何 AppArmor 配置。但是,如果您使用 安装 脚本 安装无根额外组件,则必须为 rootlesskit 手动添加 AppArmor 配置文件:

    1. 创建并安装当前登录用户的 AppArmor 配置文件:

      $ filename=$(echo $HOME/bin/rootlesskit | sed -e s@^/@@ -e s@/@.@g)
      $ cat <<EOF > ~/${filename}
      abi <abi/4.0>,
      include <tunables/global>
      
      "$HOME/bin/rootlesskit" flags=(unconfined) {
        userns,
      
        include if exists <local/${filename}>
      }
      EOF
      $ sudo mv ~/${filename} /etc/apparmor.d/${filename}
      
    2. 重启 AppArmor。

      $ systemctl restart apparmor.service
      
  • 如果未安装 dbus-user-session 包,请安装它。运行 sudo apt-get install -y dbus-user-session 并重新登录。

  • 对于 Debian 10,请将 kernel.unprivileged_userns_clone=1 添加到 /etc/sysctl.conf(或 /etc/sysctl.d)并运行 sudo sysctl --system。此步骤在 Debian 11 上不需要。

  • 对于 Debian 11,建议安装 fuse-overlayfs。运行 sudo apt-get install -y fuse-overlayfs。 在 Debian 12 上不需要此步骤。

  • Rootless docker 要求 slirp4netns 的版本大于 v0.4.0(当未安装 vpnkit 时)。 请检查您是否具备此条件,

    $ slirp4netns --version
    

    如果您没有此下载,请使用 sudo apt-get install -y slirp4netns 下载并安装,或下载最新的 发布版本。

  • 建议安装 fuse-overlayfs。运行 sudo pacman -S fuse-overlayfs。

  • 将 kernel.unprivileged_userns_clone=1 添加到 /etc/sysctl.conf (或 /etc/sysctl.d)并运行 sudo sysctl --system

  • 对于 openSUSE 15 和 SLES 15,建议安装 fuse-overlayfs。运行 sudo zypper install -y fuse-overlayfs。 在 openSUSE Tumbleweed 上不需要此步骤。

  • sudo modprobe ip_tables iptable_mangle iptable_nat iptable_filter 是必需的。 根据配置,这可能也在其他发行版上是必需的。

  • 已知适用于 openSUSE 15 和 SLES 15。

  • 对于 RHEL 8 和类似发行版,建议安装 fuse-overlayfs。运行 sudo dnf install -y fuse-overlayfs。 在 RHEL 9 和类似发行版上不需要此步骤。

  • 您可能需要 sudo dnf install -y iptables。


已知限制

  • 仅支持以下存储驱动程序:
    • overlay2(仅在运行内核 5.11 或更高版本,或 Ubuntu 风格内核时)
    • fuse-overlayfs(仅在运行内核 4.18 或更高版本,且已安装 fuse-overlayfs 时)
    • btrfs(仅在运行内核 4.18 或更高版本,或 ~/.local/share/docker 以 user_subvol_rm_allowed 挂载选项挂载时)
    • vfs
  • Cgroup 仅在使用 cgroup v2 和 systemd 运行时受支持。请参阅 资源限制。
  • 不支持以下功能:
    • AppArmor
    • Checkpoint
    • Overlay network
    • 暴露 SCTP 端口
  • 要使用 ping 命令,请参阅 路由 ping 数据包。
  • 要暴露特权 TCP/UDP 端口(< 1024),请参阅 暴露特权端口。
  • IPAddress 显示在 docker inspect 中是在 RootlessKit 的网络命名空间内。 这意味着如果没有 nsenter 进入网络命名空间,该 IP 地址无法从主机访问。
  • 主机网络 (docker run --net=host) 在 RootlessKit 内部也被命名空间化。
  • 不支持将 NFS 挂载作为 Docker 的“data-root”。此限制并非仅限于无根模式。

安装

注意

如果系统范围的 Docker 守护进程已经在运行,请考虑将其禁用:

$ sudo systemctl disable --now docker.service docker.socket
$ sudo rm /var/run/docker.sock

如果您选择不关闭 docker 服务和套接字,您需要在下一节中使用 --force 参数。目前没有已知问题,但在您关闭并禁用之前,您仍在运行具有 root 权限的 Docker。


如果您通过 RPM/DEB packages 安装了 Docker 20.10 或更高版本,您应该在 /usr/bin 中有 dockerd-rootless-setuptool.sh。

以非 root 用户身份运行 dockerd-rootless-setuptool.sh install 来设置守护进程:

$ dockerd-rootless-setuptool.sh install
[INFO] Creating /home/testuser/.config/systemd/user/docker.service
...
[INFO] Installed docker.service successfully.
[INFO] To control docker.service, run: `systemctl --user (start|stop|restart) docker.service`
[INFO] To run docker.service on system startup, run: `sudo loginctl enable-linger testuser`

[INFO] Make sure the following environment variables are set (or add them to ~/.bashrc):

export PATH=/usr/bin:$PATH
export DOCKER_HOST=unix:///run/user/1000/docker.sock

如果不存在 dockerd-rootless-setuptool.sh,您可能需要手动安装 docker-ce-rootless-extras 软件包,例如,

$ sudo apt-get install -y docker-ce-rootless-extras

如果您没有权限运行像 apt-get 和 dnf 这样的软件包管理器, 请考虑使用位于 https://get.docker.com/rootless 的安装脚本。 由于静态软件包不适用于 s390x,因此不支持 s390x。

$ curl -fsSL https://get.docker.com/rootless | sh
...
[INFO] Creating /home/testuser/.config/systemd/user/docker.service
...
[INFO] Installed docker.service successfully.
[INFO] To control docker.service, run: `systemctl --user (start|stop|restart) docker.service`
[INFO] To run docker.service on system startup, run: `sudo loginctl enable-linger testuser`

[INFO] Make sure the following environment variables are set (or add them to ~/.bashrc):

export PATH=/home/testuser/bin:$PATH
export DOCKER_HOST=unix:///run/user/1000/docker.sock

Binaries将被安装在 ~/bin。


如果遇到错误,请参阅 故障排除。

卸载

要移除 Docker 守护进程的 systemd 服务,请运行 dockerd-rootless-setuptool.sh uninstall:

$ dockerd-rootless-setuptool.sh uninstall
+ systemctl --user stop docker.service
+ systemctl --user disable docker.service
Removed /home/testuser/.config/systemd/user/default.target.wants/docker.service.
[INFO] Uninstalled docker.service
[INFO] This uninstallation tool does NOT remove Docker binaries and data.
[INFO] To remove data, run: `/usr/bin/rootlesskit rm -rf /home/testuser/.local/share/docker`

如果您已将环境变量 PATH 和 DOCKER_HOST 添加到 ~/.bashrc 中,请取消设置它们。

要删除数据目录,请运行 rootlesskit rm -rf ~/.local/share/docker。

要删除Binaries,如果您使用包管理器安装了 Docker,请删除 docker-ce-rootless-extras 软件包。 如果您通过 https://get.docker.com/rootless ( 不使用包安装) 安装了 Docker, 请删除 ~/bin 下的Binaries:

$ cd ~/bin
$ rm -f containerd containerd-shim containerd-shim-runc-v2 ctr docker docker-init docker-proxy dockerd dockerd-rootless-setuptool.sh dockerd-rootless.sh rootlesskit rootlesskit-docker-proxy runc vpnkit

用法

守护进程


systemd 单元文件已安装为 ~/.config/systemd/user/docker.service。

使用 systemctl --user 来管理守护进程的生命周期:

$ systemctl --user start docker

要在系统启动时启动守护进程,请启用 systemd 服务和 lingering:

$ systemctl --user enable docker
$ sudo loginctl enable-linger $(whoami)

以 systemd-wide 服务 (/etc/systemd/system/docker.service) 启动无根 Docker 不受支持,即使使用 User= 指令。

要在不使用 systemd 的情况下直接运行守护进程,您需要运行 dockerd-rootless.sh 而不是 dockerd。

必须设置以下环境变量:

  • $HOME: 主目录
  • $XDG_RUNTIME_DIR:一个仅预期用户可访问的临时目录,例如 ~/.docker/run。 该目录应在每次主机关闭时被删除。 该目录可以位于 tmpfs 上,但不应位于 /tmp 下。 将该目录定位在 /tmp 下可能会受到 TOCTOU 攻击的影响。

关于目录路径的说明:

  • 套接字路径默认设置为 $XDG_RUNTIME_DIR/docker.sock。 $XDG_RUNTIME_DIR 通常设置为 /run/user/$UID。
  • 数据目录默认设置为 ~/.local/share/docker。 数据目录不应位于 NFS 上。
  • 守护进程配置目录默认设置为 ~/.config/docker。 该目录与客户端使用的 ~/.docker 不同。

客户端

您需要明确指定套接字路径或 CLI 上下文。

要使用 $DOCKER_HOST 指定套接字路径:

$ export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock
$ docker run -d -p 8080:80 nginx

要使用 docker context 指定 CLI 上下文:

$ docker context use rootless
rootless
Current context is now "rootless"
$ docker run -d -p 8080:80 nginx

最佳实践

无根 Docker 中的 Docker

要在“rootful” Docker 中运行 Rootless Docker,请使用 docker:<version>-dind-rootless 镜像而不是 docker:<version>-dind。

$ docker run -d --name dind-rootless --privileged docker:25.0-dind-rootless

docker:<version>-dind-rootless 镜像以非 root 用户(UID 1000)运行。 但是,--privileged 是禁用 seccomp、AppArmor 和挂载掩码所必需的。

通过 TCP 暴露 Docker API socket

要通过 TCP 暴露 Docker API 套接字,你需要使用 DOCKERD_ROOTLESS_ROOTLESSKIT_FLAGS="-p 0.0.0.0:2376:2376/tcp" 启动 dockerd-rootless.sh。

$ DOCKERD_ROOTLESS_ROOTLESSKIT_FLAGS="-p 0.0.0.0:2376:2376/tcp" \
  dockerd-rootless.sh \
  -H tcp://0.0.0.0:2376 \
  --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem

通过 SSH 暴露 Docker API 套接字

要通过SSH暴露Docker API套接字,您需要确保在远程主机上设置了$DOCKER_HOST。

$ ssh -l <REMOTEUSER> <REMOTEHOST> 'echo $DOCKER_HOST'
unix:///run/user/1001/docker.sock
$ docker -H ssh://<REMOTEUSER>@<REMOTEHOST> run ...

路由 ping 数据包

在某些发行版中,默认情况下 ping 不起作用。

将 net.ipv4.ping_group_range = 0 2147483647 添加到 /etc/sysctl.conf(或 /etc/sysctl.d)并运行 sudo sysctl --system 以允许使用 ping。

暴露特权端口

要暴露特权端口(< 1024),请在 rootlesskit Binaries上设置 CAP_NET_BIND_SERVICE 并重启守护进程。

$ sudo setcap cap_net_bind_service=ep $(which rootlesskit)
$ systemctl --user restart docker

或者将 net.ipv4.ip_unprivileged_port_start=0 添加到 /etc/sysctl.conf(或 /etc/sysctl.d)并运行 sudo sysctl --system。

限制资源

仅在使用 cgroup v2 和 systemd 运行时,才支持使用与 cgroup 相关的 docker run 标志(如 --cpus、--memory、--pids-limit)来限制资源。 请参阅 更改 cgroup 版本 以启用 cgroup v2。

如果 docker info 显示 none 为 Cgroup Driver,则条件不满足。 当这些条件不满足时,无根模式会忽略与 cgroup 相关的 docker run 标志。 请参阅 不使用 cgroup 限制资源 以获取解决方法。

如果 docker info 显示 systemd 为 Cgroup Driver,则满足条件。 然而,通常情况下,只有 memory 和 pids 控制器默认被委托给非 root 用户。

$ cat /sys/fs/cgroup/user.slice/user-$(id -u).slice/user@$(id -u).service/cgroup.controllers
memory pids

要允许委托所有控制器,您需要按如下方式更改systemd配置:

# mkdir -p /etc/systemd/system/user@.service.d
# cat > /etc/systemd/system/user@.service.d/delegate.conf << EOF
[Service]
Delegate=cpu cpuset io memory pids
EOF
# systemctl daemon-reload

注意

委托 cpuset 需要 systemd 244 或更高版本。

不使用 cgroup 限制资源

即使 cgroup 不可用,您仍然可以使用传统的 ulimit 和 cpulimit, 尽管它们以进程粒度而非容器粒度工作, 并且可以被容器进程任意禁用。

例如:

  • 要将 CPU 使用限制在 0.5 核心(类似于 docker run --cpus 0.5): docker run <IMAGE> cpulimit --limit=50 --include-children <COMMAND>

  • 要将最大 VSZ 限制为 64MiB(类似于 docker run --memory 64m): docker run <IMAGE> sh -c "ulimit -v 65536; <COMMAND>"

  • 要将每个命名空间 UID 2000 的最大进程数限制为 100 (类似于 docker run --pids-limit=100): docker run --user 2000 --ulimit nproc=100 <IMAGE> <COMMAND>

故障排除

当系统中存在 systemd 时无法使用 systemd 安装

$ dockerd-rootless-setuptool.sh install
[INFO] systemd not detected, dockerd-rootless.sh needs to be started manually:
...

rootlesskit 如果您通过 sudo su 切换到用户,将无法正确检测 systemd。对于无法登录的用户,您必须使用 machinectl 命令,该命令是 systemd-container 包的一部分。安装 systemd-container 后,使用以下命令切换到 myuser:

$ sudo machinectl shell myuser@

其中 myuser@ 是您希望使用的用户名,@ 表示这台机器。

启动 Docker 守护进程时出错

[rootlesskit:parent] 错误:无法启动子进程:fork/exec /proc/self/exe: 操作不被允许

此错误通常发生在将 /proc/sys/kernel/unprivileged_userns_clone 的值设置为 0 时:

$ cat /proc/sys/kernel/unprivileged_userns_clone
0

要解决此问题,请将 kernel.unprivileged_userns_clone=1 添加到 /etc/sysctl.conf(或 /etc/sysctl.d)并运行 sudo sysctl --system。

[rootlesskit:parent] 错误:无法启动子进程:fork/exec /proc/self/exe:设备上没有剩余空间

此错误通常发生在 /proc/sys/user/max_user_namespaces 的值过小时:

$ cat /proc/sys/user/max_user_namespaces
0

要解决此问题,请将 user.max_user_namespaces=28633 添加到 /etc/sysctl.conf(或 /etc/sysctl.d)并运行 sudo sysctl --system。

[rootlesskit:parent] 错误:未能设置 UID/GID 映射:未能计算 uid/gid 映射:未找到用户 1001 ("testuser") 的子 UID 范围

当未配置 /etc/subuid 和 /etc/subgid 时,会发生此错误。请参阅 先决条件。

无法获取 XDG_RUNTIME_DIR

当未设置 $XDG_RUNTIME_DIR 时会出现此错误。

在非 systemd 主机上,您需要创建一个目录,然后设置路径:

$ export XDG_RUNTIME_DIR=$HOME/.docker/xrd
$ rm -rf $XDG_RUNTIME_DIR
$ mkdir -p $XDG_RUNTIME_DIR
$ dockerd-rootless.sh

注意

每次注销时必须删除该目录。

在 systemd 主机上,使用 pam_systemd 登录主机(见下文)。 该值会自动设置为 /run/user/$UID 并在每次注销时清理。

systemctl --user 失败,提示 "无法连接到总线:没有那个文件或目录"

此错误通常发生在您使用 sudo 从根用户切换到非根用户时:

# sudo -iu testuser
$ systemctl --user start docker
Failed to connect to bus: No such file or directory

您需要使用 pam_systemd 登录,而不是 sudo -iu <USERNAME>。例如:

  • 通过图形控制台登录
  • ssh <USERNAME>@localhost
  • machinectl shell <USERNAME>@

守护进程不会自动启动

您需要 sudo loginctl enable-linger $(whoami) 来启用守护进程自动 启动。请参阅 使用方法。

iptables 失败:iptables -t nat -N DOCKER: 致命错误:无法打开锁文件 /run/xtables.lock: 权限被拒绝

当主机上启用 SELinux 时,旧版本的 Docker 可能会出现此错误。

该问题已在 Docker 20.10.8 中修复。 对于旧版本的 Docker,一个已知的解决方法是运行以下命令以禁用 iptables 的 SELinux:

$ sudo dnf install -y policycoreutils-python-utils && sudo semanage permissive -a iptables_t

docker pull 错误

docker: 无法注册层: 处理 tar 文件时出错(退出状态 1): lchown <FILE>: 无效参数

当 /etc/subuid 或 /etc/subgid 中可用条目的数量不足时,会出现此错误。不同镜像所需的条目数量各不相同。然而,对于大多数镜像来说,65,536 个条目是足够的。请参阅 先决条件。

docker: 无法注册层: ApplyLayer 退出状态 1 stdout: stderr: lchown <文件>: 操作不被允许

此错误主要发生在 ~/.local/share/docker 位于 NFS 上时。

A workaround is to specify non-NFS data-root directory in ~/.config/docker/daemon.json as follows:

{"data-root":"/somewhere-out-of-nfs"}

docker run 错误

docker: 守护进程错误响应:OCI 运行时创建失败:...:读取 unix @->/run/systemd/private:读取:连接被对端重置:未知。

此错误主要发生在 cgroup v2 主机上,通常是因为用户的 dbus 守护进程未运行。

$ systemctl --user is-active dbus
inactive

$ docker run hello-world
docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: process_linux.go:385: applying cgroup configuration for process caused: error while starting unit "docker
-931c15729b5a968ce803784d04c7421f791d87e5ca1891f34387bb9f694c488e.scope" with properties [{Name:Description Value:"libcontainer container 931c15729b5a968ce803784d04c7421f791d87e5ca1891f34387bb9f694c488e"} {Name:Slice Value:"use
r.slice"} {Name:PIDs Value:@au [4529]} {Name:Delegate Value:true} {Name:MemoryAccounting Value:true} {Name:CPUAccounting Value:true} {Name:IOAccounting Value:true} {Name:TasksAccounting Value:true} {Name:DefaultDependencies Val
ue:false}]: read unix @->/run/systemd/private: read: connection reset by peer: unknown.

要修复此问题,请运行 sudo apt-get install -y dbus-user-session 或 sudo dnf install -y dbus-daemon,然后重新登录。

如果错误仍然存在,请尝试运行 systemctl --user enable --now dbus(不使用 sudo)。

--cpus, --memory, 和 --pids-limit 被忽略

这是 cgroup v1 模式下的预期行为。 要使用这些标志,需要配置主机以启用 cgroup v2。 有关更多信息,请参阅 限制资源。

网络错误

本节提供无根模式下网络问题的故障排除提示。

无根模式下的网络支持通过 RootlessKit 中的网络和端口驱动程序实现。网络性能和特性取决于您使用的网络和端口驱动程序的组合。如果您遇到与网络相关的意外行为或性能问题,请查看下表,该表显示了 RootlessKit 支持的配置以及它们的比较:

网络驱动端口驱动程序网络吞吐量端口吞吐量源 IP 传播无 SUID注意
slirp4netnsbuiltin慢快速 ✅❌✅默认在典型设置中
vpnkitbuiltin慢快速 ✅❌✅默认情况下,当未安装 slirp4netns 时
slirp4netnsslirp4netns慢慢✅✅
pastaimplicit慢快速 ✅✅✅实验性功能;需要 2023_12_04 或更高版本的 pasta
lxc-user-nicbuiltin快速 ✅快速 ✅❌❌实验性
bypass4netnsbypass4netns快速 ✅快速 ✅✅✅注意: 未集成到 RootlessKit,因为它需要自定义 seccomp 配置文件

有关排查特定网络问题的信息,请参阅:

docker run -p 失败,返回 cannot expose privileged port

docker run -p 在将特权端口(< 1024)指定为主机端口时,会因此错误而失败。

$ docker run -p 80:80 nginx:alpine
docker: Error response from daemon: driver failed programming external connectivity on endpoint focused_swanson (9e2e139a9d8fc92b37c36edfa6214a6e986fa2028c0cc359812f685173fa6df7): Error starting userland proxy: error while calling PortManager.AddPort(): cannot expose privileged port 80, you might need to add "net.ipv4.ip_unprivileged_port_start=0" (currently 1024) to /etc/sysctl.conf, or set CAP_NET_BIND_SERVICE on rootlesskit binary, or choose a larger port number (>= 1024): listen tcp 0.0.0.0:80: bind: permission denied.

当您遇到此错误时,请考虑改用非特权端口。例如,使用 8080 而不是 80。

$ docker run -p 8080:80 nginx:alpine

要允许暴露特权端口,请参阅 暴露特权端口。

Ping 不起作用

当 /proc/sys/net/ipv4/ping_group_range 设置为 1 0 时,Ping 无法工作:

$ cat /proc/sys/net/ipv4/ping_group_range
1       0

详细信息,请参阅 路由 ping 数据包。

IPAddress 显示在 docker inspect 中不可达

这是一个预期的行为,因为守护进程在 RootlessKit 的网络命名空间内被命名空间隔离。请使用 docker run -p 代替。

--net=host 不在主机网络命名空间上监听端口

这是一个预期的行为,因为守护进程在 RootlessKit 的网络命名空间内被命名空间隔离。请使用 docker run -p 代替。

网络速度慢

Docker 在无根模式下使用 slirp4netns 作为默认网络堆栈,前提是安装了 slirp4netns v0.4.0 或更高版本。 如果未安装 slirp4netns,Docker 将回退到 VPNKit。 安装 slirp4netns 可能会提高网络吞吐量。

有关 RootlessKit 网络驱动程序的更多信息,请参阅 RootlessKit 文档。

此外,更改 MTU 值可能会提高吞吐量。 可以通过创建包含以下内容的 ~/.config/systemd/user/docker.service.d/override.conf 来指定 MTU 值:

[Service]
Environment="DOCKERD_ROOTLESS_ROOTLESSKIT_MTU=<INTEGER>"

然后重启守护进程:

$ systemctl --user daemon-reload
$ systemctl --user restart docker

docker run -p 不传播源 IP 地址

这是因为 Docker 在无根模式下默认使用 RootlessKit 的 builtin 端口驱动程序,该驱动程序不支持源 IP 传播。要启用源 IP 传播,您可以:

  • 使用 slirp4netns RootlessKit 端口驱动程序
  • 使用 pasta RootlessKit 网络驱动程序,配合 implicit 端口驱动程序

The pasta 网络驱动是实验性的,但与 slirp4netns 端口驱动相比,提供了更好的吞吐性能。pasta 驱动需要 Docker Engine 版本 25.0 或更高版本。

要更改 RootlessKit 网络配置:

  1. 在 ~/.config/systemd/user/docker.service.d/override.conf 处创建一个文件。

  2. 根据您希望使用的配置,添加以下内容:

    • slirp4netns

      [Service]
      Environment="DOCKERD_ROOTLESS_ROOTLESSKIT_NET=slirp4netns"
      Environment="DOCKERD_ROOTLESS_ROOTLESSKIT_PORT_DRIVER=slirp4netns"
    • pasta 网络驱动程序,带有 implicit 端口驱动程序

      [Service]
      Environment="DOCKERD_ROOTLESS_ROOTLESSKIT_NET=pasta"
      Environment="DOCKERD_ROOTLESS_ROOTLESSKIT_PORT_DRIVER=implicit"
  3. 重启守护进程:

    $ systemctl --user daemon-reload
    $ systemctl --user restart docker
    

有关 RootlessKit 网络选项的更多信息,请参阅:

调试技巧

进入 dockerd 命名空间

The dockerd-rootless.sh 脚本在其自己的用户、挂载和网络命名空间中执行 dockerd。

为了调试,您可以通过运行 nsenter -U --preserve-credentials -n -m -t $(cat $XDG_RUNTIME_DIR/docker.pid) 进入命名空间。