声明
本文由 🤖AI 协作完成, 内容已过实际测试.
Gondolin 是一个轻量级的沙盒虚拟机方案,基于 libkrun 和 QEMU 提供快速启动的隔离执行环境。最近项目中有需要定制沙盒镜像的需求,调研了一下 Gondolin 的自定义镜像流程,记录如下。
1. 背景
Gondolin 默认提供了一些基础镜像,但实际使用中往往需要预装特定依赖。比如我们需要一个同时内置 Node.js 和 Python 3 的运行环境,以便在沙盒中直接执行脚本,而不每次都重新安装依赖。
Gondolin 的自定义镜像构建目前支持 Alpine 发行版,也可以通过 OCI 镜像(如 Debian)作为 rootfs 基础。构建产物包括内核、initramfs 和 rootfs,可以直接通过 CLI 或 SDK 使用。
2. 前置准备
在 macOS 上构建自定义镜像需要安装以下工具:
1 | brew install lz4 e2fsprogs |
确保 mke2fs 在 PATH 上:
1 | export PATH="$(brew --prefix e2fsprogs)/sbin:$PATH" |
全局安装 Gondolin CLI:
1 | npm install -g @earendil-works/gondolin |
Docker 仅在配置了
postBuild.commands或跨架构构建时才会自动使用。如果只是简单镜像,不需要安装 Docker。
3. 镜像构建
3.1 配置
创建 build-config.json:
1 | { |
关键字段说明:
| 字段 | 说明 |
|---|---|
arch |
目标架构,aarch64(Apple Silicon)或 x86_64(Intel) |
distro |
发行版,目前仅支持 alpine |
alpine.rootfsPackages |
安装到 rootfs 的 Alpine 包 |
postBuild.commands |
构建后执行的命令 |
postBuild.copy |
将主机文件复制到 guest rootfs |
oci.image |
使用 OCI 镜像作为 rootfs 基础 |
3.2 执行构建
1 | gondolin build --config build-config.json --output ./assets |
构建成功后输出类似:
1 | Build successful! |
构建产物:
1 | assets/ |
3.3 快速验证
使用 build ID 直接启动:
1 | GONDOLIN_GUEST_DIR=./assets gondolin bash -- node --version && python3 --version |
4. SDK 使用
4.1 基础用法
安装依赖:
1 | npm install @earendil-works/gondolin |
创建并执行 VM:
1 | import { VM } from "@earendil-works/gondolin"; |
4.2 执行命令
vm.exec() 支持两种形式:
1 | // 字符串形式:通过 /bin/sh -lc 执行(支持管道、变量等) |
4.3 imagePath 的三种方式
| 方式 | 示例 | 说明 |
|---|---|---|
| Build ID | "e3dbcc39-fd6e-56a3-ba30-cfa90e106a38" |
使用本地镜像仓库中的构建 |
| 路径 | "./assets" |
指向包含 manifest.json 的目录 |
| 显式对象 | { kernelPath, initrdPath, rootfsPath } |
直接指定各文件路径 |
4.4 手动启动控制
1 | const vm = await VM.create({ |
4.5 文件系统操作
SDK 提供了简化的 guest 文件系统 API:
1 | // 读写文件 |
4.6 流式输出
对于长时间运行的命令,可以使用流式输出:
1 | const proc = vm.exec("for i in 1 2 3; do echo $i; sleep 1; done", { |
4.7 交互式 Shell
1 | const result = await vm.shell(); |
4.8 SSH 与 Ingress
需要交互式调试或暴露服务时:
1 | // SSH |
5. 常用配置示例
预装 Python 包:
1 | { |
使用 OCI 镜像(Debian):
1 | { |
OCI 构建时
alpine.rootfsPackages被忽略,rootfs 来自 OCI 镜像,但 boot 层仍由 Alpine 提供。
固定 rootfs 大小:
1 | { |
6. 踩坑记录
mke2fs: command not found——brew install e2fsprogs后需要手动加 PATH。- 容器构建失败 —— macOS 上
postBuild.commands会自动触发 Docker。如果不需要 post-build 步骤,直接移除postBuild即可原生构建。 - 架构不匹配 —— Apple Silicon 用
aarch64,Intel 用x86_64。跨架构构建需要 Docker:1
gondolin build --arch x86_64 --config build-config.json --output ./x64-assets