默认隔离地交付和运行软件。
这是一个 CLI 工具,可让你:
# 安装(macOS + Linux)
curl -sSL https://smolmachines.com/install.sh | bash
# 供编码代理使用 — 安装并发现所有命令
curl -sSL https://smolmachines.com/install.sh | bash && smolvm --help
或者从 GitHub Releases 下载,并将其放入 ~/.local/share/。
Windows: 下载 windows-x86_64 版本(捆绑了 krun.dll + libkrunfw.dll),解压后运行 smolvm.exe。需要启用 Windows Hypervisor Platform(WHP)功能。
# 在临时虚拟机中运行命令(退出后清理)
smolvm machine run --net --image alpine -- sh -c "echo 'Hello world from a microVM' && uname -a"
# 交互式 shell
smolvm machine run --net -it --image alpine -- /bin/sh
# 在虚拟机内:apk add sl && sl && exit
Smolfile 用 TOML 声明一台机器 — 相当于 Dockerfile 或 cloud-init 文件,但针对的是整个虚拟机:镜像、资源、网络策略、挂载、端口和设置命令都集中在一个已检入的文件中。
image = "python:3.12-alpine"
net = true
cpus = 4
memory = 4096
ports = ["8000:8000", "5173-5180:5173-5180"]
volumes = ["./src:/app"]
init = ["pip install -r /app/requirements.txt"]
[network]
allow_hosts = ["api.stripe.com", "pypi.org"]
[auth]
ssh_agent = true
smolvm machine create --name myvm -s Smolfile # 或 --smolfile <PATH>
smolvm machine start --name myvm
端口映射接受单个端口("8080")、显式映射("8080:80")或等长的一对一范围("5173-5180:5173-5180")。一台机器最多可发布 64 个具体映射。
未知键会被拒绝而不是被忽略,因此拼写错误会在创建时失败,而不是静默地什么都不做。
常用键:image、cpus、memory、net、ports、volumes、env、
init、workdir、gpu、cuda、docker_socket、storage、overlay,以及
[network]、[dev]、、、、 表。
你不需要 Dockerfile 来保留环境。按你喜欢的方式设置一台机器 — 手动或通过 Smolfile — 然后将已停止的机器打包成 .smolmachine 工件并推送到任何 OCI 注册表:
smolvm machine shell --name myvm # 交互式安装和配置
smolvm machine stop --name myvm
smolvm pack create --from-vm myvm -o myvm
smolvm pack push --file myvm.smolmachine ghcr.io/you/myvm:v1
任何人都可以拉取它并启动完全相同的机器:
smolvm pack pull ghcr.io/you/myvm:v1
可用的 Smolfile 示例:python · node · docker-in-vm · local-llm · headless-browser · doom
沙箱化不可信代码 — 在硬件隔离的虚拟机中运行不可信程序。主机文件系统、网络和凭据通过虚拟机监控程序边界隔离。
# 网络默认关闭 — 不可信代码无法向外通信
smolvm machine run --image alpine -- nslookup example.com
# 失败 — 无网络访问
# 锁定出站流量 — 仅允许特定主机
smolvm machine run --net --image alpine --allow-host registry.npmjs.org -- wget -q -O /dev/null https://registry.npmjs.org
# 成功 — 允许的主机
smolvm machine run --net --image alpine --allow-host registry.npmjs.org -- wget -q -O /dev/null https://google.com
# 失败 — 不在允许列表中
打包为可移植可执行文件 — 将任何工作负载变成自包含的二进制文件。所有依赖项都已预烘焙 — 无需安装步骤、无需运行时下载、<200ms 内启动。
smolvm pack create --image python:3.12-alpine -o ./python312
./python312 run -- python3 --version
# Python 3.12.x — 隔离,无需 pyenv/venv/conda
使用本地容器镜像 — 适用于 CI、气隙主机和快速迭代。将 docker save / podman save 归档文件提供给 --image,通过 stdin 管道传入,或指向已解包的 rootfs 目录。镜像工作委托给你的容器工具;smolvm 只启动结果。
# 本地构建,在虚拟机中运行,无需推送/拉取
docker build -t myapp .
docker save myapp | smolvm machine run --image - -- ./app
# 从归档文件(无网络启动)
smolvm machine run --image ./myapp.tar -- ./app
# 从已解包的 rootfs 目录
smolvm machine run --image ./rootfs/ -- ./app
用于开发的持久化机器 — 创建、停止、启动。已安装的软件包在重启后仍然存在。
smolvm machine create --net --name myvm
smolvm machine start --name myvm
smolvm machine exec --name myvm -- apk add sl
smolvm machine exec --name myvm -it -- /bin/sh
# 内部:sl, ls, uname -a — 输入 'exit' 退出
smolvm machine stop --name myvm
使用 git 和 SSH,无需将私钥复制到客户机中。 将主机 SSH 代理转发到虚拟机中。只要 socket 可用,客户机就可以请求代理使用任何转发的密钥进行签名,因此只将其转发给你信任的工作负载。需要主机上运行 SSH 代理(用 ssh-add -l 检查)。
smolvm machine run --ssh-agent --net --image alpine -- sh -c "apk add -q openssh-client && ssh-add -l"
# 列出你的主机密钥;私钥材料保留在主机代理中
smolvm machine exec --name myvm -- git clone [email protected]:org/private-repo.git
在文件中声明环境 — 参见上面的 Smolfile,了解可复现的机器配置,以及如何将已配置的机器快照为可复用的 .smolmachine 镜像,而无需编写 Dockerfile。
每个工作负载都在一个硬件虚拟化的虚拟机中运行,拥有自己的客户机内核,基于 Hypervisor.framework(macOS)、KVM(Linux)或 Windows Hypervisor Platform(Windows)。libkrun 是 VMM,libkrunfw 提供客户机内核。将其打包成 .smolmachine,它就可以在主机架构匹配的任何地方运行,零依赖。
镜像使用 OCI 格式 — 与 Docker 使用的开放标准相同。Docker Hub、ghcr.io 或其他 OCI 注册表上的任何镜像都可以被拉取并作为微虚拟机启动。无需 Docker 守护进程。
默认配置:4 个 vCPU,8 GiB 内存。内存通过 virtio balloon 实现弹性 — 主机只提交客户机实际使用的内存,并自动回收其余部分。vCPU 线程在空闲时于虚拟机监控程序中休眠,因此超额配置的成本几乎为零。使用 --cpus 和 --mem 覆盖。
smolvm 通过为每个工作负载提供独立的虚拟机和客户机内核来强化客户机/主机边界。它本身并不是一个加固的多用户控制平面:
smolvm CLI 和 VMM 进程以调用主机用户的权限运行。该用户账户、主机操作系统、虚拟机监控程序后端、libkrun 和 smolvm 都属于可信计算基。--volume 传递的主机目录会按请求的访问权限有意暴露给客户机。不要将机密或敏感路径挂载到不可信的工作负载中。--ssh-agent 不会将私钥材料复制到客户机中,但它授予客户机访问转发代理 socket 的权限,因此在虚拟机运行期间能够请求签名。--net、端口转发或主机服务会扩大工作负载的可达面。将客户机中的 root 视为不可信。虚拟机边界限制了其对主机的直接访问,而每个显式转发的能力,包括挂载、网络访问、端口和 SSH 代理访问,都成为工作负载权限的一部分。
machine create 上的 --net)。仅支持 TCP/UDP,不支持 ICMP。/workspace(-v /host/dir:/workspace)优先于默认存储磁盘工作区 — 将使用你的主机目录。com.apple.security.hypervisor)签名。随附的发布版本已签名;重新签名或全新构建的二进制文件会静默丢失该权限,之后每次虚拟机启动都会失败并返回 krun_start_enter returned: -22 (EINVAL)。重新签名(临时签名即可):codesign --force --sign - --entitlements hv.entitlements <smolvm-bin>,其中 hv.entitlements 是包含 <key>com.apple.security.hypervisor</key><true/> 的 plist。--ssh-agent 需要主机上运行 SSH 代理(必须设置 SSH_AUTH_SOCK)。GPU=1 构建,并且主机上安装 virglrenderer + Vulkan 驱动(参见下面的 )。smolvm 通过 virtio-gpu / Venus(Vulkan-over-virtio)将主机 GPU 暴露给客户机。客户机工作负载会看到一个真实的 Vulkan 设备;在 Linux + Intel 上,渲染结果如下:
ANGLE (Intel, Vulkan 1.4 (Virtio-GPU Venus (Intel(R) UHD Graphics ...)), venus)
macOS — virglrenderer 和 MoltenVK 已捆绑在 smolvm 发行版中。无需额外安装。
Linux — 必须从系统包管理器安装 virglrenderer 和主机 Vulkan 驱动:
| 发行版 | 软件包 |
|---|---|
| Alpine | apk add virglrenderer mesa-vulkan-intel(AMD 使用 mesa-vulkan-ati) |
| Debian/Ubuntu | apt install virglrenderer0 mesa-vulkan-drivers |
virglrenderer 依赖主机 GPU 驱动栈中的 libEGL 和 libdrm — 这些是硬件特定的,无法捆绑。任何支持 GPU 的 Linux 主机都会通过其 GPU 驱动安装它们。
# CLI
smolvm machine run --gpu --image alpine -- vulkaninfo --summary
# Smolfile
# gpu = true
# gpu_vram = 2048 # MiB,默认 4096
客户机 Vulkan 加载器必须指向 virtio ICD:
export VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/virtio_icd.x86_64.json
参见 examples/headless-browser/,了解在无头虚拟机中使用 ANGLE + Venus 实现硬件加速 WebGL 的可运行 Chromium 配置。
--gpu 和 --cuda 提供不同的接口。--gpu 通过 virtio-gpu / Venus 暴露 Vulkan;它不提供 CUDA。--cuda 启用 CUDA API 远程调用:无驱动的客户机垫片通过 vsock 将 CUDA 调用转发到主机进程,由主机进程通过主机的 NVIDIA 驱动执行。
CUDA 远程调用需要主机上有 NVIDIA GPU 和可用的 NVIDIA 驱动。它不是 GPU 直通:客户机既不会收到物理设备,也不会收到 NVIDIA 驱动。
Fork 密集型的 Linux 主机应使用包含上游 KVM 修复
916b7f4 的内核。
受影响的内核即使在主机内存充足的情况下,也可能在首次 KVM_RUN 时间歇性报告 ENOMEM;smolvm 会降低暴露风险并替换失败的 worker,
但内核更新才是最终修复方案。
虚拟机边界仍然隔离工作负载的 CPU、内存和文件系统。GPU 访问由主机进程和共享的主机 GPU 中介,因此 GPU 隔离仍处于进程级,而非硬件或虚拟机边界。不要将 CUDA 远程调用视为加固的多租户 GPU 隔离边界。
参见 GPU access by API remoting: how a driverless microVM runs CUDA,了解设计、权衡以及与直通的对比。
Apache-2.0 · 由 @binsquare 制作 · twitter · github
[auth][health][restart][service]| smolvm | 容器 | Colima | QEMU | Firecracker | Kata |
|---|
| 工作负载边界 | VM + 客户机内核 | 命名空间 + 共享内核 | 共享虚拟机内的命名空间 | VM + 客户机内核 | VM + 客户机内核 | 每容器一个 VM |
| 启动时间 | <200ms | ~100ms | ~秒级 | ~15-30s | <125ms | ~500ms |
| 架构 | 库(libkrun) | 守护进程 | 守护进程(虚拟机内) | 进程 | 进程 | 运行时栈 |
| 每工作负载 VM | 是 | 否 | 否(共享) | 是 | 是 | 是 |
| macOS 原生 | 是 | 通过 Docker VM | 是(krunkit) | 是 | 否 | 否 |
| 可嵌入 SDK | 是 | 否 | 否 | 否 | 否 | 否 |
| 可移植工件 | .smolmachine | 镜像(需要守护进程) | 否 | 否 | 否 | 否 |
| 主机 | 客户机 | 要求 |
|---|
| macOS Apple Silicon | arm64 Linux | macOS 11+ |
| macOS Intel | x86_64 Linux | macOS 11+(未测试) |
| Linux x86_64 | x86_64 Linux | KVM(/dev/kvm) |
| Linux aarch64 | aarch64 Linux | KVM(/dev/kvm) |
| Windows x86_64 | x86_64 Linux | 已启用 Windows Hypervisor Platform(WHP) |
--net 与其他平台的工作方式相同(virtio-net 带入站端口转发;仅出站 VM 使用 TSI),machine exec / 交互式会话和 machine stats 也是如此。Windows 上尚不可用:GPU 加速和 machine fork / 快照。Pack create 需要 smolvm.exe 旁边的 storage-template.ext4 / overlay-template.ext4(Windows 没有主机 mkfs.ext4)。