了解 Docker Desktop 在 Mac 上的权限要求
本页面包含有关在 Mac 上运行和安装 Docker Desktop 所需权限要求的信息。
它还阐明了在容器中以 root
身份运行与在主机上拥有 root
访问权限之间的区别。
适用于 Windows 的 Docker Desktop 在设计时考虑了安全性。仅在绝对必要时才需要管理员权限。
权限要求
适用于 Mac 的 Docker Desktop 作为非特权用户运行。但是,Docker Desktop 需要某些功能来执行一组有限的特权配置,例如:
- 在
/usr/local/bin
中安装符号链接。 - 绑定小于 1024 的特权端口。尽管特权端口(小于 1024 的端口)通常不作为安全边界使用,但操作系统仍然阻止非特权进程绑定到它们,这会破坏像
docker run -p 127.0.0.1:80:80 docker/getting-started
这样的命令。 - 在
/etc/hosts
中确保定义了localhost
和kubernetes.docker.internal
。一些旧的 macOS 安装未在/etc/hosts
中包含localhost
,这会导致 Docker 失败。定义 DNS 名称kubernetes.docker.internal
允许 Docker 与容器共享 Kubernetes 上下文。 - 安全地缓存对开发者而言只读的注册表访问管理策略。
在安装期间授予特权访问权限。
首次启动适用于 Mac 的 Docker Desktop 时,会显示一个安装窗口,您可以选择使用适用于大多数开发者并需要授予特权访问权限的默认设置,或使用高级设置。
如果您在安全要求较高的环境工作(例如禁止本地管理员访问),则可以使用高级设置来避免授予特权访问权限。您可以配置:
- Docker CLI 工具的位置,可在系统目录或用户目录中
- 默认的 Docker socket
- 特权端口映射
根据您配置的高级设置,您必须输入密码进行确认。
您以后可以从设置中的高级页面更改这些配置。
安装符号链接
Docker 二进制文件默认安装在 /Applications/Docker.app/Contents/Resources/bin
。Docker Desktop 在 /usr/local/bin
中为二进制文件创建符号链接,这意味着它们在大多数系统上都会自动包含在 PATH
中。
在安装 Docker Desktop 期间,您可以选择将符号链接安装到 /usr/local/bin
或 $HOME/.docker/bin
。
如果选择 /usr/local/bin
且该位置对非特权用户不可写,Docker Desktop 需要授权才能确认此选择,然后在 /usr/local/bin
中创建 Docker 二进制文件的符号链接。如果选择 $HOME/.docker/bin
,则无需授权,但您必须手动将 $HOME/.docker/bin
添加到您的 PATH 中。
您还可以选择启用安装 /var/run/docker.sock
符号链接。创建此符号链接可确保依赖默认 Docker socket 路径的各种 Docker 客户端无需额外更改即可工作。
由于 /var/run
被挂载为 tmpfs,其内容会在重启时被删除,包括指向 Docker socket 的符号链接。为了确保 Docker socket 在重启后存在,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 依赖当前上下文来检索 socket 路径,Docker Desktop 启动时会将当前上下文设置为 desktop-linux
。
绑定特权端口
您可以在安装期间或安装后从设置中的高级页面选择启用特权端口映射。Docker Desktop 需要授权才能确认此选择。
确保定义了 localhost
和 kubernetes.docker.internal
您有责任确保 localhost 解析为 127.0.0.1
,并且如果使用 Kubernetes,确保 kubernetes.docker.internal
解析为 127.0.0.1
。
从命令行安装
特权配置在安装期间通过安装命令上的 --user
标志应用。在这种情况下,您在首次运行 Docker Desktop 时不会被提示授予 root 权限。具体来说,--user
标志会:
- 如果存在,卸载先前的
com.docker.vmnetd
- 设置符号链接
- 确保
localhost
解析为127.0.0.1
这种方法的限制是 Docker Desktop 每台机器只能由一个用户账户运行,即在 -–user
标志中指定的用户。
特权助手
在需要特权助手的有限情况下,例如绑定特权端口或缓存注册表访问管理策略时,特权助手由 launchd
启动并在后台运行,除非在运行时将其禁用(如前所述)。Docker Desktop 后端通过 UNIX 域 socket /var/run/com.docker.vmnetd.sock
与特权助手通信。其执行的功能包括:
- 绑定小于 1024 的特权端口。
- 安全地缓存对开发者而言只读的注册表访问管理策略。
- 卸载特权助手。
删除特权助手进程的方式与删除 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 虚拟机中以 root 身份运行的容器
使用 Docker Desktop 时,Docker daemon 和容器在由 Docker 管理的轻量级 Linux 虚拟机中运行。这意味着虽然容器默认以 root
身份运行,但这并不授予对 Mac 主机机器的 root
访问权限。Linux 虚拟机充当安全边界,并限制可以从主机访问哪些资源。任何从主机绑定挂载到 Docker 容器中的目录仍然保留其原始权限。
增强容器隔离
此外,Docker Desktop 支持增强容器隔离模式 (ECI),该模式仅适用于商业版客户,可在不影响开发者工作流程的情况下进一步保护容器。
ECI 会自动在 Linux 用户命名空间内运行所有容器,这样容器中的 root 会映射到 Docker Desktop VM 内的非特权用户。ECI 利用此技术及其他高级技术进一步保护 Docker Desktop Linux VM 内的容器,使其与 Docker daemon 和 VM 内运行的其他服务进一步隔离。