了解 Mac 上 Docker Desktop 的权限要求
本页包含有关在 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
. - 确保
localhost
和kubernetes.docker.internal
定义在/etc/hosts
.一些旧的 macOS 安装没有localhost
在/etc/hosts
,这会导致 Docker 失败。定义 DNS 名称kubernetes.docker.internal
允许 Docker 与容器共享 Kubernetes 上下文。 - 安全地缓存对开发人员只读的 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 之前的版本需要root
在第一次运行时授予访问权限。首次启动 Docker Desktop 时,您会收到管理员提示,要求您授予安装com.docker.vmnetd
特权帮助程序服务。对于后续运行,root
权限不是必需的。遵循最小权限原则,此方法允许root
访问权限仅用于绝对必要的作,同时仍能够以非特权用户身份使用 Docker Desktop。
所有特权作都使用特权帮助程序进程运行com.docker.vmnetd
.
安装符号链接
默认情况下,Docker Binaries安装在/Applications/Docker.app/Contents/Resources/bin
.Docker Desktop 为/usr/local/bin
,这意味着它们会自动包含在PATH
在大多数系统上。
在 4.18 及更高版本中,您可以选择是否在/usr/local/bin
或$HOME/.docker/bin
在安装 Docker Desktop 期间。
如果/usr/local/bin
,并且此位置不能由非特权用户写入,则 Docker Desktop 需要授权才能确认此选择,然后才能创建指向 Docker Binaries的符号链接/usr/local/bin
.如果$HOME/.docker/bin
,则不需要授权,但您必须手动添加$HOME/.docker/bin
到他们的 PATH。
您还可以选择启用/var/run/docker.sock
符号链接。创建此符号链接可确保依赖默认 Docker 套接字路径的各种 Docker 客户端无需额外更改即可工作。
由于/var/run
挂载为 tmpfs,其内容在重新启动时被删除,包括指向 Docker 套接字的符号链接。为了确保 Docker 套接字在重启后仍然存在,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 依赖当前上下文来检索套接字路径,当前上下文设置为desktop-linux
在 Docker Desktop 启动时。
对于 4.18 之前的版本,在/usr/local/bin
是 Docker Desktop 在首次启动时执行的特权配置。Docker Desktop 检查符号链接是否存在并执行以下作:
- 在以下情况下创建符号链接,而不使用管理员提示
/usr/local/bin
可由非特权用户写入。 - 触发管理员提示,要求您授权在 中创建符号链接
/usr/local/bin
.如果您授权此作,则会在/usr/local/bin
.如果您拒绝提示,不愿意运行需要提升权限的配置,或者在计算机上没有管理员权限,Docker Desktop 会在~/.docker/bin
并编辑您的 shell 配置文件以确保此位置在您的 PATH 中。这需要重新加载所有打开的 shell。 将记录拒绝以供将来运行,以避免再次提示。 如果无法确保Binaries位于 PATH 上,您可能需要手动将/Applications/Docker.app/Contents/Resources/bin
或使用 Docker Binaries的完整路径。
一个特殊情况是安装/var/run/docker.sock
符号链接。创建此符号链接可确保依赖默认 Docker 套接字路径的各种 Docker 客户端无需额外更改即可工作。由于/var/run
挂载为 tmpfs,其内容在重新启动时被删除,包括指向 Docker 套接字的符号链接。
为了确保 Docker 套接字在重启后仍然存在,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 依赖当前上下文来检索套接字路径,当前上下文设置为desktop-linux
在 Docker Desktop 启动时。
绑定特权端口
对于版本 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
注意
如果您花了太长时间来授权提示启动帮助程序进程,则该命令可能会失败并出现相同的错误,因为它可能会超时。
确保localhost
和kubernetes.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
并提示您执行此作。
从命令行安装
在 Docker Desktop for Mac 版本 4.11 及更高版本中,特权配置在安装过程中使用--user
标志。在这种情况下,系统不会提示您在首次运行 Docker Desktop 时授予 root 权限。具体来说,--user
旗:
- 卸载之前的
com.docker.vmnetd
如果存在 - 设置符号链接
- 确保
localhost
解析为127.0.0.1
此方法的限制在于,Docker Desktop 只能由每台计算机的一个用户帐户运行,即-–user
旗。
特权帮助程序
在需要特权帮助程序的有限情况下,例如绑定特权端口或缓存注册表访问管理策略,特权帮助程序由launchd
并在后台运行,除非如前所述在运行时禁用它。Docker Desktop 后端通过 UNIX 域套接字与特权帮助程序通信/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。这意味着,尽管容器默认以root
,则不会授予root
访问 Mac 主机。Linux 虚拟机
用作安全边界,并限制可从
主机。主机绑定中挂载到 Docker 容器中的任何目录仍
保留其原始权限。
增强的容器隔离
此外,Docker Desktop 还支持增强的容器隔离 模式 (ECI), 仅适用于企业客户,可进一步保护容器,而无需 影响开发人员工作流程。
ECI 会自动运行 Linux 用户命名空间中的所有容器,以便 root 映射到 Docker 中的非特权用户 桌面虚拟机。ECI 使用这种技术和其他高级技术来进一步保护 容器,以便它们进一步 与 Docker 守护程序和 VM 内运行的其他服务隔离。