Create macOS or Linux virtual machines
System & Services 进阶 20m

创建 macOS 或 Linux 虚拟机

Create macOS or Linux virtual machines

2022年6月6日

在 Apple 官方观看视频

一句话判断

在 Apple Silicon 上运行 macOS 和 Linux 虚拟机从未如此简单——Virtualization 框架把复杂的虚拟化配置变成了几行 Swift 代码,性能还接近原生。

这场 Session 讲了什么

Benjamin Poulain 详细讲解了如何使用 Apple 的 Virtualization 框架在 Apple Silicon 上创建和运行 macOS 及 Linux 虚拟机。

内容从虚拟化技术栈的整体架构开始:Apple Silicon 的硬件虚拟化支持 -> macOS 内核内置的虚拟化支持 -> Hypervisor 框架(底层 API)-> Virtualization 框架(高层 API)。Session 聚焦于 Virtualization 框架的使用。

核心内容分为三部分:通用的虚拟机配置方法、macOS 虚拟机的特殊配置与安装流程、Linux 虚拟机的运行和新特性。配置虚拟机就像在 Apple Store 上定制 Mac——选择 CPU 数量、内存大小、存储和输入设备,只不过用代码完成。

值得深挖的点

配置即代码的理念。 创建虚拟机的过程完全用 Swift 描述:从 VZVirtualMachineConfiguration 开始,设置 CPU 数量、内存大小,添加各种设备(存储、输入、显示)。这种方式把虚拟化从”运维操作”变成了”编程任务”。

macOS 虚拟机的三要素。 要创建一个虚拟 Mac,需要配置三个独有属性:硬件模型(VZMacHardwareModel,决定虚拟 Mac 的版本)、辅助存储(VZMacAuxiliaryStorage,非易失性内存的文件存储)、机器标识符(VZMacMachineIdentifier,唯一标识这台虚拟机)。加上 VZMacBootLoader,就完成了从通用虚拟机到虚拟 Mac的转变。

macOS 安装流程。 安装分三步:从恢复映像创建安装映像、将安装映像配置为启动盘、启动虚拟机后系统自动进入安装流程。安装完成后切换到已安装的系统盘启动即可。

文件共享。 虚拟 Mac 和主机 Mac 之间可以通过 VZDirectorySharingDeviceConfiguration 共享目录。设置了共享标签后,虚拟机内的 Finder 侧边栏会出现共享目录,像普通文件夹一样操作。

Linux 虚拟机的改进。 今年新增了 virtio-gpu 设备支持(VZVirtioGraphicsDeviceConfiguration),为 Linux 虚拟机提供图形加速。还新增了 virtio-balloon 设备,允许动态调整虚拟机的内存分配。

代码片段

import Virtualization

// 基础虚拟机配置
let config = VZVirtualMachineConfiguration()
config.cpuCount = 4
config.memorySize = 4 * 1024 * 1024 * 1024  // 4GB

// macOS 虚拟机的特殊配置
let platform = VZMacPlatformConfiguration()
platform.hardwareModel = savedHardwareModel  // 之前保存的硬件模型
platform.auxiliaryStorage = VZMacAuxiliaryStorage(
    contentsOf: auxiliaryStorageURL  // 辅助存储文件
)
platform.machineIdentifier = savedMachineIdentifier  // 唯一标识
config.platform = platform

// macOS 启动加载器
config.bootLoader = VZMacBootLoader()

// 添加存储设备
let diskAttachment = try VZDiskImageStorageDeviceAttachment(
    url: diskImageURL,
    readOnly: false
)
config.storageDevices = [VZDiskImageStorageDevice(attachment: diskAttachment)]

// 创建并启动虚拟机
let virtualMachine = VZVirtualMachine(configuration: config)
try await virtualMachine.start()

// 在 App 中显示虚拟机画面
let vmView = VZVirtualMachineView()
vmView.virtualMachine = virtualMachine
// 将 vmView 作为 NSView 嵌入到你的窗口中

// 配置目录共享(macOS <-> macOS)
let sharingConfig = VZDirectorySharingDeviceConfiguration()
sharingConfig.share = VZMultipleDirectoryShare(
    directories: ["shared": VZSharedDirectory(url: sharedDirURL, readOnly: false)]
)
sharingConfig.tag = 1234  // 共享标签
config.directorySharingDevices = [sharingConfig]

最佳实践

  • Apple Silicon 上运行 macOS 虚拟机的效率极高,因为 macOS 和 Virtualization 框架是协同设计的
  • 使用 VZVirtualMachineView 可以轻松将虚拟机画面嵌入到应用窗口中
  • 保存硬件模型和机器标识符,这样虚拟机在重启后保持一致性
  • 对于 Linux 虚拟机,新增的 virtio-gpu 设备提供了更好的图形性能
  • virtio-balloon 设备让你可以在运行时调整虚拟机的内存分配,提高资源利用率
  • Virtualization 框架支持 Linux 在 Apple Silicon 和 Intel 上运行,macOS 仅支持 Apple Silicon

还有什么值得关注

  • Hypervisor 框架适合需要完全控制虚拟环境的场景,大多数情况下 Virtualization 框架就够了
  • Linux 虚拟机支持完整的 Linux 发行版,不限于特定发行版
  • 虚拟机的网络配置可以通过 virtio 网络设备实现
  • 虚拟 Mac 不需要额外的 macOS 许可证(在 Apple Silicon 上运行)
WWDC 2022