为什么 macOS 上的 Docker 比 Linux 上的 Docker 差那么多?
容器与虚拟机
适用于 macOS 的 Docker
开发机制的影响
macOS 选项
总之
几乎所有在 Mac 上使用 Docker 进行开发环境的人都听过这样的笑话:它会让你的 Mac 听起来像喷气式飞机起飞一样。
然而,Linux 上的开发者们却可以轻松🤷🏻♂️进行开发,而不会遇到此类问题。
为什么在 Mac 上运行 Docker 的体验明显不如在 Linux 机器上运行 Docker?本文将探讨其中的原因。
容器与虚拟机
首先,简单介绍一下容器架构以及它与标准虚拟机 (VM) 的区别。
从广义上讲,两者相似之处在于都是在“你的电脑里运行其他电脑”。区别在于实现方式的不同。
(来源:https ://wiki.aquasec.com/display/containers/Docker+Architecture )
容器磁盘更改
如上所示,容器会使用宿主机操作系统及其内核,因此“更接近底层硬件”。例如,容器要从宿主机操作系统的硬盘驱动器读取/写入数据,必须:
- 将磁盘以原生方式挂载到容器上(即,由于内核的存在,容器可以直接访问主机操作系统上的磁盘)。
- 就像直接在主机操作系统上操作一样。
虚拟机磁盘更改
虚拟机在宿主机操作系统之上运行一个额外的操作系统,以及一个额外的抽象层(称为虚拟机管理程序),用于使“客户操作系统”能够与宿主机操作系统通信。例如,虚拟机要从宿主机硬盘读取/写入数据,必须执行以下操作:
- 在客户操作系统上挂载磁盘
- 从主机操作系统在虚拟机管理程序上挂载磁盘
- 让虚拟机管理程序同步两者之间的更改
适用于 macOS 的 Docker
虽然它可能被称为 macOS 版 Docker,但它的架构与 Linux 版 Docker 不同。
(来源:https ://collabnix.com/how-docker-for-mac-works-under-the-hood/ )
如上所示,Docker for macOS 不是直接访问主机操作系统,而是必须启动自己的 Linux 虚拟机。
然后它只能访问该虚拟机的内核,然后该虚拟机必须按照上述步骤同步容器和主机操作系统的磁盘。
虽然 Docker for Linux 基本上可以直接连接到主机操作系统(以及磁盘、网络、GPU 等),但 Docker for macOS 必须经过几个抽象层才能执行底层任务。
开发机制的影响
典型的 Docker 开发环境通常如下所示:
主机操作系统
- 开发者工具(IDE、文本编辑器、代码检查工具等)
- 源代码编辑
- 源控制
容器
- 应用程序代码和依赖项
- 代码更改时需要某种热重载或实时重载机制
- 宿主操作系统源代码的副本或引用
在 macOS 上执行命令时,你看到的喷气式飞机起飞的画面docker-compose up?那是你的主机操作系统资源在努力工作,以同步主机操作系统和容器之间的底层 I/O(特别是磁盘和网络);这还不包括运行容器本身所需的资源。
这也是为什么即使在空闲状态下,Hyperkit 进程通常也会占用大量 CPU 资源的原因。所有这些层之间的同步工作都不是件容易的事!
macOS 选项
很多人会建议你“直接在 Linux 上开发”。虽然 Docker 在 Linux 上的架构确实是其设计初衷(因此体验最佳),但对大多数人来说,简单地切换平台并不现实。
以下选项将使您的体验更接近Linux 系统。至少,喷气式飞机起飞的现象可能只会偶尔发生,而不是一直发生。
Docker for Mac Edge 构建(含 Mutagen)
截至目前,Docker 采用了一种名为Mutagen的底层技术,可以最大限度地减少磁盘更改时的资源消耗。不过,您无需担心具体细节,因为 Docker 已将其打包到 Docker for Mac Edge 版本中。
指示
- 安装适用于 Mac Edge 构建的 Docker
- 在 Docker 用户界面中,转到“资源”=>“文件共享”,然后指定要挂载到 Docker 容器的文件夹。
优点
- 受 Docker 团队“祝福”
- 最小配置——像往常一样使用 docker-compose 和 docker 文件。
- 大幅降低热重载/实时重载时的 CPU 使用率
- 文件更改速度明显加快
缺点
- 仍在解决一些技术难题
- 需要 Docker Edge 构建
docker-sync
另一种已经存在好几年的替代方案是docker-sync。
docker-sync本质上,它是一个与你的容器并行运行的容器,其作用是高效地通知你的容器文件何时发生更改。实际上,它是另一个抽象层,用于加速处理过程。
指示
- 安装docker-sync
- 根据您的开发环境修改 docker-sync.yml 文件
优点
- 可在 Docker 平台上运行
- 大幅降低热重载/实时重载时的 CPU 使用率
- 文件更改速度明显加快
缺点
- 需要进行配置修改
- 由于并行容器增多,消耗了更多 Docker 资源。
- 需要额外的编排来启动和关闭容器
- 偶尔会出现同步问题;例如,容器无法随着主机操作系统更改而更新,需要重启。
总之
Docker 最初是为 Linux 系统设计的。随着其实用性的不断验证,最终也被移植到了 macOS 和 Windows 平台。
由于这两个操作系统底层与 Linux 的机制截然不同,虚拟化是唯一可行的解决方案。然而,这也导致了我们习以为常的底层效率低下问题。
未来 Mutagen 将作为 Docker for Mac 的一部分打包,macOS 开发人员有望看到“喷气式发动机”问题开始减少。
然而,就目前而言,Docker 的最佳开发者体验仍然是其原生 Linux 版本。
文章来源:https://dev.to/ericnograles/why-is-docker-on-macos-so-much-worse-than-linux-flh

