展示 HN: Kern – 容器与资源运行时,1.5 MB 二进制文件,无守护进程
摘要
Kern 是一个极简、快速的容器与资源运行时,在一个 1.52 MB 的二进制文件中提供无根沙箱和资源管理,无需守护进程。
查看缓存全文
缓存时间: 2026/08/24 19:50
getkern/kern 源代码:https://github.com/getkern/kern
kern: 为任意工作负载(包括不受信任和 AI 生成的代码)提供的快速、无 root 权限的沙箱及虚拟资源运行时。
一个真正的、内核强制的容器,启动约需 3.5 毫秒,仅由一个 1.52 MB 的二进制文件实现,无需守护进程。
静态时内存占用为 0 · 无守护进程、无套接字、无需启动任何服务 · 一个静态二进制文件,其唯一的 Rust 依赖是 libc
CI (https://github.com/getkern/kern/actions/workflows/ci.yml)
许可证:Apache-2.0
平台%20%C2%B7%20ARM%20开发板-informational.svg)
# 安装发行版二进制文件(静态,1.52 MB,脚本验证校验和)
curl -fsSL https://raw.githubusercontent.com/getkern/kern/main/install.sh | sh
# 在真实的 OCI 镜像中启动一个一次性 shell:无 root 权限、内核强制、耗时几毫秒
kern box dev --image alpine -it -- sh
不支持原生 Windows:请使用 WSL2。安装。
kern 是什么
一个二进制文件管理资源,其中隔离是首要任务。 这就是为什么在比较表中 kern 没有单独的一行:它同时是一个容器运行时、一个沙箱、一个资源切片器和一个栈运行器,仅 1.52 MB,无需守护进程。
- 一个真正的容器。 真实的 OCI 镜像:支持
pull、从 Dockerfilebuild、commit、push、save/load。从镜像启动一个 box 约需 3.5 毫秒。 - 一个沙箱,始终无 root 权限。 用户、PID、挂载点、网络、UTS 和 IPC 命名空间,overlay 或只读根文件系统作为根,一个默认拒绝的 seccomp 白名单和 cgroup v2 限制。一个标志
--security-profile untrusted就是整个强化包。 - 资源配置文件,而不仅仅是隔离。 CPU (
vcpu:)、内存、磁盘 (vdisk:) 和设备 (vgpio:),在kern.toml中声明一次,然后按名称附加。kern run可将相同的资源上限应用于宿主机上的进程,且完全无需沙箱。docs/RESOURCES.md - 栈,使用 kern 自有格式或 Docker 格式。
kern compose up可接受kern-compose.toml(使用上述资源文件的[box.NAME]表)或你已有的docker-compose.yml,无需转换步骤。一个栈对应一个 Pod,服务之间可通过名称相互访问。 - 配套工具。
ps、logs、exec、stats、inspect、wait、top(一个实时 TUI)、doctor,另外还有 Python 和 Node SDK 以及一个供智能体使用的 MCP 服务器。其完整的 Rust 依赖树仅有libc:JSON 和 OCI 清单是手动解析的,pull则通过 shell 调用系统已有的curl和tar,而不是链接一个 TLS 栈。(1.52 MB 是优化后的发行版构建大小;从源代码直接执行cargo install生成的大小为 1.91 MB。)
kern 不是什么
- 不是虚拟机管理程序。 边界是 Linux 内核,因此内核权限提升漏洞即可逃逸。Docker 和 Podman 同样存在此问题,这也是 gVisor 和 Firecracker 存在的原因。结合标语来理解,这是从两方面看的同一行文字:不受信任和 AI 生成的代码正是 kern 的目标用途,因为你选择运行它们并承担其影响范围(智能体工具调用、CI 任务、构建步骤、代码单元)。它不适用于来自陌生人的恶意代码、多租户环境,或者你用于服务其他租户的内核。kern 始终以无 root 权限启动,而 Docker 的无 root 模式是可选的。
- 并非完全摆脱了用户命名空间的权衡。 其隔离构建于非特权用户命名空间之上,这是内核本地权限提升漏洞的一个主要来源。SECURITY.md 在任何声明之前都阐明了这一点。
- 不是你挂载内容周围的围墙。
-v $HOME:/host会将你的主目录提供给 box:挂载点是你做出的信任决策,而不是 kern 强制执行的边界。--net host和--privileged是明确的退出选项。(kern 拒绝绑定的唯一路径是其自身的运行时注册表。) - 不是 Docker 引擎的重实现。 它使用 Docker 的格式,而非其 API:没有 overlay 网络,没有插件,没有 Swarm。兼容矩阵:docs/DOCKER-COMPAT.md。
- 不是 Kubernetes 运行时。 没有 CRI。请使用 containerd 或 CRI-O。
- 尚未提供 GPU 切片。 在路线图上,此版本中没有 GPU 相关代码,因此目前没有可信任或可攻击的内容。其未知或尚未完成的功能记录在 OPEN_ITEMS.md 中,而不是留待你自行发现。
安装
kern 需要支持非特权用户命名空间和 cgroup v2 的 Linux 内核。它可在 Linux、WSL2 和 ARM 开发板(Raspberry Pi · Jetson · Arduino UNO Q)上运行;没有原生 Windows 构建版本,请使用 WSL2(kern 提供预构建的 WSL rootfs)。
最快的方式是使用发行版二进制文件:一个静态文件,无需工具链,脚本会在安装前验证其 SHA256 校验和。
curl -fsSL https://raw.githubusercontent.com/getkern/kern/main/install.sh | sh
它会为你自动选择 x86_64 或 aarch64,安装到 ~/.local/bin(以 root 身份则为 /usr/local/bin,或由 KERN_INSTALL_DIR 指定),并拒绝安装校验和不匹配的下载文件。
手动验证只需两行命令:
curl -fsSLO https://github.com/getkern/kern/releases/latest/download/kern-x86_64-unknown-linux-musl.tar.gz{,.sha256}
sha256sum -c kern-x86_64-unknown-linux-musl.tar.gz.sha256 && tar xzf kern-x86_64-unknown-linux-musl.tar.gz
从源代码构建是另一种方式,整个依赖树仅有一个 crate(libc),因此过程很短:在桌面机(i7-14700KF)上克隆、构建和安装耗时约 36 秒,在小型 ARM 开发板上则更长。
# 如果你还没有 Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
cargo install --git https://github.com/getkern/kern getkern --locked
这会将 kern 放入 ~/.cargo/bin,rustup 会将其添加到你的 PATH(如果找不到 kern,请打开新 shell 或执行 source "$HOME/.cargo/env")。
发行版还包括一个 aarch64 二进制文件、一个 Windows .exe 引导文件和一个预构建的 WSL rootfs,每个都有自己的 .sha256 校验和文件;标签经过 GPG 签名并带有独立时间戳(provenance/)。
kern doctor 可以在你尝试之前告诉你 box 是否能在这里运行。
开发板、WSL2 和完整说明:docs/INSTALL.md。
常见问题(Docker、bubblewrap、youki、E2B、Windows、威胁模型):docs/FAQ.md。
快速入门
kern box dev --image alpine -it -- sh # 在一个真实的 OCI 镜像中启动一次性 shell
kern run --memory 256M --cpus 0.5 -- ./crunch # 对进程设置资源上限,无沙箱
kern box svc --image nginx:alpine -d -p 8080:80 \ # 一个服务:发布、重启、健康检查
--restart --health-cmd 'wget -qO- localhost:80' -- nginx -g 'daemon off;'
kern ps # 查看运行状态,包括端口和健康状况
kern exec svc -it -- sh # 连接到服务 shell
kern stop svc # 发送信号,优雅等待,然后记录退出码
kern top # 实时 TUI:查看 box、CPU/内存、配置文件、卷
kern compose stack.toml up # 启动一个多 box 栈(示例在 examples/ 目录)
kern compose stack.toml down # 停止该栈
不受信任的代码,一个标志即整个安全包:
kern box job --image python:3.12-slim --security-profile untrusted --memory 256m \
-v ./job:/w -- python3 /w/x.py
--security-profile untrusted 是 seccomp 白名单 + --cap-drop ALL + --read-only 的合一可选标志(如果你愿意,也可以手动列出);加上 --require-limits 可确保除非内存/进程限制确实生效,否则拒绝启动。除非请求,否则无网络,危险能力被丢弃,seccomp 始终开启。
九十个可运行的示例,每个做一件事:examples/。
每个读取命令也支持 JSON 输出,无需解析表格:
kern ps --json | jq '.[] | select(.health == "unhealthy") | .name'
kern volume ls --json # ps · images · stats · inspect · builds · pod ls · config list · diff
你的 Docker Compose 栈,无需 Docker Desktop
kern 说 docker-compose.yml 语言。将其指向你已有的栈,kern compose up 即可运行它,无需守护进程,无需 Docker Desktop,在 Linux、WSL2 和 ARM 开板上体验一致。
# compose.yaml - 一个真实的栈,无需修改
services:
db:
image: postgres:alpine
environment: { POSTGRES_PASSWORD: secret, POSTGRES_DB: app }
web:
image: adminer
ports: ["8080:8080"]
depends_on: [db]
kern compose compose.yaml up
两个官方镜像启动,web 通过服务名访问 db,端口发布到宿主机。预热(镜像已缓存)后,Web 层在 ~0.3 秒内就绪,栈仅消耗 postgres 和 adminer 实际使用的资源(此处约 66 MB),零守护进程开销,而 Docker Desktop 在启动第一个容器前就需要一个后台虚拟机。
使用非 root 用户运行的官方镜像(postgres、redis 等)需要 uidmap 和 /etc/subuid 中的一行配置;出站镜像拉取需要 pasta;这两者在开发机上通过 apt install 即可安装,kern doctor 会指出缺少哪个。
这是本地开发循环,而非生产编排器:没有 Swarm,没有 overlay 网络。
嵌入使用:Python 与 Node
从你自己的程序中运行智能体或 LLM 生成的代码,可使用 kern-sandbox,这是对 kern 二进制文件的轻量、无依赖封装。每次调用都在一个全新的隔离 box 中运行:网络关闭、内存和 pid 限制、能力丢弃、输出有界,并且封装本身强制执行超时。
pip install kern-sandbox # PyPI · 需要上述 `kern` 二进制文件在 PATH 或 $KERN_BIN 中
npm install kern-sandbox # npm · 同理
from kern_sandbox import run_code
r = run_code("import platform; print(platform.python_version())")
print(r.stdout) # 在全新 box 中运行;超时/内存不足/阻塞的逃逸信息在 r.fault 中
- 故障是数据,而非异常:超时、内存不足终止或阻塞系统调用是结果的一个字段,而非抛出异常。
- 默认每次调用使用全新 box;
Sandbox可在调用间保持工作空间,预热的kernel()则保持一个解释器用于亚毫秒级单元(隔离性较弱,但这是可选的)。 - 无需 Jupyter 内核即可获得丰富结果:最后一个表达式、
display()调用和 matplotlib 图形都会被捕获并返回,如同笔记本单元格。
附带一个 MCP 服务器(kern-mcp):一个无依赖的 stdio 服务器,为 Claude Desktop、Cursor 或任何 MCP 客户端提供本地代码解释器。将客户端指向它:
{
"mcpServers": {
"kern": {
"command": "kern-mcp"
}
}
}
工具:run_code(python/bash/node)、write_file、read_file、list_files。每次调用都是一个网络关闭的新 box;文件在磁盘上的工作空间中跨调用持久化。设置命令、镜像和其他选项:bindings/python/README.md。
完整 API,Python 与 Node:bindings/python/README.md · bindings/node/README.md。
资源配置文件
资源切片在 ~/.config/kern/kern.toml 中声明一次,然后按名称附加到沙箱化的 box 或裸进程,使用相同的令牌。三种类型:vcpu:(CPU 和内存)、vdisk:(大小受限的临时磁盘)和 vgpio:(设备节点)。以下是其中两种及其基准来源:
[[cpu]] # 用于切片的主机预算
id = "cpu:0"
cores = 8.0
[[vcpu]] # 1.5 核 512 MiB -> 附加为 vcpu:heavy
name = "heavy"
backend = "cpu:0"
cpus = 1.5
memory = "512m"
[[gpio]] # 控制器基准
id = "gpio:0"
[[vgpio]] # 精确一个设备节点 -> 附加为 vgpio:sensor
name = "sensor"
backend = "gpio:0"
i2c = ["/dev/i2c-1"]
kern validate ~/.config/kern/kern.toml # 在运行任何程序前验证配置
kern box train --image alpine vcpu:heavy vdisk:scratch -- ./train.sh
kern run vcpu:heavy -- ./train.sh # 同样的切片,无沙箱
kern box iot --image alpine vgpio:sensor -- ls /dev
配置文件可组合:多个可附加到一个 box,显式标志优先于配置文件自身的值。每个键的命名与其 CLI 标志一致,因此 cpus 对应 --cpus,memory 对应 --memory。如果配置中引用了未声明的池,会在读取配置时拒绝,而非在 box 运行时。
docs/RESOURCES.md 有逐字段的模式说明。
当 kern 以无 root 权限运行时,vdisk: 是基于 RAM 的 tmpfs,无论其 backend 如何声明;当以特权模式运行时,则是带有真实配额的 ext4-on-loop 镜像。kern 会告知你每个配置文件实际得到的是哪种类型,而非让你猜测,并且无论哪种情况都会强制执行大小限制。
vgpio: 是芯片粒度的,而非按行。 请求 pins 会绑定整个 /dev/gpiochipN,该字符设备暴露该控制器的所有行。pins = [17] 并不将 box 限制在第 17 行:内核没有按行的挂载边界,因此引脚列表是协作性元数据,而非边界。命名一个设备节点,如上面的 i2c 所示,则只授予该节点而非其他。
kern 对比 Docker 对比 Podman
| kern | Docker | Podman | |
|---|---|---|---|
| 守护进程 | 无 | 是(dockerd + containerd) | 无 |
| 无 root 权限 | 是,始终 | 可选 | 是 |
| 冷启动,裸 box | ~2.3 ms | ~297 ms | ~293 ms |
| 冷启动,从 OCI 镜像 | ~3.5 ms | ~297 ms | ~293 ms |
| 停止服务(init 处理 SIGTERM) | ~1.9 ms | ~310 ms | ~380 ms |
| 常驻内存,无运行任务 | 0 | 154 至 160 MB | 0 |
| 占用空间 | 一个 1.52 MB 二进制文件 | 守护进程堆栈 | 多二进制安装 |
| OCI 镜像,pull / build / push | 是 | 是 | 是 |
docker-compose.yml | 是,直接读取 | 是 | 部分支持 |
| Overlay 网络、Swarm、CRI | 无 | 是 | 部分支持 |
| GPU | 在路线图上 | 是 | 是 |
性能
Intel i7-14700KF,Linux 7.0.0,发行版二进制文件,运行你也可执行的脚本:python3 examples/benchmark.py。你的结果会因 CPU、内核和文件系统而异。
| kern | bubblewrap | runc | podman | docker | |
|---|---|---|---|---|---|
| 冷启动(裸 box) | ~2.3 ms | ~2.3 ms | ~18.6 ms | ~293 ms | ~297 ms |
| 并行启动 200 个 box | ~0.11 s | ~0.16 s | ~0.35 s | ~44.8 s | ~16.2 s |
同时启动三千个约需 2.2 秒,一个运行中的 box 内存占用约 0.3 MB。
两点说明。
没有人能在单次启动延迟上绝对胜出:unshare + exec 的底层极限是 1 到 2 毫秒,因此整个顶级梯队都在自身的噪声范围内,而 bubblewrap 是一个没有镜像、能力或生命周期的启动器。有意义的差距在于与引擎相比,它们高出了两个数量级。
方法、分阶段分解、开发板数据及所有注意事项:BENCHMARKS.md。
安全
命名空间、一个 pivot_root、在 exec 前丢弃 16 种危险能力、一个始终开启的 seccomp 白名单(默认采用 moby 自身的默认过滤器,减去 kern 的 35 个逃逸系统调用,这些调用被硬性终止;集合外的系统调用返回 ENOSYS,更广泛的拒绝列表可通过 KERN_SECCOMP=denylist 选择退出)、cgroup v2 限制(--require-limits 确保除非绑定否则拒绝启动),以及一个默认拒绝的 /dev。
在边界是协作性而非内核强制的地方,SECURITY.md 会说明并指出绕过方式。你无需盲目信任:pentest/ 包含四套对抗性测试套件,用于针对内核(而非 kern 自身报告)断言这些边界,并且无需注册表账户或网络即可运行。
sh pentest/run-with-local-registry.sh ./target/release/kern
pentest/pentest-ports.sh
通过 GitHub Security Advisories 或 [email protected] 私下报告漏洞。
文档
| | |—|—|—|
| docs/INSTALL.md | 在 Linux、WSL2 和 ARM 开发板上安装(从源代码) |
| docs/DOCKER-COMPAT.md | Docker 哪些能用,哪些不能,以及差异之处 |
| docs/RESOURCES.md · docs/CONFIG.md · docs/STORAGE.md · docs/EGRESS.md | 双动词模型、kern.toml 模式、卷和出口 |
| docs/THREAT_MODEL.md · SECURITY.md · OPEN_ITEMS.md | 威胁模型(结构化,然后按机制),以及已知缺口 |
| BENCHMARKS.md · EDGE.md | 测量数据,以及在 Pi、Jetson 或 UNO Q 上运行 |
| examples/ · blog/ | 九十个可运行脚本,以及更长的文章 |
| bindings/python/README.md · bindings/node/README.md | kern-sandbox SDK:将 kern 嵌入 Python 或 Node |
状态
相似文章
Show HN: Z-Jail – 一个130KB的Linux沙箱-C99,具有7层防御且无依赖项
Z-Jail 是一个轻量级Linux沙箱,采用C99编写,拥有七层防御、无外部依赖,且二进制文件极小(约130 KiB),专为CI、CTF和轻量级评估中的安全代码执行而设计。
Show HN:Kakehashi —— 在 Linux ARM 上运行 macOS 二进制的实验性用户空间
Kakehashi 是一个实验性用户空间,它通过加载 Mach-O 文件、映射独立的 libSystem 以及转换 BSD 系统调用,将 macOS ARM64 二进制文件转换为可在 Linux aarch64 上运行。目前它支持通过 Docker 或 UTM 在 Linux ARM 上运行诸如 7-Zip 和 curl 等工具,包括多线程操作。
仅运行NES模拟器的内核
一个旨在无需任何操作系统的情况下运行NES模拟器的最小化内核,并附带像Mandelbrot分形可视化这样的额外程序。
Show HN:一个CLI实现本地文本、图像、视频、音乐和3D,无需Python
mere.run 是一个面向Apple Silicon和无头Linux的本地优先推理运行时,提供单一CLI用于文本、图像、视频、音乐、3D等,无需Python。
Launch HN: Runtime (YC P26) – 面向团队所有人的沙箱编码代理
Runtime 是一个平台,提供带有公司上下文、集成和安全护栏的沙箱编码代理,让每个团队成员都能使用代理自动执行任务并交付工作。它包含自定义环境、专用代理、可观察性,并支持各种集成和部署选项。