Featured image of post Linux 非 root 用户使用 Docker

Linux 非 root 用户使用 Docker

- 非 root 用户使用 Docker

背景

Docker 默认安装后,只有 root 用户(或者用 sudo)才能访问 Docker daemon,普通用户直接执行 docker ps 会报错:

1
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock

原因在于 Docker CLI 是通过 unix socket /var/run/docker.sock 和 daemon 通信的,而这个 socket 的属主是 root、属组是 docker,权限是 660,只有 root 和 docker 组的成员能读写。把当前用户加入 docker 组之后,Docker CLI 就能以组权限访问 daemon 了:

docker 组与 docker.sock 的权限关系

可以自己看一下这个 socket 的权限:

1
ls -l /var/run/docker.sock
1
srw-rw---- 1 root docker 0 Nov 24 08:55 /var/run/docker.sock

操作步骤

在终端执行以下命令:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 1. 创建 docker 用户组(安装 Docker 时通常已经创建,提示已存在可以忽略)
sudo groupadd docker

# 2. 将当前用户加入 docker 组
sudo usermod -aG docker $USER

# 3. 让组权限立即生效(不用重新登录)
newgrp docker

# 4. 验证配置是否成功
docker ps

如果第 4 步输出容器列表或者只有表头的空表,没有再报 “permission denied”,就说明配置成功了:

配置前后对比

usermod -aG 里的 -a 一定不能漏。只写 -G 会把用户从其他附加组(比如 sudo)里移除。

可选:如果还是不生效

newgrp docker 只对当前这个终端生效,它会开一个新的 shell 并带上 docker 组。其他已经打开的终端、已经登录的 SSH 会话仍然是旧的组信息。

如果执行 docker ps 仍然提示权限不足,说明 shell 会话没有刷新。可以:

1
2
3
4
5
# 登出再登录,或重新连接 SSH
exit
# 然后重新登录,确认 docker 组已经生效
id -nG
docker ps

id -nG 的输出里有 docker,说明组权限已经生效。

可选:~/.docker 权限报错

如果之前用 sudo 跑过 docker 命令,加组之后可能会看到这样的警告:

1
2
WARNING: Error loading config file: /home/user/.docker/config.json -
stat /home/user/.docker/config.json: permission denied

这是因为 ~/.docker 目录当时是以 root 身份创建的。把它的属主改回来即可:

1
2
sudo chown "$USER":"$USER" "$HOME/.docker" -R
sudo chmod g+rwx "$HOME/.docker" -R

安全提示

把用户加入 docker 组,就等价于赋予了 root 权限:任何能访问 Docker daemon 的人,都能启动一个挂载宿主机根目录的特权容器,在宿主机上执行任意命令。即:你可以为所欲为。

请只对受信任的用户、在自己的开发机上这么配置,不建议在多人共享的服务器上使用。共享服务器上可以考虑 Docker 的 Rootless 模式,让 daemon 本身也以普通用户身份运行。

参考

由 Hugo 强力驱动