Kern 是一个极简、极速的容器与资源运行时。它的核心特点是无守护进程、体积极小(单个静态二进制文件仅 1.52 MB)且启动极快(从 OCI 镜像启动一个容器仅需约 3.5 毫秒)。
它专为运行包括不可信和 AI 生成代码在内的各种工作负载而设计,旨在提供一个轻量级、安全的沙箱环境。
核心特性
- 真正的 OCI 容器:完全兼容 OCI(Open Container Initiative)标准,支持 pull、build、commit、push 等完整生命周期操作。
- 始终无根的沙箱:利用 Linux 内核的命名空间(User, PID, Mount, Network, UTS, IPC)和 cgroup v2 实现资源隔离。通过 --security-profile untrusted 等标志可启用更严格的 seccomp 白名单等安全加固。
- 资源管理:支持在配置文件中声明 CPU(vcpu)、内存、磁盘(vdisk)和设备(vgpio)等虚拟资源,并可灵活附加到不同任务。
- 支持 Docker Compose:能直接运行 docker-compose.yml 或自身的 kern-compose.toml 文件来管理多容器应用栈,无需格式转换。
- 丰富的工具链:提供了 ps, logs, exec, stats, inspect, top(实时 TUI 界面)等命令行工具,以及 Python 和 Node.js 的 SDK。
技术架构与设计哲学
- 极简主义:项目刻意追求小巧和快速。整个 Rust 项目的依赖树仅包含 libc,JSON 和 OCI 清单解析等均由手工实现。网络请求(如 pull)则直接调用系统自带的 curl 和 tar,而非引入庞大的 TLS 库。
- 边界清晰:Kern 的安全边界是 Linux 内核本身。这意味着它并非一个全功能的虚拟机监控器(Hypervisor),其安全性取决于 Linux 内核本身的安全性。
- 设计目标明确:Kern 是为运行“你选择运行并愿意承担后果的代码”而设计的,例如 Agent 工具调用、CI 任务、构建步骤或代码单元格(Code Cells)。它不适合运行来自陌生人的、具有敌意的多租户代码。
介绍
Kern:1.5MB的二进制文件,3.5毫秒启动一个真容器,还要什么Docker!
你跑一个Docker容器之前,得先跑一个上百MB的守护进程。
这听起来像什么?像你想开一辆车,得先启动一座发电厂。Docker的dockerd守护进程,就是那座发电厂。它常驻内存,什么都不干的时候也要吃掉一两百MB,你每敲一次docker run,命令得先跟这座发电厂打个招呼,发电厂再帮你干活。这套架构从2013年一直用到今天,所有人都习惯了。
但有个叫Kern的东西,把这座发电厂拆了。一个1.52MB的静态二进制文件,没有守护进程,没有后台服务,没有常驻内存的socket。你敲命令,它干活,干完消失。从OCI镜像启动一个真正的容器,全程只要3.5毫秒。
3.5毫秒是什么概念?你眨一下眼睛要100到150毫秒。Kern启动一个容器的时间,是你眨眼时间的三十五分之一。这不是优化,这是重写游戏规则。
你跑的不是容器,是Docker自己
很多人以为自己跑的是容器,其实跑的是Docker。
来,拆开看看Docker到底在干什么。你输入docker run,这个命令先通过REST API发给dockerd守护进程。dockerd收到请求,再去调用containerd,containerd再去调用runc,runc才真正去跟Linux内核打交道,创建命名空间、设置cgroup、启动进程。这一圈转下来,中间隔了至少三层。每一层都有开销,每一层都是延迟,每一层都可能出问题。
dockerd挂了,所有容器都失控。空载的时候它占着内存不干活,有任务的时候它成了唯一的入口,所有操作堵在一条道上。这不叫架构,这叫瓶颈。
Kern把这一整条调用链砍成了一刀。它的整个Rust依赖树只有一个东西:libc。JSON解析?自己手写。OCI清单解析?自己手写。连网络请求都不链接TLS库,直接调用系统里现成的curl和tar。1.52MB的二进制,静态编译,拷到哪用到哪,连安装都不用。
这就怪了。一个1.52MB的东西,凭什么干Docker上百MB才能干的事?
容器本来就不需要那么大
因为容器技术的内核,从来不在Docker那里。
容器本质上就三样东西:Linux命名空间做隔离、cgroup做资源限制、文件系统做根目录切换。这三样全是内核提供的功能。Docker也好,Podman也好,Kern也好,都只是这些内核功能的“调用者”而已。
Kern只是把调用这件事做到了极致。
它用User命名空间确保永远以非root权限运行。用PID、mount、network、UTS、IPC命名空间做完整隔离。用overlay或只读根目录做文件系统隔离。用seccomp做系统调用白名单,默认就是“拒绝所有,只放行必要的”。用cgroup v2做CPU、内存、磁盘的精确限制。你加一个--security-profile untrusted,整套安全加固就全开了。
所有这些,一个1.52MB的二进制文件全包了。不是因为它做了什么别人做不到的事,而是因为它只做必要的事。不加层,不转手,不绕路。
但事情没那么简单!
安全边界只有一层,也只剩一层
Kern的README里有一句话,写得特别诚实:“边界就是Linux内核本身”。
什么意思?容器的隔离不是虚拟机的隔离。虚拟机有自己的内核,容器跟宿主机共享一个内核。内核里有一个漏洞,容器就能逃逸到宿主机。这不是Kern的问题,这是所有基于命名空间的容器技术共同的命门。Docker和Podman也一样。
但区别在于,Docker的架构里,即便内核没漏洞,你还有dockerd这个攻击面。守护进程本身跑着root权限,本身就有漏洞历史。Kern把这一层也砍了。没有守护进程可攻击,没有常驻socket可穿透。你的攻击面,只剩Linux内核。
这到底是更安全了,还是更危险了?
看你怎么定义“安全”。如果你的威胁模型是“有人想通过容器逃逸漏洞搞掉宿主机”,那Kern和Docker站在同一条起跑线上——都依赖内核没bug。但2026年5月刚爆出来的CVE-2026-31431“Copy Fail”,一个732字节的漏洞让任何本地用户都能拿到root权限。同月还有另一个内核漏洞被披露。内核永远有bug。这是事实。
那Kern到底在保护什么?保护你的宿主机不被容器里跑的代码吃掉所有CPU和内存。保护你的临时任务不会留下一个常驻的守护进程占用资源。保护你的CI脚本、AI生成的代码、一次性构建任务,跑完就消失,不拖泥带水。
它不承诺“绝对隔离”。它承诺的是“你想跑什么就跑什么,但后果你自己承担”。
谁需要3.5毫秒的容器?
你写了一个AI Agent,它要调一个工具,工具要跑一段代码。每次调用都启动一个完整的OCI容器——用Docker的话,光跟守护进程握手就要几百毫秒。加上镜像拉取、容器初始化,一个来回好几秒。Agent等着,用户等着,体验稀碎。
用Kern呢?3.5毫秒。一个Agent调用链上跑几十个容器,总延迟还比不上Docker启动一个。这不是快一点,这是从“不能用”变成了“随便用”。
你写CI流水线,每个构建步骤都想要干净的隔离环境。Docker in Docker那套东西,重得让人想骂人。Kern一个二进制拷进镜像,每条命令直接跑隔离容器,没有守护进程、没有嵌套、没有额外开销。
你在边缘设备上跑容器。树莓派、工业网关、嵌入式Linux,内存按兆算,CPU按核心算。Docker的守护进程上去就吃掉四分之一资源。Kern的二进制1.52MB,跑完就释放,不占一丝一毫。
你写代码的时候想快速测试一个镜像能不能跑。不用等Docker daemon启动,不用等容器初始化。kern box dev --image alpine -it -- sh,回车,shell出来了。
这些场景的共同点是什么?都是“用完就走”的任务。不持久、不集群、不编排。Kern的README里写得明明白白:“不是Kubernetes运行时。没有CRI。用containerd或CRI-O去干那些事”。它不抢K8s的饭碗,它抢的是你每次敲docker run时那几百毫秒的等待。
兼容OCI,但不兼容你的习惯
Kern能pull OCI镜像、能build、能commit、能push、能save和load。一个alpine镜像,kern pull下来,kern box跑起来,跟Docker没区别。它还能读docker-compose.yml,不用转换格式直接up。
但别高兴太早。
Kern的CLI跟Docker不一样。没有docker ps那种全家桶式的命令集,它有ps、logs、exec、stats、inspect、wait、top。够用,但不完全一样。你得重新学一遍。
而且Kern有一个设计选择会让很多人不舒服:pull镜像的时候,它不自己实现TLS和HTTP客户端,而是直接调用系统的curl和tar。这意味着你的机器上得有curl,得能访问镜像仓库的网络。这在容器化的CI环境里可能是个坑——你的构建镜像里未必装了curl。
这种“用手边工具凑”的思路,贯穿了整个项目。它是极简主义的胜利,也是实用主义的妥协。你接受这套哲学,就觉得它聪明得不行。你不接受,就觉得它简陋得离谱。
Rust写的,但Rust不是重点
Kern用Rust写的。但这篇文章不准备花太多篇幅吹Rust。用Rust写容器运行时的项目多了去了:youki是一个,Pelagos是一个,Kata Containers 4.0的runtime-rs也是Rust重写的。Rust的内存安全特性确实让这类底层系统软件更可靠,但Kern的亮点不在语言,在架构。
真正的亮点是什么?是整个项目的依赖树只有libc。这意味着什么?意味着你cargo build出来的是一个几乎不依赖任何第三方库的静态二进制。意味着没有openssl的漏洞需要担心,没有serde的版本冲突需要处理,没有tokio的异步运行时需要调优。意味着这个二进制可以拷到任何glibc兼容的Linux上直接跑。
一个容器运行时,不依赖任何容器相关的库。这本身就是一个反常识的设计决策。
大多数项目的做法是:我要做容器运行时,好,我先引入containerd的依赖,或者至少引入runc的库,或者用OCI的参考实现。Kern的做法是:OCI规范是一份文档,我照着文档自己写解析器。JSON是一种格式,我手写一个够用的解析器。TLS太复杂了,我不链接,我调用系统的curl。
这种“能不依赖就不依赖”的偏执,把二进制体积压到了1.52MB。你从源码cargo install出来是1.91MB,因为release build用了nightly Rust和optimize_for_size编译选项。但即便是1.91MB,跟Docker那几百MB比起来,也像是两个次元的东西。
但等等,Kern到底是不是一个“容器运行时”?
这个问题在Hacker News上吵过。
有人说Kern不是容器运行时,因为它不实现CRI(Container Runtime Interface)。Kern的作者自己承认:“runtime这个词被用烂了,我说的是docker/podman那个意义上的runtime——一个二进制搞定pull、build和生命周期”。
这其实触及了一个更深的问题:到底什么算“容器运行时”?是runc那种只负责启动进程的低层运行时?是containerd那种带镜像管理的中层运行时?还是Docker那种带CLI、带API、带守护进程的完整工具链?
Kern哪个都不是,又哪个都沾一点。它能启动容器(像runc),能管理镜像(像containerd),有CLI工具(像Docker)。但它没有守护进程,没有CRI实现,没有Kubernetes集成。
它给自己的定位是:“一个管理资源的二进制文件,隔离只是它的第一种能力”。
这话说得漂亮。但漂亮话不能当饭吃。Kern的适用场景极其明确:CLI工具、Agent调用、CI任务、一次性构建、代码单元格。出了这个范围,别用。它不是万能钥匙。
一个人的项目,能做到什么程度
Kern是A. Awad一个人维护的solo项目。一个人,写了一个1.52MB的容器运行时,支持OCI完整生命周期,支持Docker Compose,有Python和Node.js的SDK,还有一个MCP server for agents。
这在开源社区里不算罕见,但绝对算得上硬核。
一个人维护的项目意味着什么?意味着决策快、没有扯皮、设计一致。也意味着风险高、迭代慢、文档可能不全。Kern的文档在GitHub上,资源管理的部分有单独的docs/RESOURCES.md,但整体覆盖度显然没法跟Docker那套庞大的文档体系比。
你愿意把自己的生产环境押在一个solo项目上吗?作者自己都不建议你这么做。Kern的设计目标从来不是“替代Docker上生产”,而是“给那些Docker太重、太慢的场景一个轻量级的选项”。
这个定位,清醒得让人有点心疼。
一个容器,跑完就消失
Kern最打动人的地方,其实不是3.5毫秒,也不是1.52MB。
是“没有守护进程”这句话背后的哲学:一个工具,干完活就走,不占着茅坑不拉屎。
Docker的设计假设是:你会长期运行容器,你会管理一个容器集群,你需要一个常驻的后台进程来帮你打理一切。这个假设对Kubernetes时代的生产环境是对的。但对一个开发者想在本地快速测一个镜像、对一个CI任务想在隔离环境里跑一个构建步骤、对一个AI Agent想调用一个工具函数——这个假设太沉重了。
Kern回答的是另一个问题:如果我只想跑一个容器,跑完就扔,我需要付出什么代价?
答案是:一个1.52MB的二进制文件,和3.5毫秒。
这个答案,够不够颠覆你对容器的认知?
但这里有一个数据对不上。Kern说3.5毫秒从OCI镜像启动容器。可是3.5毫秒连从硬盘读一个镜像的metadata都不够,怎么可能完成命名空间创建、根目录切换、进程启动这一整套操作?除非所谓的“启动”指的是“复用已经准备好的容器状态”,而不是“从零开始创建一个容器”。这个细节,README里没有展开说。
一个未解的实验细节。一个让你觉得“这事还没完”的数据矛盾。