无根模式

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

无根模式不需要root权限,即使在安装Docker守护程序期间,只要满足先决条件即可。

工作原理

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

无根模式不使用带有SETUID位的二进制文件或文件能力, 除了newuidmapnewgidmap,这些是允许在用户命名空间中使用多个UID/GID所必需的。

先决条件

  • 你必须在主机上安装newuidmapnewgidmap。这些命令在大多数发行版中由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包安装docker-ce-rootless-extrasapt-get install docker-ce-rootless-extras),那么rootlesskit的AppArmor配置文件已经与apparmor deb包捆绑在一起。使用这种安装方法,您不需要手动添加任何AppArmor配置。如果您使用安装脚本安装rootless extras,则必须手动为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上不需要此步骤。

  • 无根 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 v2和systemd运行时支持Cgroup。请参阅 限制资源
  • 以下功能不受支持:
    • AppArmor
    • 检查点
    • 覆盖网络
    • 暴露SCTP端口
  • 要使用ping命令,请参阅 路由ping数据包
  • 要暴露特权TCP/UDP端口(< 1024),请参阅 暴露特权端口
  • IPAddressdocker inspect 中显示的 IP 地址位于 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参数。目前没有已知的问题,但直到你关闭并禁用之前,你仍然在运行rootful Docker。


如果您使用RPM/DEB包安装了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-getdnf这样的包管理器, 考虑使用在 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

二进制文件将安装在 ~/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

要删除二进制文件,如果您是通过包管理器安装的Docker,请删除docker-ce-rootless-extras包。 如果您是通过 https://get.docker.com/rootless ( 无包安装), 请删除~/bin目录下的二进制文件:

$ 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服务和linger:

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

不支持将Rootless Docker作为系统范围的systemd服务(/etc/systemd/system/docker.service)启动,即使使用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:-dind-rootless 镜像,而不是 docker:-dind

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

docker:-dind-rootless 镜像以非 root 用户(UID 1000)运行。 然而,禁用 seccomp、AppArmor 和挂载掩码需要 --privileged

通过TCP暴露Docker API套接字

要通过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 二进制文件上设置 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相关的docker run标志(如--cpus--memory--pids-limit)限制资源仅在运行cgroup v2和systemd时支持。 请参阅 更改cgroup版本以启用cgroup v2。

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

如果 docker info 显示 systemd 作为 Cgroup Driver,则条件满足。 然而,通常情况下,默认情况下只有 memorypids 控制器被委托给非 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不可用,您仍然可以使用传统的ulimitcpulimit, 尽管它们以进程粒度而不是容器粒度工作, 并且可以被容器进程任意禁用。

例如:

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

  • 将最大虚拟内存大小限制为64MiB(类似于docker run --memory 64m): docker run sh -c "ulimit -v 65536; "

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

故障排除

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

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

rootlesskit 如果通过 sudo su 切换到用户,则无法正确检测 systemd。对于无法登录的用户,必须使用 systemd-container 包中的 machinectl 命令。安装 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从root用户切换到非root用户时:

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

而不是使用sudo -iu ,你需要使用pam_systemd登录。例如:

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

守护进程不会自动启动

你需要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 : 无效的参数

/etc/subuid/etc/subgid中的可用条目数量不足时,会发生此错误。所需的条目数量因镜像而异。然而,65,536个条目对于大多数镜像来说已经足够。请参阅先决条件

docker: 注册层失败: ApplyLayer 退出状态 1 标准输出: 标准错误: lchown : 操作不允许

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

一个解决方法是,在~/.config/docker/daemon.json中指定非NFS的data-root目录,如下所示:

{"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-sessionsudo dnf install -y dbus-daemon,然后重新登录。

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

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

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

网络错误

本节提供了在无根模式下进行网络故障排除的提示。

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

Network driverPort driverNet throughputPort throughputSource IP propagationNo SUIDNote
slirp4netnsbuiltinSlowFast ✅Default in a typical setup
vpnkitbuiltinSlowFast ✅Default when slirp4netns isn't installed
slirp4netnsslirp4netnsSlowSlow
pastaimplicitSlowFast ✅Experimental; Needs pasta version 2023_12_04 or later
lxc-user-nicbuiltinFast ✅Fast ✅Experimental
bypass4netnsbypass4netnsFast ✅Fast ✅Note: Not integrated to RootlessKit as it needs a custom seccomp profile

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

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数据包

IPAddressdocker 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 端口驱动

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命名空间

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

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