瞭解 Docker Desktop 在 Mac 上的權限需求

此頁面包含關於在 Mac 上執行和安裝 Docker Desktop 的權限需求資訊。

它還闡明了以 root 身份執行容器與在主機上具有 root 權限的區別。

權限需求

Docker Desktop for Mac 以非特權使用者身份執行。但是,Docker Desktop 需要某些功能來執行一組有限的特權設定,例如

  • /usr/local/bin安裝符號連結
  • 繫結小於 1024 的特殊權限埠。所謂的「特殊權限埠」通常不用作安全邊界,但是作業系統仍然會阻止非特權行程繫結它們,這會破壞 docker run -p 127.0.0.1:80:80 docker/getting-started 等命令。
  • /etc/hosts確保已定義 localhostkubernetes.docker.internal。某些舊的 macOS 安裝在 /etc/hosts 中沒有 localhost,這會導致 Docker 失敗。定義 DNS 名稱 kubernetes.docker.internal 允許 Docker 與容器共用 Kubernetes 環境。
  • 安全地快取 Registry 存取管理策略,該策略對開發人員而言是唯讀的。

根據所使用的 Docker Desktop for Mac 版本,會在安裝期間、首次執行期間或僅在需要時授予特殊權限存取權。


從 4.18 版及更高版本開始,Docker Desktop for Mac 可更好地控制安裝期間啟用的功能。

Docker Desktop for Mac 首次啟動時,會顯示一個安裝視窗,您可以在其中選擇使用預設設定 (適用於大多數開發人員,需要您授予特殊權限存取權) 或使用進階設定。

如果您在安全性要求較高的環境中工作,例如禁止本地管理員存取的環境,則可以使用進階設定來移除授予特殊權限存取權的需求。您可以設定

  • Docker CLI 工具的位置 (在系統或使用者目錄中)
  • 預設 Docker 通訊端
  • 特殊權限埠映射

根據您設定的進階設定,您必須輸入密碼進行確認。

您可以稍後在「設定」的「進階」頁面中變更這些設定。

4.15 至 4.17 版的 Docker Desktop for Mac 不需要永久執行特殊權限行程。每當設定需要提升的權限時,Docker Desktop 都會提示您有關需要執行的任務的資訊。大多數設定只套用一次,後續執行不再提示特殊權限存取權。Docker Desktop 啟動特殊權限行程的唯一時間是繫結主機作業系統預設不允許的特殊權限埠。

4.15 之前的 Docker Desktop for Mac 版本需要在第一次執行時授予 root 權限存取權。Docker Desktop 首次啟動時,您會收到管理員提示,要求授予安裝 com.docker.vmnetd 特殊權限輔助程式服務的權限。後續執行不需要 root 權限。遵循最小權限原則,這種方法允許僅將 root 權限存取權用於絕對必要的作業,同時仍然能夠以非特權使用者身份使用 Docker Desktop。所有特殊權限作業都使用特殊權限輔助程式行程 com.docker.vmnetd 執行。


Docker 二進位檔預設安裝在 /Applications/Docker.app/Contents/Resources/bin 中。Docker Desktop 會在 /usr/local/bin 中建立二進位檔的符號連結,這表示它們會自動包含在大部分系統的 PATH 中。


在 4.18 版及之後的版本中,您可以在安裝 Docker Desktop 時選擇將符號連結安裝在 /usr/local/bin$HOME/.docker/bin

如果選擇 /usr/local/bin,且此位置不允許非特權使用者寫入,則 Docker Desktop 需要授權才能確認此選擇,然後才會在 /usr/local/bin 中建立 Docker 二進制檔案的符號連結。如果選擇 $HOME/.docker/bin,則不需要授權,但您必須手動將 $HOME/.docker/bin 加入您的 PATH 中

您還可以選擇啟用 /var/run/docker.sock 符號連結的安裝。建立此符號連結可確保依賴預設 Docker Socket 路徑的各種 Docker 用戶端都能正常運作,而無需額外變更。

由於 /var/run 被掛載為 tmpfs,因此重新啟動時其內容會被刪除,包括 Docker Socket 的符號連結。為了確保 Docker Socket 在重新啟動後存在,Docker Desktop 會設定一個 launchd 啟動任務,透過執行 ln -s -f /Users/<user>/.docker/run/docker.sock /var/run/docker.sock 來建立符號連結。這可確保您在每次啟動時都不會被提示建立符號連結。如果您在安裝時未啟用此選項,則不會建立符號連結和啟動任務,您可能必須在使用的用戶端中將 DOCKER_HOST 環境變數明確設定為 /Users/<user>/.docker/run/docker.sock。Docker CLI 依賴目前的上下文來擷取 Socket 路徑,目前的上下文在 Docker Desktop 啟動時會設定為 desktop-linux

對於 4.18 之前的版本,在 /usr/local/bin 中安裝符號連結是 Docker Desktop 在第一次啟動時執行的特權設定。Docker Desktop 會檢查符號連結是否存在,並採取以下動作:

  • 如果 /usr/local/bin 可供非特權使用者寫入,則會在沒有管理員提示的情況下建立符號連結。
  • 觸發管理員提示,要求您授權在 /usr/local/bin 中建立符號連結。如果您授權,則會在 /usr/local/bin 中建立 Docker 二進制檔案的符號連結。如果您拒絕提示、不願意執行需要提升權限的設定,或者您的機器上沒有管理員權限,Docker Desktop 會在 ~/.docker/bin 中建立符號連結,並編輯您的 Shell 設定檔,以確保此位置在您的 PATH 中。這需要重新載入所有已開啟的 Shell。系統會記錄拒絕的動作,以避免在將來再次提示您。如果無法確保二進制檔案在您的 PATH 中,您可能需要手動將 /Applications/Docker.app/Contents/Resources/bin 加入您的 PATH 中,或使用 Docker 二進制檔案的完整路徑。

一個特殊情況是 /var/run/docker.sock 符號連結的安裝。建立此符號連結可確保依賴預設 Docker Socket 路徑的各種 Docker 用戶端都能正常運作,而無需額外變更。由於 /var/run 被掛載為 tmpfs,因此重新啟動時其內容會被刪除,包括 Docker Socket 的符號連結。為了確保 Docker Socket 在重新啟動後存在,Docker Desktop 會設定一個 launchd 啟動任務,透過執行 ln -s -f /Users/<user>/.docker/run/docker.sock /var/run/docker.sock 來建立符號連結。這可確保您在每次啟動時都不會被提示建立符號連結。如果您拒絕提示,則不會建立符號連結和啟動任務,您可能必須在使用的用戶端中將 DOCKER_HOST 明確設定為 /Users/<user>/.docker/run/docker.sock。Docker CLI 依賴目前的上下文來擷取 Socket 路徑,目前的上下文在 Docker Desktop 啟動時會設定為 desktop-linux


繫結特殊權限埠


在 4.18 版及之後的版本中,您可以在安裝期間或安裝後在「設定」的「進階」頁面中選擇啟用特權連接埠映射。Docker Desktop 需要授權才能確認此選擇。

對於 4.18 以下的版本,如果您執行的容器需要繫結特權連接埠,Docker Desktop 會先嘗試以非特權程序直接繫結它。如果作業系統阻止此操作且失敗,Docker Desktop 會檢查是否有執行特權輔助程序 com.docker.vmnetd 來透過它繫結特權連接埠。

如果特權輔助程序未執行,Docker Desktop 會提示您授權在 launchd 下執行它。這會將特權輔助程序設定為在 4.15 之前的 Docker Desktop 版本中執行。但是,此特權輔助程序提供的功能現在僅支援連接埠繫結和快取 Registry Access Management 策略。如果您拒絕啟動特權輔助程序,則無法完成特權連接埠的繫結,Docker CLI 將會傳回錯誤。

$ docker run -p 127.0.0.1:80:80 docker/getting-started

docker: Error response from daemon: Ports are not available: exposing port
TCP 127.0.0.1:80 -> 0.0.0.0:0: failed to connect to /var/run/com.docker.vmnetd.sock:
is vmnetd running?: dial unix /var/run/com.docker.vmnetd.sock: connect: connection
refused.
ERRO[0003] error waiting for container: context canceled

**注意**

如果您授權啟動輔助程序的提示時間過長,導致逾時,則該命令可能會失敗並顯示相同的錯誤。


確保已定義 localhostkubernetes.docker.internal


在 4.18 版及之後的版本中,您有責任確保 localhost 解析為 127.0.0.1,如果使用 Kubernetes,則 kubernetes.docker.internal 必須解析為 127.0.0.1

第一次執行時,Docker Desktop 會檢查 localhost 是否解析為 127.0.0.1。如果解析失敗,它會提示您允許將映射新增至 /etc/hosts。同樣地,當安裝 Kubernetes 叢集時,它會檢查 kubernetes.docker.internal 是否解析為 127.0.0.1,並提示您執行此操作。


從命令列安裝

在 Mac 版 Docker Desktop 4.11 及之後的版本中,特權設定會在安裝過程中使用 安裝命令--user 旗標套用。在這種情況下,系統不會在 Docker Desktop 第一次執行時提示您授予 root 權限。具體來說,--user 旗標會執行以下操作:

  • 解除安裝先前的 com.docker.vmnetd(如果有的話)
  • 設定符號連結
  • 確保 localhost 解析為 127.0.0.1

這種方法的限制是,每台機器上只能有一個使用者帳戶執行 Docker Desktop,也就是在 -–user 旗標中指定的帳戶。

特殊權限輔助程式

在需要特權輔助程序的少數情況下,例如繫結特權連接埠或快取 Registry Access Management 策略,特權輔助程序會由 launchd 啟動並在背景執行,除非先前所述在執行時停用它。Docker Desktop 後端透過 UNIX 網域 Socket /var/run/com.docker.vmnetd.sock 與特權輔助程序通訊。它執行的功能如下:

  • 繫結小於 1024 的特權連接埠。
  • 安全地快取 Registry 存取管理策略,該策略對開發人員而言是唯讀的。
  • 解除安裝權限輔助程式。

移除權限輔助程式的步驟與移除 launchd 處理程序相同。

$ ps aux | grep vmnetd
root             28739   0.0  0.0 34859128    228   ??  Ss    6:03PM   0:00.06 /Library/PrivilegedHelperTools/com.docker.vmnetd
user             32222   0.0  0.0 34122828    808 s000  R+   12:55PM   0:00.00 grep vmnetd

$ sudo launchctl unload -w /Library/LaunchDaemons/com.docker.vmnetd.plist
Password:

$ ps aux | grep vmnetd
user             32242   0.0  0.0 34122828    716 s000  R+   12:55PM   0:00.00 grep vmnetd

$ rm /Library/LaunchDaemons/com.docker.vmnetd.plist

$ rm /Library/PrivilegedHelperTools/com.docker.vmnetd

在 Linux 虛擬機器中以 root 身份執行的容器

使用 Docker Desktop 時,Docker Daemon 和容器會在 Docker 管理的輕量級 Linux 虛擬機器中運行。這表示雖然容器預設以 root 身分執行,但这並不會授予 root 存取 Mac 主機的權限。Linux 虛擬機器作為安全邊界,限制可以從主機存取的資源。從主機掛載到 Docker 容器的任何目錄仍保留其原始權限。

增強型容器隔離

此外,Docker Desktop 支援增強型容器隔離模式(ECI),此模式僅適用於企業客戶,可在不影響開發人員工作流程的情況下進一步保護容器。

ECI 會自動在 Linux 使用者命名空間內執行所有容器,以便將容器中的 root 對應到 Docker Desktop 虛擬機器內非特權的使用者。ECI 使用此技術和其他進階技術來進一步保護 Docker Desktop Linux 虛擬機器中的容器,使其與 Docker Daemon 和虛擬機器內執行的其他服務進一步隔離。