適用於 Linux 的 Docker Desktop 常見問題
為什麼適用於 Linux 的 Docker Desktop 會執行 VM?
適用於 Linux 的 Docker Desktop 執行虛擬機器 (VM) 基於以下原因
確保 Docker Desktop 在各平台上提供一致的體驗。
在研究過程中,使用者希望適用於 Linux 的 Docker Desktop 最常被引用的原因是確保 Docker Desktop 在所有主要作業系統上都能提供功能一致的體驗。 使用 VM 可確保 Linux 使用者的 Docker Desktop 體驗與 Windows 和 macOS 的體驗非常相似。
利用新的核心功能。
有時我們想要利用新的作業系統功能。 因為我們控制 VM 內的核心和作業系統,所以我們可以立即將這些功能推出給所有使用者,即使是故意堅持使用其機器作業系統 LTS 版本的使用者。
增強安全性。
容器映像弱點對主機環境構成安全風險。 有大量的非官方映像無法保證已針對已知弱點進行驗證。 惡意使用者可以將映像推送到公共登錄檔,並使用不同的方法誘騙使用者提取並執行它們。 VM 方法可以減輕此威脅,因為任何獲得 root 權限的惡意軟體都僅限於 VM 環境,而無法存取主機。
為什麼不執行無 root Docker? 雖然這具有表面上限制 root 使用者存取權限的優點,因此在「top」中一切看起來都更安全,但它允許非特權使用者在其自己的使用者命名空間中獲得
CAP_SYS_ADMIN
並存取核心 API,而這些 API 並不預期會被非特權使用者使用,從而導致 弱點。在對效能的影響最小情況下,提供功能一致性和增強安全性的優點。
適用於 Linux 的 Docker Desktop 使用的 VM 使用
VirtioFS
,這是一種共用檔案系統,允許虛擬機器存取位於主機上的目錄樹。 我們的內部基準測試顯示,透過為 VM 分配正確的資源,使用 VirtioFS 可以實現近乎原生檔案系統的效能。因此,我們調整了適用於 Linux 的 Docker Desktop 中 VM 可用的預設記憶體。 您可以使用 Docker Desktop 的**設定** > **資源**索引標籤中的**記憶體**滑桿,根據您的特定需求調整此設定。
如何啟用檔案共用?
適用於 Linux 的 Docker Desktop 使用 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) |
1 | `/etc/subuid` / `/etc/subgid` 中指定的 ID 範圍的起始值 + 0(例如 100000) |
2 | `/etc/subuid` / `/etc/subgid` 中指定的 ID 範圍的起始值 + 1(例如 100001) |
3 | `/etc/subuid` / `/etc/subgid` 中指定的 ID 範圍的起始值 + 2(例如 100002) |
... | ... |
如果缺少 `/etc/subuid` 和 `/etc/subgid`,則需要建立它們。兩者都應包含以下格式的項目 - `<使用者名稱>:<ID 範圍起始值>:<ID 範圍大小>`。例如,要允許目前使用者使用從 100000 到 165535 的 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 容器內將共享檔案 `chown` 為 UID 為 1000 的使用者所擁有,則它在主機上顯示為 UID 為 100999 的使用者所擁有。這會產生令人遺憾的副作用,即無法輕鬆存取主機上的此類檔案。解決方法是使用新的 GID 建立一個群組,并将我們的使用者新增到該群組,或者為與 Docker Desktop 虛擬機器共享的資料夾設定遞迴 ACL(請參閱 `setfacl(1)`)。
Docker Desktop 在哪裡儲存 Linux 容器?
Docker Desktop 將 Linux 容器和映像儲存在 Linux 檔案系統中單個大型「磁碟映像」檔案中。這與 Linux 上的 Docker 不同,後者通常將容器和映像儲存在主機檔案系統的 `/var/lib/docker` 目錄中。
磁碟映像檔案在哪裡?
要找到磁碟映像檔案,請從 Docker Desktop 控制面板中選擇「設定」,然後從「資源」索引標籤中選擇「進階」。
「進階」索引標籤會顯示磁碟映像的位置。它還會顯示磁碟映像的最大大小和磁碟映像實際佔用的空間。請注意,其他工具可能會以最大檔案大小而不是實際檔案大小來顯示檔案的空間使用情況。
如果檔案太大怎麼辦?
如果磁碟映像檔案太大,您可以
- 將其移至更大的磁碟機
- 刪除不必要的容器和映像
- 減小檔案的最大允許大小
如何將檔案移至更大的磁碟機?
要將磁碟映像檔案移至其他位置
選擇「設定」,然後從「資源」索引標籤中選擇「進階」。
在「磁碟映像位置」區段中,選擇「瀏覽」並選擇磁碟映像的新位置。
選擇「套用並重新啟動」以使變更生效。
請勿直接在 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。
如何減小檔案的最大大小?
要減小磁碟映像檔案的最大大小
從 Docker Desktop 控制面板中選擇「設定」,然後從「資源」索引標籤中選擇「進階」。
「磁碟映像大小」區段包含一個滑桿,可讓您更改磁碟映像的最大大小。調整滑桿以設定較低限制。
選擇「套用並重新啟動」。
當您減小最大大小時,目前的磁碟映像檔案將被刪除,因此所有容器和映像都將遺失。