了解 Mac 上 Docker Desktop 的权限要求

本页包含有关在 Mac 上运行和安装 Docker Desktop 的权限要求的信息。

它还明确了如何运行容器,而不是在主机上拥有访问权限。rootroot

权限要求

Docker Desktop for Mac 以非特权用户身份运行。但是,Docker Desktop 需要某些功能来执行一组有限的特权配置,例如:

  • 正在安装符号链接/usr/local/bin
  • 绑定小于 1024 的特权端口。所谓的“特权端口”通常不用作安全边界,但是操作系统仍然会阻止非特权进程绑定它们,从而破坏像 .docker run -p 127.0.0.1:80:80 docker/getting-started
  • 确保在 中定义了 localhostkubernetes.docker.internal。一些旧的 macOS 安装没有 in ,这会导致 Docker 失败。定义 DNS 名称允许 Docker 与容器共享 Kubernetes 上下文。/etc/hostslocalhost/etc/hostskubernetes.docker.internal
  • 安全地缓存对开发人员只读的 Registry Access Management 策略。

根据使用的 Docker Desktop for Mac 版本,在安装、首次运行或仅在需要时授予特权访问权限。


从版本 4.18 及更高版本开始,Docker Desktop for Mac 提供了对安装期间启用的功能的更大控制。

Docker Desktop for Mac 首次启动时,它会显示一个安装窗口,您可以在其中选择使用默认设置(适用于大多数开发人员,并要求您授予特权访问权限)或使用高级设置。

如果您在安全要求较高的环境中工作,例如禁止本地管理访问,则可以使用高级设置来消除授予特权访问权限的需要。您可以配置:

  • Docker CLI 工具在系统或用户目录中的位置
  • 默认的 Docker 套接字
  • 特权端口映射

根据您配置的高级设置,您必须输入密码进行确认。

您可以稍后从 Settings (设置) 中的 Advanced (高级) 页面更改这些配置。

适用于 Mac 的 Docker Desktop 版本 4.15 到 4.17 不需要特权进程永久运行。每当配置需要提升的权限时,Docker Desktop 都会提示您有关它需要执行的任务的信息。大多数配置只应用一次,后续运行不再提示特权访问。 Docker Desktop 唯一可以启动特权进程的时间是绑定主机 OS 上默认不允许的特权端口。

Docker Desktop for Mac 4.15 之前的版本需要在首次运行时授予访问权限。首次启动 Docker Desktop 时,您会收到管理员提示,要求您授予安装特权帮助程序服务的权限。对于后续运行,不需要权限。遵循最小权限原则,此方法允许仅将访问权限用于绝对必要的操作,同时仍能够以非特权用户身份使用 Docker Desktop。 所有特权操作都使用特权帮助程序进程运行。rootcom.docker.vmnetdrootrootcom.docker.vmnetd


默认情况下,Docker 二进制文件安装在 中。Docker Desktop 为 中的二进制文件创建符号链接,这意味着它们会自动包含在大多数系统中。/Applications/Docker.app/Contents/Resources/bin/usr/local/binPATH


在版本 4.18 及更高版本中,您可以选择是在安装 Docker Desktop 时还是在安装 Docker Desktop 期间安装符号链接。/usr/local/bin$HOME/.docker/bin

如果选择此选项,并且此位置不能由非特权用户写入,则 Docker Desktop 需要授权以确认此选择,然后才能在 中创建指向 Docker 二进制文件的符号链接。如果选择,则不需要授权,但您必须手动将 $HOME/.docker/bin 添加到其 PATH。/usr/local/bin/usr/local/bin$HOME/.docker/bin

您还可以选择启用符号链接的安装。创建此符号链接可确保依赖默认 Docker 套接字路径的各种 Docker 客户端无需额外更改即可工作。/var/run/docker.sock

由于 是作为 tmpfs 挂载的,因此其内容会在重新启动时删除,包括指向 Docker 套接字的符号链接。为了确保 Docker 套接字在重新启动后仍然存在,Docker Desktop 会设置一个启动任务,该任务通过运行 来创建符号链接。这可确保您在每次启动时都不会提示您创建符号链接。如果在安装时未启用此选项,则不会创建符号链接和启动任务,并且您可能必须在它使用的客户端中显式设置环境变量。Docker CLI 依赖于当前上下文来检索套接字路径,当前上下文设置为 Docker Desktop 启动时。/var/runlaunchdln -s -f /Users/<user>/.docker/run/docker.sock /var/run/docker.sockDOCKER_HOST/Users/<user>/.docker/run/docker.sockdesktop-linux

对于 4.18 之前的版本,安装符号链接是 Docker Desktop 在首次启动时执行的特权配置。Docker Desktop 检查符号链接是否存在并执行以下操作:/usr/local/bin

  • 如果非特权用户可写入,则创建不带管理员提示的符号链接。/usr/local/bin
  • 触发管理员提示,让您授权在 中创建符号链接。如果您授权此操作,则会在 中创建指向 Docker 二进制文件的符号链接。如果您拒绝提示,不愿意运行需要提升权限的配置,或者在计算机上没有管理员权限,Docker Desktop 会在 shell 配置文件中创建符号链接并编辑此位置,以确保此位置在您的 PATH 中。这需要重新加载所有打开的 shell。 将记录拒绝以供将来运行,以避免再次提示。 如果无法确保二进制文件位于 PATH 上,您可能需要手动添加到其 PATH 或使用 Docker 二进制文件的完整路径。/usr/local/bin/usr/local/bin~/.docker/bin/Applications/Docker.app/Contents/Resources/bin

一个特殊情况是安装符号链接。创建此符号链接可确保依赖默认 Docker 套接字路径的各种 Docker 客户端无需额外更改即可工作。由于 挂载为 tmpfs,因此其内容会在重新启动时删除,包括指向 Docker 套接字的符号链接。 为了确保 Docker 套接字在重新启动后仍然存在,Docker Desktop 会设置一个启动任务,该任务通过运行 来创建符号链接。这可确保在每次启动时都不会提示您创建符号链接。如果拒绝提示,则不会创建符号链接和启动任务,并且您可能必须在它使用的客户端中显式设置 to。Docker CLI 依赖于当前上下文来检索套接字路径,当前上下文设置为 Docker Desktop 启动时。/var/run/docker.sock/var/runlaunchdln -s -f /Users/<user>/.docker/run/docker.sock /var/run/docker.sockDOCKER_HOST/Users/<user>/.docker/run/docker.sockdesktop-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 解析为 ,如果使用 Kubernetes,则将其解析为 。127.0.0.1kubernetes.docker.internal127.0.0.1

首次运行时,Docker Desktop 会检查是否解析为 .如果解析失败,它会提示您允许将映射添加到 。同样,安装 Kubernetes 集群时,它会检查 Resolved to 并提示您执行此操作。localhost127.0.0.1/etc/hostskubernetes.docker.internal127.0.0.1


从命令行安装

在适用于 Mac 的 Docker Desktop 版本 4.11 及更高版本中,在安装过程中使用安装命令上的标志应用特权配置。在这种情况下,系统不会提示您在首次运行 Docker Desktop 时授予 root 权限。具体而言,该标志:--user--user

  • 卸载上一个com.docker.vmnetd
  • 设置符号链接
  • 确保 解析为localhost127.0.0.1

此方法的局限性在于,Docker Desktop 只能由每台计算机的一个用户帐户运行,即标志中指定的帐户。-–user

特权帮助程序

在需要特权帮助程序的有限情况下,例如绑定特权端口或缓存注册表访问管理策略,特权帮助程序由特权帮助程序启动并在后台运行,除非如前所述在运行时禁用它。Docker Desktop 后端通过 UNIX domain socket 与特权帮助程序通信。它执行的功能是:launchd/var/run/com.docker.vmnetd.sock

  • 绑定小于 1024 的特权端口。
  • 安全地缓存对开发人员只读的 Registry Access Management 策略。
  • 卸载特权帮助程序。

删除特权帮助程序进程的方式与删除进程的方式相同。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 VM 中以 root 身份运行的容器

借助 Docker Desktop,Docker 守护程序和容器可以在轻量级 Linux 中运行 由 Docker 管理的 VM。这意味着,尽管容器默认以 方式运行,但这不会授予对 Mac 主机的访问权限。Linux 虚拟机 用作安全边界,并限制可从 主机。主机绑定中挂载到 Docker 容器中的任何目录仍 保留其原始权限。rootroot

增强的容器隔离

此外,Docker Desktop 还支持增强的容器隔离 模式 (ECI), 仅适用于企业客户,可进一步保护容器,而无需 影响开发人员工作流程。

ECI 会自动运行 Linux 用户命名空间中的所有容器,以便 root 映射到 Docker 中的非特权用户 桌面虚拟机。ECI 使用这种技术和其他高级技术来进一步保护 容器,以便它们进一步 与 Docker 守护程序和 VM 内运行的其他服务隔离。