犀牛鸟 2026 研究笔记 estelledc.github.io

第八章 · gVisor——「不用 KVM 也能隔离」的第三条路

这章为谁设计

你想理解「如果我的环境没有 KVM(比如 Mac、某些 VPS),还能怎么做隔离」。


一句话定位

Google 开源的「用户态内核」,在用户空间重新实现 Linux 系统调用接口,拦截所有应用行为,不需要硬件虚拟化。


日常类比

想象你去一家餐厅吃饭(你的应用在运行)。你不直接进厨房(不直接调用真实内核),而是通过服务员(Sentry)点菜。服务员会:

你永远不碰厨房。即使你是一个想搞破坏的顾客,你能做的最坏的事就是为难服务员——而服务员是专业训练过的,不会被你忽悠进厨房。

类比边界:真实的 Sentry 比服务员复杂得多——它要模拟整个 Linux 内核的行为(几百个系统调用),任何一个模拟不准确都可能导致应用出 bug。


核心设计哲学

gVisor 的核心理念是:隔离不一定需要硬件虚拟化,只需要「翻译层」

对比三种隔离思路:

思路 代表 类比 原理
硬件隔离 Firecracker/CubeSandbox 独立别墅 每个租户有自己的地基和墙壁(独立内核)
系统调用过滤 seccomp-bpf 门禁白名单 只允许做白名单里的事,其他直接拒绝
用户态内核 gVisor 服务员翻译 所有操作都经过翻译层,翻译层决定真正做什么

gVisor 和 seccomp 的区别:seccomp 只做「允许/拒绝」(黑白名单),gVisor 做的是「完整翻译」——它理解你要做什么,用自己的方式实现,而不是简单地放行或拒绝。


Sentry 的技术特点

Sentry 是 gVisor 的核心组件——一个用 Go 写的、运行在用户态的完整 Linux 内核替代品。


gVisor 的核心优势

不需要 KVM:不是所有环境都有 KVM——Mac 全系列没有、某些 VPS 没有、WSL 1 没有、嵌套虚拟化未开启的云服务器也没有。gVisor 可以直接跑在普通 Docker 里。

启动速度是进程级的:不需要 boot 一个 VM(那需要加载内核、初始化设备),只需要启动一个 Go 进程(毫秒级)。

与 Kubernetes 原生集成runsc(gVisor 的 OCI 运行时)可以直接替代 runc,在 K8s 里给 Pod 加上 gVisor 隔离——不需要改任何业务代码。


gVisor 的核心劣势

系统调用兼容性边界

Linux 有超过 400 个系统调用,每个还有 flag 组合、edge case、内核版本差异。gVisor 的 Sentry 要逐个实现——这是一个永远追不完的任务。

真实案例 #13535tty 命令在 gVisor 容器里输出 “not a tty”——pty 相关的 syscall 实现有遗漏。

真实案例 #13529:EROFS(只读压缩文件系统)镜像在 gVisor 里启动失败——某个挂载操作的行为和真实 Linux 不一致。

对 AI Agent 场景的影响:如果 Agent 代码跑了一些需要特殊 syscall 的操作(如某些 ML 库的优化路径),Sentry 可能不支持或性能很差。

空闲资源消耗

真实案例 #13361:一个 sleep inf 的容器(完全空闲),gVisor 的 Sentry 进程占用 15-20% CPU。原因是 Go runtime 的 scheduler 和 netpoll 机制在等待 guest syscall 时持续轮询。

这在高密度场景下是致命的:1000 个空闲沙箱,每个浪费 0.1% CPU = 100% = 一整个核心浪费了。


代码量为什么巨大

gVisor 是 6 个项目里代码量最大的(「数千文件」)。原因很简单:要在用户态重新实现 Linux 内核的几万个 syscall 行为。每新增一个 syscall 支持,都需要在 Sentry 里实现一遍,还需要写测试确保行为与真实 Linux 一致。

对比:Firecracker 代码量只有「数百文件」——因为大部分系统逻辑交给 Linux 内核做,Firecracker 只管 VM 管理。


gVisor 的 add-syscall 工作流(AI 配置揭秘)

gVisor 的 .claude/skills/add-syscall/SKILL.md 定义了一个完整的「如何在 gVisor 里实现新 syscall」的工作流,包含四个阶段:

  1. 理解现状:查 syscall 表,确定当前支持级别
  2. 规划:对比 Linux 行为和 gVisor 需求差异
  3. 实现:写 ABI 常量 → 写 handler → 更新 syscall 表 → 更新 BUILD 文件
  4. 测试驱动验证:先跑原生测试(在真实 Linux 内核上),再跑 gVisor 测试(在 Sentry 上),确保两者行为一致

这个「原生 → gVisor 两步验证」是 gVisor 的独特质量门禁——确保 Sentry 的行为与真实 Linux 一致。


关键洞察

gVisor 和 Firecracker/CubeSandbox 解决的是同一个问题(隔离不可信代码),但路线完全不同:

维度 gVisor Firecracker/CubeSandbox
隔离方式 软件翻译(用户态内核) 硬件隔离(KVM VM)
需要 KVM
启动速度 极快(进程级) 快(60-125ms)
syscall 兼容性 有边界(99% 但不是 100%) 完整(跑真实内核)
攻击面 Sentry 本身(Go 代码) KVM + VMM(Rust 代码)
适合场景 无 KVM 环境、高频创建、可接受兼容性风险 需要完整兼容、强隔离、多租户

读完这章你应该能回答

  1. gVisor 的 Sentry 是什么?(用户态的 Linux 内核替代品,用 Go 写)
  2. gVisor 不需要 KVM 的优势在哪?(Mac/VPS/WSL 等无 KVM 环境也能用)
  3. gVisor 的最大劣势是什么?(syscall 兼容性不是 100%,某些应用可能跑不了)
  4. 什么时候选 gVisor 而不是 Firecracker?(没有 KVM、需要极快启动、能接受兼容性风险)

导读目录:README.md 上一章:第七章 · Daytona——星数最高的 AI 沙箱平台 下一章:第九章 · Kata Containers——容器和 VM 的「混血儿」