解決 Docker 權限被拒絕的問題

每天使用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引擎正在運行,顯示active (running)。

Displaying Docker Engine status

如果Docker引擎未啟動,請運行下面的systemctl命令來啟動Docker引擎(start docker)。

sudo systemctl start docker

現在,執行 hello-world Docker 指令,就像您在“執行提升權限的 Docker 指令”部分中所做的那樣,以驗證錯誤是否已解決。

sudo docker run hello-world

將使用者帳戶添加到具有非根使用者訪問權限的群組

您已經確認 Docker 引擎正在運行,但仍然收到 Docker 權限被拒絕的錯誤?如果是這樣,您需要將您的使用者帳戶添加到具有非根使用者訪問權限的群組中。為什麼?因為您在 Linux 機器上運行的任何 Docker 指令,如果不在使用者組中,就會觸發 權限被拒絕的錯誤。

  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 群組。

每次要以非根使用者身份運行 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 命令以特權模式運行 Docker 容器(--privileged hello-world)。

sudo docker run --privileged hello-world

結論

通過本教程,您已經學會了許多解決 Docker 權限被拒絕 錯誤的方法,從運行提升權限的命令到在特權模式下運行 Docker。

現在您知道了在構建基於 Docker 的 應用 時如何擺脫錯誤;也許您還想始終保持 Docker 映像清潔?

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