Docker Desktop for Linux 的常見問題

為什麼 Docker Desktop for Linux 執行一個 VM?

Docker Desktop for Linux 執行虛擬機器 (VM) 的原因如下:

  1. 確保 Docker Desktop 在不同平臺提供一致的體驗。

    在研究中,使用者希望 Docker Desktop for Linux 的最常被提及的原因是確保所有主要作業系統上的 Docker Desktop 體驗具有功能對等性。使用 VM 確保了 Linux 使用者的 Docker Desktop 體驗將與 Windows 和 macOS 使用者的體驗非常接近。

  2. 利用新的核心特性。

    有時我們想利用新的作業系統特性。由於我們控制著 VM 內部的核心和作業系統,我們可以立即將其推廣給所有使用者,甚至包括那些故意堅持使用其機器作業系統的 LTS 版本的使用者。

  3. 增強安全性。

    容器映象漏洞對宿主環境構成安全風險。存在大量未經官方驗證的非官方映象,不能保證其沒有已知漏洞。惡意使用者可以將映象推送到公共登錄檔,並使用不同方法誘騙使用者拉取並執行它們。VM 方法可以緩解此威脅,因為任何獲得 root 許可權的惡意軟體都將限制在 VM 環境中,無法訪問宿主。

    為什麼不執行無根 Docker?雖然這表面上限制了對 root 使用者的訪問,使得一切在“top”中看起來更安全,但它允許非特權使用者在其自己的使用者名稱空間中獲得 CAP_SYS_ADMIN 並訪問不期望由非特權使用者使用的核心 API,從而導致漏洞

  4. 在對效能影響最小的情況下,提供功能對等和增強安全性的好處。

    Docker Desktop for Linux 使用的 VM 使用 VirtioFS,這是一個共享檔案系統,允許虛擬機器訪問位於主機上的目錄樹。我們的內部基準測試顯示,透過為 VM 分配合適的資源,VirtioFS 可以實現接近原生的檔案系統性能。

    因此,我們調整了 Docker Desktop for Linux 中 VM 的預設記憶體。您可以透過使用 Docker Desktop 的 Settings > Resources 選項卡中的 Memory 滑塊,根據您的特定需求調整此設定。

如何啟用檔案共享?

Docker Desktop for Linux 使用 VirtioFS 作為在宿主和 Docker Desktop VM 之間啟用檔案共享的預設(目前也是唯一)機制。

為了不要求提升許可權,同時不無故限制共享檔案的操作,Docker Desktop 在使用者名稱空間(參見 user_namespaces(7))中執行檔案共享服務(virtiofsd),並配置了 UID 和 GID 對映。因此,Docker Desktop 依賴於主機配置為允許當前使用者使用從屬 ID 委託。為此,/etc/subuid(參見 subuid(5))和 /etc/subgid(參見 subgid(5))必須存在。Docker Desktop 僅支援透過檔案配置的從屬 ID 委託。Docker Desktop 將當前使用者 ID 和 GID 對映到容器中的 0。它使用 /etc/subuid/etc/subgid 中與當前使用者對應的第一個條目,為容器中大於 0 的 ID 設定對映。

容器中的 ID主機上的 ID
0 (root)執行 Docker Desktop 的使用者 ID (例如 1000)
10 + /etc/subuid//etc/subgid 中指定的 ID 範圍的開頭 (例如 100000)
21 + /etc/subuid//etc/subgid 中指定的 ID 範圍的開頭 (例如 100001)
32 + /etc/subuid//etc/subgid 中指定的 ID 範圍的開頭 (例如 100002)
......

如果缺少 /etc/subuid/etc/subgid,則需要建立它們。兩者都應包含以下形式的條目 - <username>:<id 範圍的開始>:<id 範圍大小>。例如,要允許當前使用者使用從 100 000 到 165 535 的 ID

$ grep "$USER" /etc/subuid >> /dev/null 2&>1 || (echo "$USER:100000:65536" | sudo tee -a /etc/subuid)
$ grep "$USER" /etc/subgid >> /dev/null 2&>1 || (echo "$USER:100000:65536" | sudo tee -a /etc/subgid)

要驗證配置是否已正確建立,請檢查其內容

$ echo $USER
exampleuser
$ cat /etc/subuid
exampleuser:100000:65536
$ cat /etc/subgid
exampleuser:100000:65536

在這種情況下,如果 Docker Desktop 容器中一個共享檔案被使用者 UID 為 1000 的使用者 chown,它在主機上會顯示為 UID 為 100999 的使用者所有。這有一個不幸的副作用,阻止了在主機上輕鬆訪問此類檔案。透過建立一個具有新 GID 的組並將我們的使用者新增到其中,或者為與 Docker Desktop VM 共享的資料夾設定遞迴 ACL(參見 setfacl(1)),可以解決此問題。

Docker Desktop 將 Linux 容器儲存在哪裡?

Docker Desktop 將 Linux 容器和映象儲存在 Linux 檔案系統中的單個大“磁碟映象”檔案中。這與 Linux 上的 Docker 不同,後者通常將容器和映象儲存在主機檔案系統的 /var/lib/docker 目錄中。

磁碟映象檔案在哪裡?

要找到磁碟映象檔案,請從 Docker Desktop Dashboard 選擇 Settings,然後從 Resources 選項卡中選擇 Advanced

Advanced 選項卡顯示磁碟映象的位置。它還顯示磁碟映象的最大大小以及磁碟映象實際佔用的空間。請注意,其他工具可能會以最大檔案大小而不是實際檔案大小來顯示檔案的空間使用情況。

如果檔案太大怎麼辦?

如果磁碟映象檔案太大,您可以

  • 將其移動到更大的驅動器
  • 刪除不必要的容器和映象
  • 減小檔案的最大允許大小
如何將檔案移動到更大的驅動器?

要將磁碟映象檔案移動到其他位置

  1. 選擇 Settings,然後從 Resources 選項卡中選擇 Advanced

  2. Disk image location 部分,選擇 Browse 併為磁碟映象選擇一個新位置。

  3. 選擇 Apply 以使更改生效。

不要直接在 Finder 中移動檔案,因為這可能導致 Docker Desktop 丟失該檔案。

如何刪除不必要的容器和映象?

檢查您是否有任何不必要的容器和映象。如果您的客戶端和守護程式 API 執行版本 1.25 或更高版本(使用客戶端上的 docker version 命令檢查您的客戶端和守護程式 API 版本),您可以透過執行以下命令檢視詳細的空間使用資訊:

$ docker system df -v

或者,要列出映象,請執行

$ docker image ls

要列出容器,請執行

$ docker container ls -a

如果有很多冗餘物件,請執行以下命令

$ docker system prune

此命令會刪除所有已停止的容器、未使用的網路、懸空映象和構建快取。

根據磁碟映象檔案的格式,可能需要幾分鐘才能在主機上回收空間。

  • 如果檔名為 Docker.raw:主機上的空間應在幾秒鐘內回收。
  • 如果檔名為 Docker.qcow2:空間將在幾分鐘後通過後臺程序釋放。

只有在刪除映象時才會釋放空間。當在執行中的容器中刪除檔案時,空間不會自動釋放。要在任何時候觸發空間回收,請執行以下命令:

$ docker run --privileged --pid=host docker/desktop-reclaim-space

請注意,許多工具報告的是最大檔案大小,而不是實際檔案大小。要從終端查詢主機上檔案的實際大小,請執行

$ cd ~/.docker/desktop/vms/0/data
$ ls -klsh Docker.raw
2333548 -rw-r--r--@ 1 username  staff    64G Dec 13 17:42 Docker.raw

在此示例中,磁碟的實際大小為 2333548 KB,而磁碟的最大大小為 64 GB。

如何減小檔案的最大大小?

要減小磁碟映象檔案的最大大小

  1. 從 Docker Desktop Dashboard 選擇 Settings,然後從 Resources 選項卡中選擇 Advanced

  2. Disk image size 部分包含一個滑塊,允許您更改磁碟映象的最大大小。調整滑塊以設定下限。

  3. 選擇**應用**。

當您減小最大大小時,當前的磁碟映象檔案將被刪除,因此所有容器和映象都將丟失。