使用 Docker-OSX 在 Linux 中运行 macOS
最初出现在我的博客. 我碰巧在我目前的工作场所Process Street中,我必须修复我们的iOS 应用程序中的一个错误。但是......我想在 Linux 机器上做这个,而不是在 MacBook 上。在这种情况下该怎么办?让我们在虚拟机中运行 macOS! 目录 1.先决条件 *CPU 虚拟化 *RAM,磁盘空间 *码头工人 2.安装Docker-OSX *开始吧! *安装操作系统 3.自定义
最初出现在我的博客.
我碰巧在我目前的工作场所Process Street中,我必须修复我们的iOS 应用程序中的一个错误。但是......我想在 Linux 机器上做这个,而不是在 MacBook 上。在这种情况下该怎么办?让我们在虚拟机中运行 macOS!
目录
1.先决条件
*CPU 虚拟化
*RAM,磁盘空间
*码头工人
2.安装Docker-OSX
*开始吧!
*安装操作系统
3.自定义安装
*提取磁盘映像
*添加 RAM 和 CPU
*从主机共享文件夹
*写入共享文件夹
*联网,访问端口
*设置主机网络
*使用 VNC 客户端
4.结论
先决条件
CPU虚拟化
您的 CPU 应支持 Intel VT 或 AMD-V 等虚拟化。在您的 BIOS/UEFI 中启用它,然后再继续。 (例如,在我的 Ryzen 系统上,这是一个必须在 BIOS 中启用的“AMD SVM”设置。)
然后安装内核虚拟化管理器 (KVM) 和 QEMU。对于 Fedora Linux,请参阅此处的文档。很简单:
# sudo dnf install @virtualization
进入全屏模式 退出全屏模式
然后启动libvirtd
systemd 服务并检查kvm
内核模块是否正在运行。
借助 KVM,x86 虚拟化提供了接近原生的性能,这意味着来自 Mac 虚拟机的 CPU 调用以安全的方式直接路由到您的处理器,而不会受到任何形式的仿真损失。
尽管图形和一般 UI 响应速度会很慢,但使用 KVM,只要你有一些强大的 CPU,比如更新的 Intel i7 或 Ryzen 7,软件就会运行得非常快。
例如,将 KVM 的效率与DOSBox进行比较,因为 DOS 程序使用低级 BIOS 中断和真实 CPU 模式,所以需要完全仿真。这种模拟可能会慢几个数量级,尽管在今天的机器上模拟 DOOM 时这不是问题。 :)
RAM,磁盘空间
如果您想运行 Xcode,请至少安装 16Gb 的 RAM,以便您可以为虚拟机分配大约 8Gb。
您将需要数十 GB 的磁盘空间。一旦您开始安装软件,QEMU“qcow”图像就会疯狂地扩展,直到它们达到 200 Gb 的预设限制。使用几天后,我的图像文件增长到 170 Gb。因此,请准备好具有足够可用空间的 HDD/SSD。
码头工人
由于我们将使用Docker-OSX项目,因此您需要在本地拉取、运行甚至创建 Docker 映像。您可能对podman很幸运,尽管它与您的系统交互的方式与 Docker 不同。 YMMV。要安装 Docker,请遵循安装指南。
安装Docker-OSX
熟悉 Docker-OSX下载页面。它有一个很好的、很长的自述文件!命令可能会更改,因此请参阅自述文件以获取最新版本。
简而言之,Docker-OSX 运行一个 Arch Linux 容器,该容器执行 QEMU 并为您设置预安装的或 vanilla macOS 映像。可疯狂定制:您可以通过单个docker run
命令快速开始,但根据您的需要,您可以自定义虚拟机运行方式的多个方面,如屏幕分辨率、共享文件夹、USB 直通、VNC 连接等。
开始吧!
只需运行一个基本图像。选择您的操作系统版本(Catalina、Big Sur、Monterey)。我建议选择仍然受支持的 Big Sur,但不像 Monterey 那样新,它可能存在一些仿真问题。
运行适当的命令:
docker run -it \
--device /dev/kvm \
-p 50922:10022 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e "DISPLAY=${DISPLAY:-:0.0}" \
sickcodes/docker-osx:big-sur
进入全屏模式 退出全屏模式
这是做什么的?它会拉取一个预构建的 Big Sur 映像,将您的 /dev/kvm
设备和一个 X11 套接字转发到容器中。它在主机中的 50922 端口公开容器内的 10022 端口,以进行 SSH 访问(可选)。它还设置了一个环境变量,告诉容器使用哪个 X 显示器。
对于管理 Docker 容器,如果您不想处理命令行,我建议使用 Visual Studio 代码](https://code.visualstudio.com/docs/containers/overview)的[Docker 扩展。非常方便!
基本上,当容器运行时,QEMU 虚拟机将继续运行。如果您从 macOS 内部关闭机器,容器将停止。docker run
启动一个全新的容器,但您可以稍后通过docker start
启动同一个容器。
安装操作系统
启动后,您将看到 macOS 的恢复安装程序:
Mac VM 的引导加载程序
您必须按照 README 的“附加启动说明”部分来格式化虚拟磁盘映像并在其上安装 macOS(该映像包含预先安装的 Big Sur 安装介质)。
格式化虚拟磁盘映像
这是非常简单的点击式工作,您很快就会收到自己的 macOS 安装!
享受新安装!
从这里开始,如何自定义图像由您决定。我将在这里展示一些技巧!
自定义您的安装
提取磁盘镜像
我建议做的第一件事是提取 macOS 磁盘映像,以便在您试验 VM 设置时,您将拥有所有工作和设置的持久安装。它只是/var/lib/docker
中的一个大文件:
sudo find /var/lib/docker -size +10G | grep mac_hdd_ng.img
进入全屏模式 退出全屏模式
将文件复制到有空间增长的方便位置(2-300Gb!)。从这里开始,您可以使用“裸”容器之一创建您自己的自定义映像,在该容器中,该文件只是作为卷安装:
docker run -it \
--device /dev/kvm \
-v "${PWD}/mac_hdd_ng.img:/image" \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e "DISPLAY=${DISPLAY:-:0.0}" \
sickcodes/docker-osx:naked
进入全屏模式 退出全屏模式
从这里开始,为了方便起见,我建议您创建一个文本文件来存储docker run
命令的版本。是时候破解了!
添加 RAM 和 CPU
默认情况下,仅使用 4 个内核和 4 Gb 的 RAM 创建 VM。为什么不使用更多?根据您的系统,添加参数-e RAM=8 -e CPU_STRING=16
以使其更快、更快!
从主机共享文件夹
这个非常有用,因为您可能想从主机共享一些文件。不幸的是,这并不简单。因为网络开箱即用,如果只是一些较小的文件,您实际上可能会更好地通过 Dropbox 等云提供商共享文件!
请参阅此处的说明。您基本上将文件夹名称作为docker run
参数传递,例如-v "$HOME/mac/shared:/mnt/hostshare"
,并添加一些额外的 QEMU 参数,将这个文件夹定义为一个名为hostshare
的设备。此外,在 VM 内部,每次启动后,您必须挂载这个文件夹:sudo -S mount_9p hostshare
。
在 Finder 的菜单栏中,单击“前往 - 计算机”以访问此共享文件夹。这种共享文件夹不如原生“qcow”磁盘镜像快;不要将它用于包含数千个文件的文件夹,例如 Git repos,这将是一种缓慢的体验。
写入共享文件夹
您可能会注意到您无法写入共享文件夹。这是因为 Linux 权限系统的工作原理:每个用户都有一个与每个文件相关联的 ID。在确定文件系统权限时,实际上使用的是此 ID 而不是您的用户名。
macOS 也是 POSIX 兼容的操作系统,使用相同的访问模型,但您的 macOS 用户很可能默认具有不同的 ID,因此主机操作系统将拒绝权限。
使任何人都可以写入共享文件夹可能会起作用,但从安全角度来看是很糟糕的。幸运的是,您可以使用一些命令来更改您的 macOS 用户 ID。请参阅此处的指南。不是超级复杂,但也不是很简单。如果你打算这样做,我建议在你的 VM 中安装任何软件之前这样做,因为每个文件都需要重置它们的用户 ID。
联网,访问端口
Docker 中的网络本身就很困难,此外,我们正在让这个 VM 在 QEMU 中运行。哎哟。除了浏览网页之外,您可能还有不同的用例,这应该是开箱即用的。
将端口从 VM 转发到主机,例如,在 VM 中运行 nginx 或某些服务器后端是一个有效的用例。对于每个被转发的端口,在设置容器时需要一些额外的参数,请参阅此处的 README 部分。
从 VM 访问主机端口,即localhost
访问也可以通过使用-p
Docker 参数将相应端口转发到容器来实现。 QEMU 将宿主机的localhost
(在 Docker 内部!)设置为10.0.2.2
,之后,
设置主机网络
如果您不想单独将端口转发到 Docker 容器中,您可以选择使用“主机网络”驱动程序。在这种情况下,您可以通过10.0.2.2
访问所有 Linux 机器的端口。从安全角度来看,这也是一个缺点:只有在您知道自己在做什么的情况下才这样做。
使用 VNC 客户端
默认的 QEMU 窗口可以完成这项工作,但通过 VNC 客户端访问您的 VM 要方便得多。它具有以下优点:
-
关闭模拟器窗口时不必停止 VM
-
显示主机的鼠标光标以获得更流畅的体验
-
捕获键盘快捷键,如
CMD+C
等。 -
通过键入从主机剪贴板“插入”(即使没有直接剪贴板共享)
-
改变连接质量等
我建议使用RemminaVNC 客户端,因为它非常先进,但您可以随意使用自己的客户端。有多种方法可以获得支持 VNC 的版本,最简单的可能是在 repo 中构建一个自定义 Dockerfile(如果需要不同的分辨率,请编辑文件):
$ git clone git@github.com:sickcodes/Docker-OSX.git
$ cd Docker-OSX/vnc-version
$ docker build -t docker-osx:nakedvnc -f Dockerfile.nakedvnc .
进入全屏模式 退出全屏模式
记下构建容器时打印的 VNC 密码!每次运行都将是永久的,因此您可以将其保存到您的 VNC 客户端。您可以通过localhost:5999
连接到它。不要忘记在 QEMU 菜单栏和 VNC 客户端中设置“抓取输入”和“隐藏菜单栏”。
如果您终止 VNC 连接,您的 macOS 系统将继续运行。整洁的!
这是我的示例 Docker 命令以供参考,运行支持 VNC 的容器(在上面构建),带有共享文件夹、自定义映像和主机网络。
docker run \
--device /dev/kvm \
--network host \
-v "$HOME/mac/mac_hdd_ng.img:/image" \
-v "$HOME/mac/shared:/mnt/hostshare" \
-e EXTRA="-virtfs local,path=/mnt/hostshare,mount_tag=hostshare,security_model=passthrough,id=hostshare" \
-e RAM=8 \
-e CPU_STRING=16 \
docker-osx:nakedvnc
进入全屏模式 退出全屏模式
结论
我希望你喜欢阅读这个小指南。尝试这个实验确实展示了我们当前的虚拟化技术是多么先进,并允许您将 macOS 用于合法用例,例如安全虚拟机内的安全研究。
更多推荐
所有评论(0)