Docker rootless 脚本安装
Ubuntu 24.04 上安装 rootless 的 Docker
说明
💧rootless Docker 不适合生产环境
- 性能较差:rootless 模式使用用户态网络(如
slirp4netns),吞吐低、延迟高,严重影响高负载服务性能。 - 功能受限:某些功能如自定义网络驱动、挂载卷、overlay 文件系统等在 rootless 模式下无法使用或不稳定。
- 兼容性问题: 需要系统支持
user namespaces和cgroup v2,在一些老旧或企业发行版上配置复杂、不稳定。 - 运维复杂度高:日志、存储路径不同于标准 Docker,调试和管理不方便,容易混乱。
以下是 rootless Docker 适合使用的场景:
- 本地开发与测试环境:开发者无需 root 权限即可运行容器,降低系统风险,适合个人机器或 CI 流水线中的构建与测试。
- 多用户共享服务器:在一台服务器上多个用户运行容器时,使用 rootless 模式可避免互相干扰,提高隔离性和安全性。
- 受限或受控环境:在不允许获取 root 权限的系统中(如教育环境、托管虚拟机),rootless 模式是容器化运行的可行方式。
- CI/CD 系统中的隔离构建任务:用于构建、打包、测试等任务时,rootless 模式减少对主机系统的侵入,提升安全性。
这些场景下对性能和容器功能要求较低,因此更适合使用 rootless Docker。
准备
# 更新系统和软件包
sudo apt update && sudo apt upgrade -y
# 安装必要依赖
sudo apt install -y uidmap dbus-user-session fuse-overlayfs curl
# 加载 Linux 内核模块 nf_tables,该模块是 nftables 框架的核心组件,用于实现 Linux 防火墙和包过滤系统。
sudo modprobe nf_tables
用户映射文件
配置 /etc/subuid 和 /etc/subgid
为每个用户分配 UID/GID 映射段(确保不重叠)
建议在 login.defs 配置文件中设置如下内容
SUB_UID_MIN 100000
SUB_UID_MAX 600100000
SUB_UID_COUNT 65536
SUB_GID_MIN 100000
SUB_GID_MAX 600100000
SUB_GID_COUNT 65536
Ubuntu24.04 已经默认设置,不需要任何操作。
Ubuntu22.04 需要放开注释,添加上述内容。
创建新用户和用户组
sudo adduser --disabled-password --gecos "" dockeruser1
你可以重复这个命令来创建多个用户,例如 dockeruser2、dockeruser3 等。
adduser:创建新用户的命令(比 useradd 更易用,自动设置更多内容)。
--disabled-password:不为用户设置密码,用户不能使用密码登录系统(但可以通过 SSH 密钥等其他方式登录)。
--gecos "":GECOS 字段用于设置用户的全名、办公室号、电话等信息,这里设置为空字符串,表示不填写这些信息。
dockeruser1:要创建的用户名。
在创建用户之后,adduser 命令会自动分配 UID/GID 映射到 /etc/subuid 和 /etc/subgid,可以通过以下命令确认:
grep dockeruser1 /etc/subuid /etc/subgid
给新用户配置登录密码,或者使用 SSH 公钥方式连接 Linux 服务器
# 配置密码
passwd dockeruser1
后续都在登录 dockeruser1 后操作
AppArmor 配置文件
AppArmor 用于限制 rootless Docker 的权限,提升安全性。
创建并安装当前登录用户的 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
此代码块会生成一个针对您的用户 rootlesskit 可执行文件路径量身定制的 AppArmor 配置文件。
比如 home.dockeruser1.bin.rootlesskit,dockeruser1 是当前的登录用户名
# 这一句需要 sudo 组,可以让 root 用户来操作
sudo mv ~/${filename} /etc/apparmor.d/${filename}
# 比如:sudo mv /home/dockeruser1/home.dockeruser1.bin.rootlesskit /etc/apparmor.d/home.dockeruser1.bin.rootlesskit
重新启动 AppArmor 服务
sudo systemctl restart apparmor.service
脚本安装
配置代理
这里是下载安装包的代理
代理的目的是下载 https://download.docker.com/linux/static/stable/ 里面的文件包
比如
https://download.docker.com/linux/static/stable/x86_64/docker-28.2.1.tgz
https://download.docker.com/linux/static/stable/x86_64/docker-rootless-extras-28.2.1.tgz
国内连 Docker 官网比较慢,可以考虑走代理。
# 这个是环境变量临时使用局域网的代理,(可选)如果网络受限,配置代理以加速下载
export http_proxy="http://192.168.10.40:10808"
export https_proxy="http://192.168.10.40:10808"
使用脚本安装
脚本安装 docker rootless
curl -fsSL https://get.docker.com/rootless | sh
使用脚本离线安装
访问 https://get.docker.com/rootless ,保存为 rootless_install.sh 文件
提前下载安装包,以版本 28.2.1 举例
- docker-28.2.1.tgz
- docker-rootless-extras-28.2.1.tgz
找到以下代码段:
(
cd "$tmp"
curl -L -o docker.tgz "$STATIC_RELEASE_URL"
curl -L -o rootless.tgz "$STATIC_RELEASE_ROOTLESS_URL"
)
将其 替换为:
cp ./docker-28.2.1.tgz "$tmp/docker.tgz"
cp ./docker-rootless-extras-28.2.1.tgz "$tmp/rootless.tgz"
示例修改后的关键部分:
do_install() {
echo "# Executing docker rootless install script, commit: $SCRIPT_COMMIT_SHA"
init_vars
checks
tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' EXIT INT TERM
# 使用本地文件代替在线下载
cp ./docker-28.2.1.tgz "$tmp/docker.tgz"
cp ./docker-rootless-extras-28.2.1.tgz "$tmp/rootless.tgz"
# 解压到 $HOME/bin/
(
mkdir -p "$BIN"
cd "$BIN"
tar zxf "$tmp/docker.tgz" --strip-components=1
tar zxf "$tmp/rootless.tgz" --strip-components=1
)
exec_setuptool "$@"
}
如果你需要让这些 .tgz 来自固定目录(如 /opt/docker/),也可以将 cp 命令改成:
cp /opt/docker/docker-28.2.1.tgz "$tmp/docker.tgz"
cp /opt/docker/docker-rootless-extras-28.2.1.tgz "$tmp/rootless.tgz"
运行安装脚本 rootless_install.sh 文件
bash rootless_install.sh
配置环境变量
# 配置环境变量
cat <<EOF >> "$HOME/.bashrc"
export PATH=$HOME/bin:$PATH
export DOCKER_HOST=unix:///run/user/$UID/docker.sock
EOF
source "$HOME/.bashrc"
配置代理
Docker 镜像拉取的代理
# 创建文件夹
mkdir -p ~/.config/docker
配置镜像地址,请参考:搭建自己的免费 Docker 镜像加速器
tee ~/.config/docker/daemon.json <<EOF
{
"registry-mirrors": ["https://docker.1ms.run"]
}
EOF
重启 Docker
systemctl --user restart docker
管理命令
启动 docker
systemctl --user start docker
设置 docker 开机启动,这样每次你用户的 systemd 启动时(登录或被唤醒时),docker 就会自动启动。
systemctl --user enable docker
查看 docker 状态
systemctl --user status docker
随系统开机启动
让用户服务在系统启动时自动启动
运行以下命令:
loginctl enable-linger dockeruser1
这一步是关键!它告诉系统:即使用户没有登录,也保持该用户的 systemd 用户服务活跃。
可以重复这个命令来让多个用户的 systemd 用户服务开机启动,例如 dockeruser2、dockeruser3 等。
查看已经配置的用户
ls -l /var/lib/systemd/linger/
这个目录中列出的文件名就是启用了 linger 的用户名。
类似显示
dockeruser1@node25:~$ ls -l /var/lib/systemd/linger/
total 0
-rw-r--r-- 1 root root 0 Jun 9 07:31 dockeruser1
取消 linger
loginctl disable-linger dockeruser1
测试
# Hello
docker run --rm -it docker.io/library/alpine echo "Hello, Rootless Docker!"
# 启动一个 Redis 服务,然后退出登录,稍后登录查看服务是否刚刚启动,检查登出时服务是否也停止了
docker run -d \
--name redis5 \
-p 6379:6379 \
--restart unless-stopped \
redis:5
注意对外的端口是不能重复的,比如 dockeruser1 用了端口 6379 ,dockeruser2 是不能再用的。
个人习惯,所有应用放在 app 文件夹下
mkdir ~/app
compose 插件
新版 Docker自带了,不用额外安装
mkdir -p ~/.docker/cli-plugins
curl -SL https://github.com/docker/compose/releases/download/v2.40.3/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose
chmod +x ~/.docker/cli-plugins/docker-compose
注意:v2.40.3 是当前最新版,
你可以前往 GitHub 发布页确认最新版本:https://github.com/docker/compose/releases
验证是否安装成功
docker compose version
如果输出类似如下信息说明安装成功:
Docker Compose version v2.40.3
目录
~/bin 目录下
dockerd-rootless.sh:启动 rootless Docker 守护进程的脚本。dockerd:Docker 守护进程二进制文件。rootlesskit:用户空间工具,用于管理 rootless 容器网络和命名空间。vpnkit:用户空间网络代理,提供网络访问(如果启用了 vpnkit 网络)。docker:Docker CLI 客户端命令。

浙公网安备 33010602011771号