适用于 Docker Desktop for Linux 的常见问题解答
为什么 Docker Desktop for Linux 会运行虚拟机?
Docker Desktop for Linux 运行虚拟机 (VM) 的原因如下
确保 Docker Desktop 在不同平台上提供一致的体验。
在研究过程中,用户想要使用 Docker Desktop for Linux 的最常见原因是确保在所有主要操作系统上实现功能一致的 Docker Desktop 体验。利用虚拟机可以确保 Linux 用户的 Docker Desktop 体验与 Windows 和 macOS 用户的体验相一致。
利用新的内核功能。
有时我们希望利用新的操作系统功能。由于我们控制着虚拟机内部的内核和操作系统,因此可以立即将这些功能推广到所有用户,即使是那些有意坚持使用机器操作系统 LTS 版本的用户。
增强安全性。
容器镜像漏洞对主机环境构成了安全风险。存在大量的非官方镜像,这些镜像无法保证经过验证以识别已知漏洞。恶意用户可以将镜像推送到公共注册表,并使用不同的方法诱骗用户拉取和运行这些镜像。虚拟机方法可以缓解这种威胁,因为任何获得 root 权限的恶意软件都将被限制在虚拟机环境中,无法访问主机。
为什么不运行无根 Docker?虽然这样做可以暂时限制对 root 用户的访问,因此在“top”中一切看起来都更安全,但它允许非特权用户在自己的用户命名空间中获得 `CAP_SYS_ADMIN` 并访问未预期由非特权用户使用的内核 API,从而导致 漏洞.
为了在尽可能减少性能影响的情况下获得功能一致性和增强的安全性。
Docker Desktop for Linux 使用的虚拟机使用 `VirtioFS`,这是一个共享文件系统,允许虚拟机访问主机上的目录树。我们的内部基准测试表明,通过正确地向虚拟机分配资源,可以使用 VirtioFS 达到接近本机的文件系统性能。
因此,我们调整了 Docker Desktop for Linux 中分配给虚拟机的默认内存。您可以使用 Docker Desktop 的“设置”>“资源”选项卡中的“内存”滑块根据您的具体需求调整此设置。
如何启用文件共享?
Docker Desktop for Linux 使用 VirtioFS 作为默认机制(目前也是唯一机制)来启用主机和 Docker Desktop 虚拟机之间的文件共享。为了不需要提升权限,也不必不必要地限制对共享文件的操作,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) | 运行 DD 的用户 ID(例如 1000) |
1 | 0 + ` /etc/subuid ` / ` /etc/subgid ` 中指定的 ID 范围的开始位置(例如 100000) |
2 | 1 + ` /etc/subuid ` / ` /etc/subgid ` 中指定的 ID 范围的开始位置(例如 100001) |
3 | 2 + ` /etc/subuid ` / ` /etc/subgid ` 中指定的 ID 范围的开始位置(例如 100002) |
... | ... |
如果 ` /etc/subuid ` 和 ` /etc/subgid ` 不存在,则需要创建它们。两者都应包含以下形式的条目 - ` <username>:<start of id range>:<id range size> `。例如,要允许当前用户使用从 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 容器中将共享文件 ` chown ` 为由 UID 为 1000 的用户拥有,则它在主机上显示为由 UID 为 100999 的用户拥有。这会导致一个不幸的副作用,即阻止在主机上轻松访问此类文件。可以通过创建一个使用新 GID 的组并将我们的用户添加到该组来解决此问题,或者通过为与 Docker Desktop 虚拟机共享的文件夹设置递归 ACL(请参见 ` setfacl(1) ` )。
Docker Desktop 在哪里存储 Linux 容器?
Docker Desktop 在 Linux 文件系统中的一个大型“磁盘映像”文件中存储 Linux 容器和镜像。这与 Linux 上的 Docker 不同,后者通常将容器和镜像存储在主机文件系统上的 ` /var/lib/docker ` 目录中。
磁盘映像文件在哪里?
要找到磁盘映像文件,请从 Docker 仪表板中选择“设置”,然后从“资源”选项卡中选择“高级”。
“高级”选项卡会显示磁盘映像的位置。它还会显示磁盘映像的最大大小和磁盘映像实际占用的空间。请注意,其他工具可能会根据最大文件大小而不是实际文件大小来显示文件的空间使用情况。
如果文件太大怎么办?
如果磁盘映像文件太大,您可以
- 将其移动到更大的驱动器
- 删除不必要的容器和镜像
- 减小文件的最大允许大小
如何将文件移动到更大的驱动器?
要将磁盘映像文件移动到其他位置
选择“设置”,然后从“资源”选项卡中选择“高级”。
在“磁盘映像位置”部分中,选择“浏览”并选择磁盘映像的新位置。
选择“应用并重启”以使更改生效。
不要直接在 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 仪表盘中选择 **设置**,然后从 **资源** 选项卡中选择 **高级**。
**磁盘镜像大小** 部分包含一个滑块,允许您更改磁盘镜像的最大大小。调整滑块以设置较低的限制。
选择 **应用并重启**。
当您减小最大大小时,当前的磁盘镜像文件将被删除,因此所有容器和镜像都将丢失。