- 虚拟化
- 开发工具
- 云原生
【免费下载链接】multipass
Multipass orchestrates virtual Ubuntu instances
multipass mount是 Multipass 中用于将宿主机本地目录映射到 Ubuntu 实例(instance)文件系统的核心命令,支持经典(classic)与原生(native)两种挂载类型,并可通过用户/组 ID 映射(UID/GID mapping)保持文件所有权的跨端一致性。本文基于仓库内 mount 命令参考文档 展开,结合 数据共享指南、Mount 原理文档、ID 映射文档 以及 CLI 与 daemon 源码实现,完整覆盖mount/umount的语法、全部选项、实际用例、底层工作原理与安全注意事项,帮助你高效地在宿主机与实例之间共享数据。
mount命令概览
multipass mount将宿主机上的一个本地目录映射到实例中,使目录内容及其后续变更在两端同时可见。你可以通过--type指定挂载类型,并通过-g/-u定义组 ID 或用户 ID 映射,使实例内文件与文件夹的所有权从宿主机 ID 映射到实例 ID。
基本语法如下(以 classic 挂载为例):
multipass mount --type=classic /host/path <instance name>:/instance/path使用multipass umount命令可撤销映射。关于 classic 与 native 挂载的差异详见 Mount 原理;关于如何用mount在宿主机与实例间共享数据的完整示例见 How to share data with an instance。
完整命令行选项参考
以下内容即multipass help mount的完整输出,说明了该命令的全部可用选项:
Usage: multipass mount [options] <source> <target> [<target> ...] Mount a local directory inside the instance. If the instance is not currently running, the directory will be mounted automatically on next boot. Options: -h, --help Displays help on commandline options -v, --verbose Increase logging verbosity. Repeat the 'v' in the short option for more detail. Maximum verbosity is obtained with 4 (or more) v's, i.e. -vvvv. -g, --gid-map <host>:<instance> A mapping of group IDs for use in the mount. File and folder ownership will be mapped from <host> to <instance> inside the instance. Can be used multiple times. Mappings can only be specified as a one-to-one relationship. -u, --uid-map <host>:<instance> A mapping of user IDs for use in the mount. File and folder ownership will be mapped from <host> to <instance> inside the instance. Can be used multiple times. Mappings can only be specified as a one-to-one relationship. -t, --type <type> Specify the type of mount to use. Classic mounts use technology built into Multipass. Native mounts use hypervisor and/or platform specific mounts. Valid types are: 'classic' (default) and 'native' Arguments: source Path of the local directory to mount target Target mount points, in <name>[:<path>] format, where <name> is an instance name, and optional <path> is the mount point. If omitted, the mount point will be under /home/ubuntu/<source-dir>, where <source-dir> is the name of the <source> directory.参数说明
source:本地要挂载的目录路径,必须是宿主机上真实存在、可读的目录(源码层面会对此进行校验,见下文)。target:目标挂载点,格式为<name>[:<path>],其中<name>是实例名称,<path>是可选的挂载点路径。若省略<path>,挂载点默认为实例内/home/ubuntu/<source-dir>,其中<source-dir>为source目录的目录名。-u/--uid-map <host>:<instance>:用户 ID 映射,将文件与文件夹的所有权从宿主机用户 ID 映射到实例内的用户 ID。可多次使用(多对映射),但每个映射必须是一对一关系。-g/--gid-map <host>:<instance>:组 ID 映射,规则与 UID 映射相同。-t/--type <type>:挂载类型,合法取值为classic(默认)与native。-v/--verbose:增加日志详细程度,可重复v以获取更多细节,最大冗长度为-vvvv。
源码中的参数校验与默认行为
上述选项并非仅是文档描述,mount.cpp 中的parse_args实现了完整的解析与校验逻辑,可作为实际行为依据:
- source 校验:代码使用
QFileInfo检查 source 路径,依次验证其存在(Source path ... does not exist)、是目录(Source path ... is not a directory)、可读(Source path ... is not readable),并通过QDir::absolutePath()规范为绝对路径后写入请求。 - target 解析:每个 target 参数按
:切分,前半部分作为实例名,后半部分作为目标路径;源码注释表明若省略路径,挂载点将位于home_in_instance(即/home/ubuntu)之下的<source-dir>。 - ID 映射格式校验:通过正则表达式
^([0-9]+[:][0-9]+)$校验-u/-g值必须是纯数字的host:instance形式,非法输入会报Invalid UID/GID map given。 - 默认 ID 映射:当未显式指定
-u/-g时,CLI 会添加默认映射——宿主机当前用户 UID/GID(mcp::getuid()/mcp::getgid())映射到实例内的default_id(在 client_platform.h 中定义为-1,由后端解释为默认用户,通常即ubuntu用户)。这一点解释了为何默认挂载后实例内文件归属于ubuntu用户。 - 挂载类型校验:
checked_mount_type只接受classic与native两个字符串(不区分大小写,toLower后比较),其他取值抛出ValidationException,提示Bad mount type '...' specified, please use 'classic' or 'native'。 - 命令执行:解析成功后,
Mount::run通过 gRPC 将MountRequest分发给 daemon,并使用旋转动画(spinner)反馈进度,失败时通过standard_failure_handler_for输出错误。
实际操作示例
基础共享:挂载宿主机目录到实例
将宿主机本地目录映射到实例,基本语法为:
multipass mount <local path> <instance name>例如,在 Linux 系统上将本地家目录$HOME映射到名为keen-yak的实例:
multipass mount $HOME keen-yak运行multipass info keen-yak可查看挂载结果:
... Mounts: /home/michal => /home/michal此后,本地家目录/home/michal的内容在实例内即可见、可读写。挂载路径是持久的,会一直保持到被显式卸载(unmount)为止,即使实例关机重启后,挂载也会在下次启动时自动恢复(CLI 帮助文本与源码均说明了这一点:"If the instance is not currently running, the directory will be mounted automatically on next boot")。
挂载到指定路径
若希望将本地目录挂载到实例中的特定路径,可显式指定目标:
multipass mount $HOME keen-yak:/some/path注意(覆盖语义):如果
/some/path在实例文件系统中已存在,其原有内容会被挂载目录临时隐藏(overlay),但不会被覆盖或删除;卸载后原目录内容会重新出现。因此,不能将外部目录挂载到实例的$HOME目录之上——$HOME中包含访问实例所需的 SSH 密钥,一旦被隐藏将无法再通过 shell 登录该实例。
在创建实例时定义挂载
也可以在创建实例时直接指定挂载,使用launch命令的--mount选项:
multipass launch --mount /local/path:/instance/path使用 ID 映射保持文件所有权
不同系统间用户 ID 往往不一致(如 macOS 用户 UID 为501,而 Ubuntu 实例内默认用户ubuntu的 UID 为1000)。通过-u/-g指定映射可让文件在两端保持正确的所有权。例如,将宿主机 UID501映射为实例内 UID1000:
multipass mount ~/Documents foo:Documents -u 501:1000由于 ID 映射在宿主机与实例之间双向生效,它必须是一对一关系:宿主机上的每个用户/组 ID 只能映射到实例内的一个 ID,反之亦然。以下命令是非法的,因为它将宿主机两个不同 UID(501、502)映射到了实例内同一个 UID(1000),Multipass 将无法确定宿主机上 UID 为501的文件在实例内应归属哪个 ID:
multipass mount ~/Documents foo:Documents -u 501:1000 -u 502:1000正确的多对映射写法应为:
multipass mount ~/Documents foo:Documents -u 501:1000 -u 502:1001同样的规则也适用于反向场景:不能把实例内的一个 ID 映射到宿主机上的两个不同 ID。ID 映射的详细原理参见 ID mapping 文档。
卸载共享目录(umount)
使用umount命令卸载先前挂载的路径。可指定具体路径进行定向卸载:
multipass umount keen-yak:/home/michal若不指定任何路径,则一次性卸载该实例的所有共享目录:
multipass umount keen-yakumount的完整帮助输出如下:
Usage: multipass umount [options] <mount> [<mount> ...] Unmount a directory from an instance. Options: -h, --help Displays help on commandline options -v, --verbose Increase logging verbosity. Repeat the 'v' in the short option for more detail. Maximum verbosity is obtained with 4 (or more) v's, i.e. -vvvv. Arguments: mount Mount points, in <name>[:<path>] format, where <name> are instance names, and optional <path> are mount points. If omitted, all mounts will be removed from the named instances.从源码看,umount.cpp 中umount命令还注册了别名unmount,其解析逻辑与mount的 target 解析一致:按:切分<name>[:<path>],仅给定实例名而不给路径时,即表示移除该实例上的全部挂载。
挂载类型:classic 与 native
Multipass 提供两种挂载类型,可通过--type选择:
- classic(默认):基于 Multipass 内置技术(SSHFS,SSH 文件系统)实现,在所有后端上均可用,兼容性更高,但因 SSH 加密通信而略有性能开销。
- native:使用驱动相关的高性能挂载技术,仅在特定后端可用:
- Hyper-V上通过 SMB/CIFS 实现;
- QEMU上通过 9P 协议实现。
从源码看,挂载类型的分派发生在 daemon 侧:daemon.cpp 中mount请求处理逻辑将请求中的MountType(CLASSIC/NATIVE)转换为VMMount::MountType(定义见 vm_mount.h),随后make_mount据此分派:
return mount.get_mount_type() == VMMount::MountType::Classic ? std::make_unique<SSHFSMountHandler>(vm, config->ssh_key_provider.get(), target, mount) : vm->make_native_mount_handler(target, mount);即 classic 挂载由SSHFSMountHandler处理(相关实现见 sshfs_mount_handler.cpp 及sftp_server相关文件),而 native 挂载则委托给具体虚拟化后端实现(例如 QEMU 的 qemu_mount_handler.cpp 与 Windows 的 smb_mount_handler.cpp)。若挂载目录时实例正在运行,daemon 会立即激活挂载;否则挂载将在实例下次启动时自动建立,这一行为在 test_daemon_mount.cpp 等测试中有覆盖验证。
安全注意事项
由于挂载以高权限身份执行,使用时需留意以下安全边界(详见 Mount 文档的安全小节):
- Linux:挂载以
root身份执行(snap 安装除外),因此对宿主机整个操作系统具有写权限。但由于只有特权用户(sudo、wheel、admin组成员)能使用 Multipass,这通常不构成问题。若通过 snap 安装,snap 的 confinement 会限制挂载范围在/home目录内(且不能挂载/home中的隐藏文件/文件夹),并根据所连接的接口限制可移动介质。即便如此,拥有 Multipass 访问权的用户 A 仍可能访问另一用户 B 在其家目录中建立的挂载。 - macOS:同样以
root身份挂载、对整个操作系统有写权限;同样因仅特权用户可用 Multipass 而无虞。 - Windows:挂载以特权用户(
SYSTEM)身份执行,对整个操作系统有写权限。出于历史原因,Windows 上挂载默认被禁用;如需启用,可设置local.privileged-mounts键。该设置项在 Linux 和 macOS 上默认为true,Windows 上默认为false(见 local-privileged-mounts 文档),可通过multipass set local.privileged-mounts=Yes等命令修改(支持on/off、yes/no、1/0、true/false及大小写变体)。
延伸阅读
- How to share data with an instance:完整的宿主机与实例数据共享实操,包含
transfer命令的用法。 - Mount 原理:classic 与 native 挂载的详细对比与安全说明。
- ID mapping:ID 映射的机制与一对一约束。
umount参考:卸载挂载的命令参考。launch参考:在创建实例时通过--mount定义挂载。local.privileged-mounts:控制mount是否被允许的设置项。
- 虚拟化
- 开发工具
- 云原生
【免费下载链接】multipass
Multipass orchestrates virtual Ubuntu instances
相关推荐
Multipass umount 命令完全指南:卸载主机与实例间的目录映射
Multipass umount 命令完全指南:卸载主机与实例间的目录映射 multipass umount 是 Multipass 中与 mount 命令成对
虚拟化开发工具云原生Multipass项目实例数据共享指南:mount与transfer命令详解
Multipass项目实例数据共享指南:mount与transfer命令详解 前言 Multipass作为轻量级虚拟机管理工具,提供了便捷的本地开发环境搭建方案
虚拟化开发工具云原生Multipass文件共享终极指南:mount命令与自动同步技巧全解析
Multipass文件共享终极指南:mount命令与自动同步技巧全解析 Multipass作为Ubuntu官方推出的轻量级虚拟机管理工具,其文件共享功能是开发者
虚拟化开发工具云原生
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考