rootless 简介
rootless模式允许以非root用户身份运行Docker守护程序和容器,以减轻守护程序和容器运行时中的潜在漏洞。只要满足先决条件,即使在Docker守护程序安装期间,无根模式也不需要root特权。无根模式是Docker Engine v19.03中引入的一项实验功能。无根模式从Docker Engine v20.10的实验中毕业。
无根模式在用户命名空间内执行Docker守护进程和容器。这与userns remap模式非常相似,只是在userns remmap模式下,守护进程本身以root权限运行,而在无根模式下,后台进程和容器都在没有root权限的情况下运行。
Rootless 模式利用 user namespaces 将容器中的 root 用户和 Docker 守护进程(dockerd)用户映射到宿主机的非特权用户范围内。Docker 此前已经提供了 --userns-remap 标志支持了相关能力,提升了容器的安全隔离性。Rootless 模式在此之上,让 Docker 守护进程也运行在重映射的用户名空间中。
参考:https://docs.docker.com/engine/security/rootless/
操作系统: Ubuntu 22.04 LTS
前置条件
创建普通用户
useradd -m -s /bin/bash testuser
为普通用户配置sudo权限
echo 'testuser ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/testuser
chmod 440 /etc/sudoers.d/testuser
切换到普通用户
su - testuser
您必须在主机上安装newuidmap
和newgidmap
。这些命令由大多数发行版的uidmap
软件包提供。
sudo apt-get install -y uidmap
在/etc/suubid
和/etc/subid
中应至少包含用户的65536个从属UID/GID。在下面的示例中,用户testuser有65536个从属UID/GID(231072-296607)。
$ id -u
1001
$ whoami
testuser
$ grep ^$(whoami): /etc/subuid
testuser:231072:65536
$ grep ^$(whoami): /etc/subgid
testuser:231072:65536
特定于发行版的提示,如果未安装,请安装dbus-user-session
软件包。默认情况下启用overlay2
存储驱动程序。
sudo apt-get install -y dbus-user-session
安装docker
首先按照官方正常流程安装docker-ce
sudo apt-get update -y
sudo apt-get install -y ca-certificates curl gnupg lsb-release
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update -y
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
通过运行 hello-world 映像验证 Docker 引擎是否已正确安装。
sudo docker run hello-world
禁用docker服务
sudo systemctl disable --now docker.service docker.socket
配置环境变量
loginctl enable-linger $(whoami)
cat >>$HOME/.bashrc<<'EOF'
export XDG_RUNTIME_DIR=/run/user/$(id -u)
export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock
export PATH=/usr/bin:$PATH
EOF
source $HOME/.bashrc
安装rootless软件包
curl -fsSL https://get.docker.com/rootless | sh
查看docker服务运行状态
testuser@ubuntu:~$ systemctl --user status docker
● docker.service - Docker Application Container Engine (Rootless)
Loaded: loaded (/home/testuser/.config/systemd/user/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2022-12-22 12:00:33 CST; 10h ago
Docs: https://docs.docker.com/go/rootless/
Main PID: 9415 (rootlesskit)
Tasks: 37
Memory: 31.9M
CPU: 18.155s
CGroup: /user.slice/user-1001.slice/user@1001.service/app.slice/docker.service
├─9415 rootlesskit --net=slirp4netns --mtu=65520 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver=builtin --copy-up=/etc --copy-up=/run --propagat>
├─9425 /proc/self/exe --net=slirp4netns --mtu=65520 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver=builtin --copy-up=/etc --copy-up=/run --propa>
├─9442 slirp4netns --mtu 65520 -r 3 --disable-host-loopback --enable-sandbox --enable-seccomp 9425 tap0
├─9450 dockerd
└─9467 containerd --config /run/user/1001/docker/containerd/containerd.toml --log-level info
Dec 22 12:00:34 ubuntu dockerd-rootless.sh[9450]: time="2022-12-22T12:00:34.357595184+08:00" level=warning msg="Unable to find cpu controller"
Dec 22 12:00:34 ubuntu dockerd-rootless.sh[9450]: time="2022-12-22T12:00:34.357656874+08:00" level=warning msg="Unable to find io controller"
Dec 22 12:00:34 ubuntu dockerd-rootless.sh[9450]: time="2022-12-22T12:00:34.357669424+08:00" level=warning msg="Unable to find cpuset controller"
Dec 22 12:00:34 ubuntu dockerd-rootless.sh[9450]: time="2022-12-22T12:00:34.358167646+08:00" level=info msg="Loading containers: start."
Dec 22 12:00:34 ubuntu dockerd-rootless.sh[9450]: time="2022-12-22T12:00:34.363349751+08:00" level=info msg="skipping firewalld management for rootless mode"
Dec 22 12:00:34 ubuntu dockerd-rootless.sh[9450]: time="2022-12-22T12:00:34.453762675+08:00" level=info msg="Default bridge (docker0) is assigned with an IP address 172.17.0.0/16. Daemon option --bip ca>
Dec 22 12:00:34 ubuntu dockerd-rootless.sh[9450]: time="2022-12-22T12:00:34.499494915+08:00" level=info msg="Loading containers: done."
Dec 22 12:00:34 ubuntu dockerd-rootless.sh[9450]: time="2022-12-22T12:00:34.516587473+08:00" level=info msg="Docker daemon" commit=3056208 graphdriver(s)=btrfs version=20.10.21
Dec 22 12:00:34 ubuntu dockerd-rootless.sh[9450]: time="2022-12-22T12:00:34.516853174+08:00" level=info msg="Daemon has completed initialization"
Dec 22 12:00:34 ubuntu dockerd-rootless.sh[9450]: time="2022-12-22T12:00:34.558781032+08:00" level=info msg="API listen on /run/user/1001/docker.sock"
testuser@ubuntu:~$
使用docker运行容器
docker run -d -p 8080:80 nginx
查看容器内的用户id为0
testuser@ubuntu:~$ docker exec -it funny_noyce id -u
0
查看进程用户id为165636
testuser@ubuntu:~$ ps -ef |grep nginx
testuser 69100 69077 0 22:31 ? 00:00:00 nginx: master process nginx -g daemon off;
165636 69148 69100 0 22:31 ? 00:00:00 nginx: worker process
165636 69149 69100 0 22:31 ? 00:00:00 nginx: worker process
testuser 69522 69369 0 22:52 pts/0 00:00:00 grep --color=auto nginx