非 root 用户可以使用 user_namespaces(7)
执行 containerd。
例如,RootlessKit 可用于设置用户命名空间(以及挂载命名空间和可选的网络命名空间)。更多信息请参阅 RootlessKit 文档。
另请参见 https://rootlesscontaine.rs/ 。
“简易方法”
最简单的方法是使用 containerd/nerdctl 中的 containerd-rootless-setuptool.sh
。
$ containerd-rootless-setuptool.sh install
$ nerdctl run -d --restart=always --name nginx -p 8080:80 nginx:alpine
更多信息请参阅 nerdctl/docs/rootless.md。
“繁琐方法”
守护进程
$ rootlesskit --net=slirp4netns --copy-up=/etc --copy-up=/run \
--state-dir=/run/user/1001/rootlesskit-containerd \
sh -c "rm -f /run/containerd; exec containerd -c config.toml"
--net=slirp4netns --copy-up=/etc
只有在你想取消共享网络命名空间时才需要。
有关网络驱动程序的更多信息,请参阅 RootlessKit documentation 。--copy-up=/DIR
在/DIR
上挂载一个可写的 tmpfs,并在父命名空间的/DIR
下挂载文件的符号链接,这样用户就可以在挂载名称空间中添加/删除/DIR
下的文件。
在典型设置中需要使用--copy-up=/etc
和-copy-up=/run
。
根据 containerd 插件配置的不同,可能还需要添加更多--copy-up
选项。rm -f /run/containerd
会删除父命名空间(如果存在)上 “复制到(copied-up)”/run/containerd
的符号链接,非 root 用户无法访问该链接。
主机上实际的/run/containerd
目录不受影响。- 如果未设置,
--state-dir
将被设置为/tmp
下的一个随机目录。RootlessKit 会将 PID 写入该目录下名为child_pid
的文件。 - 你需要为
config.toml
提供自己的路径配置。
version = 2
root = "/home/penguin/.local/share/containerd"
state = "/run/user/1001/containerd"
[grpc]
address = "/run/user/1001/containerd/containerd.sock"
客户端
客户端程序如 ctr
也需要在守护进程命名空间内执行。
$ nsenter -U --preserve-credentials -m -n -t $(cat /run/user/1001/rootlesskit-containerd/child_pid)
$ export CONTAINERD_ADDRESS=/run/user/1001/containerd/containerd.sock
$ export CONTAINERD_SNAPSHOTTER=native
$ ctr images pull docker.io/library/ubuntu:latest
$ ctr run -t --rm --fifo-dir /tmp/foo-fifo --cgroup "" docker.io/library/ubuntu:latest foo
- 除 Ubuntu 和 Debian 内核外,在内核 5.11 之前,
overlayfs
snapshotter 无法在用户命名空间内工作。
不过,如果运行内核 >= 4.18,可以使用fuse-overlayfs
快照器 代替。 - 启用 cgroup 需要 cgroup v2 和 systemd,例如
ctr run --cgroup "user.slice:foo:bar" --runc-systemd-cgroup ...
。
另请参阅 runc documentation。