解决 Docker 权限被拒问题

运行应用程序时,如果遇到 Docker 权限被拒绝的错误,可能会使日常工作变得像噩梦一样。但别担心,本文将帮助您在短时间内恢复运行。

在本教程中,您将学到许多解决令人生畏的 Docker 权限被拒绝错误消息的方法。

先决条件

本教程包含实际演示。要跟着操作,请确保您已准备好以下内容:

  • 本教程中的演示在 Ubuntu 20.04 上运行,但其他 Linux 发行版也适用。
  • Docker 引擎,教程运行版本为 20.10.8,构建为 3967b7d。

运行提升的 Docker 命令

许多因素可能导致连接到 Docker 时出现权限被拒绝错误。其中一个因素是您可能在运行 Docker 命令时未在前面添加sudo 命令。sudo 命令是在运行命令时赋予您提升的管理权限和安全权限的关键。

下面,您可以看到尝试运行docker命令时出现的可怕的权限被拒绝错误。

Running into a permission denied error

请启动您的终端,并在下面的docker命令前面加上sudo来运行hello-world Docker镜像。由于您正在运行提升权限的命令,您需要输入密码才能继续。

sudo docker run hello-world

您将看到类似下面显示的输出,指示Docker已正确安装。

Running Elevated (sudo) Docker Commands

重新启动Docker引擎

如果运行提升权限的Docker命令未解决权限被拒绝的错误,请验证您的Docker引擎是否正在运行。与运行不带sudo命令的docker命令类似,停止的Docker引擎会触发权限被拒绝的错误。如何修复错误?通过重新启动您的Docker引擎。

运行下面的systemctl命令来确认Docker引擎的状态(status docker),以及它是否正在运行。

sudo systemctl status docker

下面,您可以通过返回的状态显示来判断Docker引擎是否正在运行活跃(运行中)。

Displaying Docker Engine status

如果Docker引擎处于非活跃状态,请运行下面的systemctl命令来启动Docker引擎(start docker)。

sudo systemctl start docker

现在,运行 hello-world Docker 命令,就像在“运行 Elevated Docker Commands”部分中所做的那样,以验证错误是否已解决。

sudo docker run hello-world

向具有非 root 用户访问权限的组添加用户帐户

您已确认 Docker 引擎正在工作,但仍然收到 Docker permission denied 错误?如果是这样,您需要将用户帐户添加到具有非 root 用户访问权限的组中。为什么?因为在不属于用户组的 Linux 机器上运行的任何 Docker 命令都会触发 permission denied 错误。

  1. 运行下面的 groupadd 命令以创建一个名为 docker 的新组。输入密码以继续运行该命令。
sudo groupadd docker

如果用户组中存在 docker 组,则将看到如下输出。

Creating a New Group Named ‘docker’

2. 接下来,运行下面的 usermod 命令,其中 -aG 选项告诉命令将您的用户帐户 (programmer) 添加到 (docker) 组中。此命令使您的用户帐户具有非用户访问权限。

sudo usermod -aG docker programmer

3. 运行下面的 newgrp 命令以将当前的实际组 ID 更改为 docker 组。

每当您要以非 root 用户身份运行 Docker 时,请运行此命令。

sudo newgrp docker 

最后,重新运行 hello-world Docker 镜像以确认您不再看到错误。如果在此时仍然出现错误,则考虑给予更多权限访问 docker.sock 文件docker.sock 文件是 UNIX 套接字,是用户与系统之间通信进程信息的一种方式,Docker 守护进程将其作为 Docker API 的入口监听。

运行下面的 chmod 命令以授予所有用户对 /var/run/docker.sock 文件的读写权限(666)。现在再次运行 hello-world Docker 镜像,查看是否已解决错误。

sudo chmod 666 /var/run/docker.sock

编辑 Docker 服务单元文件

如果将 Docker 作为非根用户运行仍无法解决错误,则尝试编辑 Docker SystemD,一个服务控制系统,服务单元文件。 Docker 服务文件包含可能改变 Docker 守护程序行为的敏感参数。您可以通过添加额外命令来修改 Docker 单元文件的默认行为以改变服务的默认行为。

1. 运行以下命令以在您喜欢的文本编辑器中打开 Docker 服务单元文件。例如,此示例中,Docker 服务文件将在 nano 文本编辑器中打开。

sudo nano /usr/lib/systemd/system/docker.service

2. 在 Docker 服务单元文件中找到带有 [Service] 标题的区域,如下所示。复制/粘贴下面的命令到 Docker 服务单元文件中并保存更改。

下面,SupplementaryGroups 命令设置附加的 Unix 组到进程执行的位置。同时,ExecStartPost 命令清理即使服务启动失败也执行的操作。

SupplementaryGroups=docker    
ExecStartPost=/bin/chmod 666 /var/run/docker.sock
Editing the Docker Service Unit File

3. 现在,运行下面的命令来重新启动并启用 Docker 服务。这样做可以使您重新启动 Docker 服务,以避免在运行 Docker 命令时出现错误。

# 重新加载所有 Docker 单元文件并重新创建整个依赖树。
sudo systemctl daemon-reload
# 重新启动 Docker 服务
sudo systemctl start docker
# 启用 Docker 在您的计算机上运行。
sudo systemctl enable docker

4. 最后,重新运行 hello-world Docker 镜像,看看是否仍然出现权限被拒绝的错误。

以特权模式运行 Docker

最后但同样重要的是,在修复 Docker 权限被拒绝错误的列表中是以特权模式运行 Docker。这样做将使 Docker 容器获得系统的根访问权限。

以特权模式运行 Docker 是有风险的,容易受到黑客攻击。因此,请谨慎行事,只有在完全了解自己在做什么时才以特权模式运行 Docker。

1. 运行以下命令列出系统中的所有 Docker 容器,并获取要运行的容器的 ID。

sudo docker ls -a
Listing all Docker Containers in the System

2. 接下来,运行下面的 docker inspect 命令,检查要运行的容器是否已处于特权模式(--format='{{.HostConfig.Privileged}}')。请将下面的 CONTAINER_ID 替换为在第一步中记录的实际容器 ID。

docker inspect --format='{{.HostConfig.Privileged}}' CONTAINER_ID

如果容器处于特权模式,则命令将在控制台返回一个true值。但如果命令返回一个 false 值,如下所示,请继续下一步。

Checking if a Container is in Privileged Mode

3. 最后,运行以下 docker 命令以特权模式--privileged运行 Docker 容器(docker run hello-world)。

sudo docker run --privileged hello-world

结论

通过本教程,您学会了解决 Docker permission denied 错误的多种方法,从运行提升的命令到以特权模式运行 Docker。

现在您知道了在构建基于 Docker 的应用程序时消除错误的方法;也许您还想始终保持 Docker 镜像的清洁状态?

Source:
https://adamtheautomator.com/docker-permission-denied/