☰
Multipass 核心概念解析:从架构、实例到安全与性能的完整指南
2026/9/26 2:44:25 网站建设 项目流程
  • 虚拟化
  • 开发工具
  • 云原生

【免费下载链接】multipass

Multipass orchestrates virtual Ubuntu instances

项目地址:https://gitcode.com/gh_mirrors/mu/multipass
点击查看免费下载

本文基于docs/explanation/系列概念指南整理而成,系统梳理了 Multipass(在 Linux、macOS 与 Windows 上编排虚拟 Ubuntu 实例的工具)的核心设计思想:客户端/守护进程架构、平台与驱动差异、实例与镜像机制、exec/mount/snapshot 等日常操作背后的原理,以及安全认证、ID 映射与性能调优建议。读完本文,你将理解 Multipass 各组件之间的调用关系,并能准确解释local.driver、local.privileged-mounts、client.primary-name等关键设置的作用,以及multipass exec与 SSH 在命令解析上的本质区别。


架构(Architecture)

架构类主题解释 Multipass 在宿主机上如何运转,包括客户端、守护进程、存储、实例与网络等高层结构。整体概览参见 参考架构,平台差异见 Platform、Service 与 Driver。

Multipass 是一套客户端/服务器(client/server)模型:客户端负责提供用户界面并把请求委托给守护进程(daemon),守护进程则负责实际管理实例、认证、设置存储与文件系统共享等所有繁重工作。用multipass命令或 GUI 操作实例时,本质上都是在向后台的multipassd进程发送请求。

客户端(Clients):CLI 与 GUI

Multipass 提供两种用户界面客户端,均与守护进程通信并委托操作:

  • CLI(命令行界面):即multipass可执行程序,通过multipass launch、multipass start等命令在终端中控制实例。CLI 的实现在 src/client/cli 目录中,其中 cli.cpp 负责解析命令行参数并建立与守护进程的连接。
  • GUI(图形界面):基于 Flutter 构建的独立桌面应用(源码位于 src/client/gui),提供可视化、点选式的实例管理界面,与 CLI 一样通过 RPC 与守护进程交互。

从源码结构看,两者共享同一套 gRPC 协议定义(src/rpc/multipass.proto)与相同的 RPC 客户端逻辑,差异仅在于用户交互层的表现形式。

守护进程 / 服务(Daemon / Service)

守护进程(multipassd)是长期运行的后台进程,负责实例生命周期管理、客户端认证、配置存储与文件系统共享。它以特权用户身份运行,因此能直接访问系统资源,并控制哪些用户有权使用 Multipass 的实例。

关于客户端与守护进程的分离架构,其核心优势是灵活性:理论上守护进程可以与客户端运行在不同机器上,从而支持远程使用 Multipass。

守护进程的自动启动在 Multipass 安装完成后即被触发,并配置为随系统开机自启。这保证了客户端无需手动启动守护进程即可立刻操作实例,并在系统重启后自动恢复持久化的实例。multipassd的实现集中在 src/daemon 目录(如 daemon.cpp、daemon_main.cpp)。

从 cli.cpp 的源码注释可以看到,守护进程的监听端点可通过unix:<socket_file>的形式指定——在 Linux/macOS 上这是 Unix 域套接字;而在 Windows 上,platform_win.cpp 返回localhost:50051,即 TCP 套接字。

存储 / 挂载(Storage / Mounts)

Mount 是宿主机与客户实例之间的文件系统共享,把宿主目录暴露到虚拟机内部,用于双向文件传输。底层技术取决于挂载类型与宿主平台,可以是 SSHFS/SFTP、9P 或 SMB(详见后文 Mount 一节)。

实例(Instances)

实例是由宿主机承载的 Linux 虚拟机。Multipass 使用与用户原生操作系统匹配的 hypervisor 技术来模拟运行实例。

镜像主机(Image Hosts)

镜像主机是获取磁盘镜像的远程来源——目前是公开的云 Linux 镜像在线仓库。Multipass 会周期性抓取并更新来自镜像主机的元数据,同时清理旧镜像、按需下载新镜像。镜像抓取与解析的相关实现见 src/image_host(如 ubuntu_image_host.cpp)与 src/simplestreams。

网络(Networking)

Multipass 在宿主机上利用专用子网创建一个虚拟网络。每个实例通过 DHCP 从该私有网络获得 IP 地址。在此私有网络内,实例可以发起出站连接(egress)、相互通信,并能被宿主机访问,但无法被宿主机外部访问。如需入站连接(ingress),可以将实例桥接到宿主机的物理网络(例如家庭局域网中的其他电脑)。网络相关实现见 src/network(如 subnet.cpp)。

Web

Multipass 实例默认在线(只要宿主机联网即可):它们既可通过私有网络也可通过公共网络访问互联网;守护进程本身也会从网络获取信息,尤其是镜像主机。

平台(Platform)

平台指宿主机操作系统——Windows、macOS 或 Linux。尽管 Multipass 力求跨平台提供统一的界面,但并非所有特性在所有平台都可用,主要差异如下:

特性仅在以下平台支持说明
Windows 终端集成Windows影响设置client.apps.windows-terminal.profiles
MountsLinux、macOS、Windows(默认禁用)Windows 上可通过设置local.privileged-mounts启用;影响mount、umount与launch命令
全局 IPv6(QEMU)Linux、macOS使用 QEMU 驱动时,全局 IPv6 地址仅在 macOS 上可用
驱动(Drivers)Linux、macOS、Windows不同平台可用驱动不同,影响local.driver设置,详见下文驱动功能差异
桥接 Wi-Fi 网络macOS在 Linux 和 Windows 上,networks命令的输出不会显示 Wi-Fi 网络

驱动(Driver)

驱动(driver)是 Multipass 模拟运行机器的技术,对应某个 hypervisor 或中间层技术,有时也被称为"后端(backend)"。Multipass 依赖驱动才能运行,支持多种驱动但同一时刻只使用一种,通过设置local.driver选择;未手动设置时使用平台合适的默认驱动。

从源码看,驱动是插件化的:multipassd通过工厂(factory)创建具体后端,并使用后端相关的数据/缓存目录来隔离实例数据(见 daemon.cpp 中对backend_directory_path的使用),不支持的特性会抛出not_implemented_on_this_backend_exception(daemon.cpp)。

各平台支持的驱动:

  • Linux:QEMU。自 Multipass 1.16 起,LXD 和 libvirt 不再可用。
  • macOS:QEMU、Apple Virtualization framework(AppleVZ)和 VirtualBox。自 1.13 起,Hyperkit 不再可用。
  • Windows:Hyper-V(仅 Windows Pro 可用)或 VirtualBox。

默认驱动:

  • Linux 和 macOS 默认使用 QEMU;
  • Windows 取决于系统版本:Windows Pro 使用 Hyper-V,Windows Home 使用 VirtualBox。

实例作用域(Instance scopes):一般情况下,实例与单一驱动绑定。用某驱动启动的一组实例,只有在该驱动启用时可见;切换驱动后 Multipass 进入独立的实例作用域(该作用域内实例集合初始为空,因此可以在不同驱动下用同名启动实例,且彼此互不影响)。不过实例在驱动之间是保留的:切回此前用过的驱动时,Multipass 会恢复对应的实例作用域,并尝试恢复切换前的实例状态。

例外:在 macOS 上,由 Multipass 1.12 或更高版本,已停止的 Hyperkit 实例会被自动迁移到 QEMU(参见 如何在 macOS 上从 Hyperkit 迁移到 QEMU)。

驱动功能差异:

特性不支持的驱动说明
原生挂载(Native mounts)AppleVZ、VirtualBox影响mount命令的--type选项
快照(Snapshots)AppleVZ影响snapshot命令
挂起(Suspend)AppleVZ影响suspend命令

除驱动差异外,还存在宿主平台导致的功能差异,见 Platform。


实例(Instances)

实例类主题解释所创建虚拟机的生命周期、身份与资源。相关指南包括 Instance、Image 与 Settings keys and values。

实例(Instance)

实例是由 Multipass 创建和管理的虚拟机,其命名约定详见 实例名称格式。

主实例(Primary instance)

Multipass CLI 借助一个特殊实例——主实例(默认名为primary)提供若干快捷键行为:

  • 不带位置参数调用状态转换命令时,start、restart、stop、suspend均作用于该特殊实例;shell命令同样如此。
  • start和shell在主实例不存在时会自动创建它。
  • 创建主实例时,Multipass CLI 会自动把用户主目录挂载进实例;如同任何其他挂载一样,可用multipass umount卸载。例如multipass umount primary会卸载primary实例内由 Multipass 建立的所有挂载(包括自动挂载的Home)。
  • 注意:在 Windows 上挂载默认因安全原因被禁用,详见后文安全一节。
  • 除此之外,主实例与其他实例完全一样,其属性等同于手动执行multipass launch --name primary创建的实例。

主实例的名字可通过设置client.primary-name修改。该设置决定 Multipass 作为主实例创建和操作的实例名,既可以把任意已有实例设为主实例,也可以彻底禁用主实例功能。

镜像(Image)

Multipass 使用针对云环境调优的磁盘镜像/系统镜像来启动虚拟机。可用multipass find查看可用镜像列表。镜像来源包括:

  • Ubuntu Cloud Images(https://cloud-images.ubuntu.com/)
  • Ubuntu CD Images(https://cdimages.ubuntu.com/)
  • 以及其他来源

也可以从文件或 URL 启动镜像,前提是镜像提供云部署所需的工具,核心要求是:

  • cloud-init
  • SSH

具体某个镜像的系统要求,请参阅对应镜像的官方文档。

设置键与值(Settings keys and values)

Multipass 设置以树状结构组织,每个设置由唯一的key标识,在任一时刻取单一value。相关的Settings类实现见 src/settings/settings.cpp,其keys()/get()/set()通过注册的 handlers 解析键路径(settings.cpp),未识别的键抛出UnrecognizedSettingException。

设置键是形如点分隔路径的字符串(如client.primary-name),指定从设置树根到叶子的路径,每个叶子对应一个独立设置。通配符可用来一次性指代多个设置,例如:

  • local.<instance-name>.*:影响特定实例的全部设置;
  • local.*.cpus:所有 Multipass 实例的 CPU 数量。

设置值是字符串,其语法(可能的取值与表示形式)和语义(解释方式)由具体设置决定。值通常表达常见概念(如true、false、42),内部按对应数据类型(布尔、整数等)解释;也可能更复杂(如一个按键组合),但始终通过字符串表示与显示(例如Ctrl+Alt+U)。


使用 Multipass(Using Multipass)

与实例交互和扩展功能相关的概念,包括 exec 与 shells、Mount、Alias 与 Snapshot。

multipass exec与 Shell

exec 如何解析命令

当你从 shell 调用multipass exec时,命令首先由你所在的 shell 解析,解析结果是 multipass 客户端在参数列表(argv)中看到的内容。

例如在 Linux shell 中输入multipass exec primary -- ls ~,波浪号会先被翻译成调用用户的本地主目录,再传给 Multipass;但在 Windows PowerShell 中并非如此,因为那里~没有同样的含义。

引号处理同样取决于调用 shell:在大多数 Linux/macOS shell 中,单引号界定字符串并逐字传给程序。而 Windows PowerShell 不这样处理单引号——传入'abc def'会得到两个参数'abc和def'。可改用双引号"abc def",但双引号内的字符串会经受 shell 展开。例如:

set USER=me multipass exec -n rich-zorilla -- bash -c "echo %USER%"

输出为:me。

而在 Linux 上展开语法不同:

multipass exec -n rich-zorilla -- bash -c "echo $USER"

此例输出为:ubuntu。

SSH 如何解析命令

Multipass 会在给定实例中执行--之后的命令,仿佛中间没有额外的 shell(这是简化说法,实际情况稍复杂)。这与使用 SSH 时有所不同。考虑在bashshell 中执行:

multipass exec mp-builder -- python3 -c 'import sys; print(sys.argv)' foo bar

输出为:['-c', 'foo', 'bar']。

若改用 SSH,则整个命令需要用引号包裹:

ssh -i /var/root/Library/Application\ Support/multipassd/ssh-keys/id_rsa ubuntu@192.168.66.34 python -c 'import sys; print(sys.argv)' foo bar

示例输出(报错):

bash: -c: line 1: syntax error near unexpected token `sys.argv' bash: -c: line 1: `python -c import sys; print(sys.argv) foo bar'
用 shell 解析命令

要解决上述multipass exec的问题,可以在实例内显式调用一个 shell 来解析命令。例如:

multipass exec calm-woodcock -- sh -c 'ls -a ~'

示例输出:

. .. .bash_logout .bashrc .cache .profile .ssh

Windows 命令提示符下的等价写法(注意用适合调用 shell 的引号):

multipass exec calm-woodcock -- sh -c "ls -a ~"

只要调用 shell 的引号使用得当,这种写法在跨平台行为上保持一致;而不加sh -c时,在所有平台上都会失败(失败方式因是否引用嵌套命令而不同)。sh -c技巧提供了更一致的跨平台体验。

输入/输出重定向

multipass exec可与管道配合,在宿主与实例命令之间重定向输入/输出。例如,把宿主机当前目录内容写入实例rich-zorilla中的文件save:

ls -la | multipass exec -n rich-zorilla -- bash -c "cat > save"

反过来,把实例rich-zorilla主目录内容保存到宿主文件:

multipass exec -n rich-zorilla -- bash -c "ls -la" | cat > save
其他 shell 技巧

其他 shell 特性可与multipass exec组合使用。例如 bash 的 here-string:

multipass exec -n primary -- bash << EOF > hostname > whoami > EOF

示例输出:

primary ubuntu

再如命令替换(command substitution):

ping $(multipass exec rich-zorilla -- hostname -I)

示例输出:

PING 10.239.73.39 (10.239.73.39) 56(84) bytes of data. 64 bytes from 10.239.73.39: icmp_seq=1 ttl=64 time=0.371 ms 64 bytes from 10.239.73.39: icmp_seq=2 ttl=64 time=0.304 ms 64 bytes from 10.239.73.39: icmp_seq=3 ttl=64 time=0.439 ms ^C --- 10.239.73.39 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2054ms rtt min/avg/max/mdev = 0.304/0.371/0.439/0.055 ms

Mount(挂载)

mount是从宿主到实例的目录映射,使挂载目录的内容及变更在两端同时可用。Multipass 有两种挂载类型:classic(经典,默认)和native(原生)。

  • Classic mounts:使用 SSHFS(SSH 文件系统)实现文件/目录共享,在所有后端都可用。SSHFS 基于 SSH,因安全通信而付出一定性能代价。
  • Native mounts:使用驱动相关的技术以获得高性能,仅在以下场景可用:
    • Hyper-V:基于 SMB/CIFS 实现;
    • QEMU:基于 9P 协议实现。

具体支持情况也受驱动功能差异影响(见上文 Driver 一节)。

挂载的安全考虑(Security considerations)

挂载的安全影响因平台而异:

  • Linux:由于挂载以root身份执行(除非通过 snap 安装,见下),理论上允许写入整个宿主机操作系统。但因为只有特权用户(sudo、wheel、admin组成员)能使用 Multipass,因此不是问题。若通过 snap 包安装,snap 约束 会阻止挂载/home目录之外的路径(以及/home内的隐藏文件/文件夹),并可能限制可移动介质(取决于所连接接口)。但仍需注意:有 Multipass 权限的用户(A)可以访问另一用户(B)挂载到 B 主目录的挂载点。
  • macOS:挂载同样以root执行,允许写整个宿主机 OS;但由于只有特权用户(sudo、wheel、admin组成员)能使用 Multipass,因此不是问题。
  • Windows:挂载以特权用户(SYSTEM)执行,允许写整个宿主机操作系统。由于历史原因,Windows 上挂载默认禁用(即使当前版本的 Multipass 要求用户先通过认证才能获得服务)。如需启用,参见local.privileged-mounts。

Alias(别名)

在 Multipass 中,别名(alias)是"在指定实例内运行的命令"的快捷方式。别名通过multipass alias创建(见 alias 命令参考),使用与维护方法参见 如何使用实例命令别名。别名的数据模型与解析逻辑在 src/utils/alias_definition.cpp 中实现。

Snapshot(快照)

快照是实例在某一时刻的概念性映像,可用于把实例恢复到该时刻的状态。为此,快照记录实例的所有可变属性——即通过 Multipass 交互可能变化的属性,包括:磁盘内容与大小、CPU 数量、内存大小和挂载。别名不被视为实例的一部分,因此不记录。

用法:

  • 用snapshot命令创建快照,用restore恢复;创建和恢复快照要求实例处于停止状态。
  • 用multipass list --snapshots查看可用快照列表,用multipass info <instance>.<snapshot>查看某个快照详情,用delete删除快照。

父子关系(Parents):实例的磁盘内容以分层方式记录在快照中:每个新快照记录相对其父快照的变化。某快照的父快照是创建该快照时最近一次被创建或恢复的快照。删除某快照后,其父/子快照仍保留一致的实例记录。Multipass 会提供快照的父子关系信息,帮助识别其角色或内容。

注意事项:

  • 长链条快照对性能有不利影响:由于依赖磁盘 diff 层,序列中的快照越多,读取最古老层记录的数据所需的跳数就越多。
  • 快照虽便于保存和恢复实例状态,但作为安全备份的用途有限:它们与原始镜像存储在同一介质上,同样可能受磁盘故障影响。

安全与性能(Security and performance)

相关概念指南包括 About security、Authentication、ID mapping 与 About performance。

关于安全(About security)

警告:Multipass 主要面向开发、测试和本地环境,不适用于生产环境。在部署 Multipass 虚拟机前,请仔细审阅本页安全考虑。

Multipass 运行一个守护进程,在 Linux/macOS 上通过Unix socket本地访问,在 Windows 上通过TLS socket访问。任何能访问该 socket 的人都可以完全控制 Multipass,包括挂载宿主机文件系统或篡改所有实例的安全特性。因此,务必把守护进程访问限制在可信用户范围内。

守护进程的本地访问:守护进程以 root 运行并提供 Unix socket 用于本地通信。Multipass 的访问控制首先基于组成员身份,之后由用户在被接受提供的 passphrase 时获得的 TLS 证书决定。第一个连接的用户若属于sudo组(或视 OS 为wheel/adm),其 TLS 证书会自动导入守护进程并被认证;此后其他用户连接时需要先用管理员设置的 passphrase 执行authenticate。

认证(Authentication)

执行任何命令前,Multipass 都要求用户与服务完成认证。认证流程基于由椭圆曲线(EC)密钥签名的x509 证书(由 OpenSSL 驱动):用户连接时,Multipass 验证证书以确保只有经过验证的用户能访问服务。相关实现可参考 src/cert/client_cert_store.cpp 与 src/cert/ssl_cert_provider.cpp。

按平台区分:

  • Linux 与 macOS:客户端与守护进程通过 Unix 域 socket 通信。首次使用时,socket 只允许属于其所属组的用户连接(例如sudo、admin或wheel,用户需属于该组,否则连接被拒绝)。当第一个属于管理员组的客户端连接后,其 OpenSSL 证书被守护进程接受,此后 socket 对所有用户开放。其他用户连接 Multipass 服务时,需要用先前设置的local.passphrase进行认证。
  • Windows:Windows 宿主使用监听50051 端口的 TCP socket 与客户端通信(对应 platform_win.cpp 中的localhost:50051)。由于 TCP socket 没有文件所有权概念,该 socket 对所有人开放——这并不安全,任何 Multipass 用户都能连接并执行任意命令。为弥补这一缺口,用户现在必须通过认证才能使用服务;为减轻负担,安装更新版 Multipass 的用户会自动完成客户端认证,其他用户则需用先前设置的 passphrase 认证。

ID 映射(ID mapping)

ID 映射指挂载目录时在宿主系统与实例之间对齐用户或组 ID 的过程,确保从宿主挂载到实例的文件保留一致的属主和权限属性。

由于 ID 映射同时作用于宿主到实例和反向,必须定义为一对一关系:宿主上的每个用户/组 ID 应直接映射到虚拟机内的单个用户/组 ID,反之亦然。

例如,把用户 ID501映射到 "foo" 实例中的用户 ID1000:

multipass mount ~/Documents foo:Documents -u 501:1000

反之,不允许把同一用户映射到实例内的第二个用户 ID,因为 Multipass 无法确定把宿主上 ID 为501的文件在实例内分配给哪个用户 ID。以下命令是无效挂载(宿主多个 ID 映射到实例同一 ID):

multipass mount ~/Documents foo:Documents -u 501:1000 -u 502:1000

正确做法是映射两个不同用户 ID:

multipass mount ~/Documents foo:Documents -u 501:1000 -u 502:1001

同理,把实例内的单个用户/组 ID 映射到宿主的两个不同 ID 也不允许。ID 映射的挂载实现见 src/utils/vm_mount.cpp 与挂载处理逻辑 src/sshfs_mount。

关于性能(About performance)

考虑 Multipass 性能时需兼顾两个对象:Multipass 实例与宿主机。

宿主机系统:

  • CPU/核心/线程:规划实例时需考虑宿主 CPU 速度、核心数与线程数,以及同时运行的实例数量。分配给实例的核心数与运行实例数会显著影响宿主机上的进程。一般建议至少预留两个不分配给运行实例的线程。
  • 内存使用:分配给实例的内存量也会显著影响宿主。不要过度分配运行实例的内存,否则可能让宿主变慢甚至无响应。建议为宿主至少预留4GB内存,具体取决于宿主自身负载,可能需要更多。

Multipass 实例:

  • CPU:分配给实例的 CPU 数量直接影响实例性能。通常 CPU 越多、实例性能潜力越大,但这高度依赖实例预期的工作负载。
  • 内存:与核心一样,分配给实例的内存直接影响其性能,同样取决于预期工作负载。内存密集型负载在分配更多内存时通常能获得更大的性能提升。

实例资源的实际分配通过launch命令的--cpus、--memory、--disk等选项完成,相关数据结构见 src/utils/vm_specs.cpp。


术语表(Glossary)

  • Alias(别名):在 Multipass 中,别名是"在指定实例内运行的命令"的快捷方式。参见 alias 命令参考 与 如何使用实例命令别名。
  • Host(宿主):指 Multipass 实际运行所在的物理机器。

延伸阅读

若想深入实践,可继续阅读同一文档体系中的相关内容:

  • 操作指南:安装 Multipass、管理实例、设置驱动、与实例共享数据、认证 Multipass 服务用户
  • 命令参考:命令行界面索引、实例状态
  • 设置参考:设置索引、local.driver、local.privileged-mounts、local.passphrase、client.primary-name
  • 概念指南入口:docs/explanation/index.md
  • 虚拟化
  • 开发工具
  • 云原生

【免费下载链接】multipass

Multipass orchestrates virtual Ubuntu instances

项目地址:https://gitcode.com/gh_mirrors/mu/multipass
点击查看免费下载
上一篇:netscan:网络扫描的终极指南,5分钟掌握网络探测技巧
下一篇:终极指南:如何在Mac上免费获得完整的NTFS读写权限

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询