前 15 篇把 Tetragon 运行时安全拆到可观测与可排障的精度:进程血缘、hook、三条加载路径、内核选择器、Override 与 SIGKILL、JSON 与 gRPC 分流、Runtime Hooks 窗口,并对照了 Falco、auditd、CNP/Hubble、seccomp。选型若再写成「各有优劣看场景」,等于把机制丢掉。
本文是终章:用机制排除树收束判断,回收 Cilium 16 指向的 Tetragon 叶,写明何时不该跑 Tetragon,列出仍开放的问题,并以 ADR 可粘贴的语言关闭「eBPF 运行时安全内核」续作边界。不做跨方案延迟或 CPU 排行榜。
本篇在系列中的位置
篇目 核心内容 第 15 篇 · Runtime Hooks OCI hook 与容器边界 第 16 篇 · 选型收束(终章) 排除树、开放问题、边界关闭 系列目录 全部篇目
版本锚定:Tetragon v1.7.0(源码 tag v1.7.0,2026-04-29)。加载键是
collectionKey{name, namespace}。spec.nodeSelector与 live 文档的 domain sharding(k8s / grpc / static)晚于该 tag,不得写成当前能力。产品对照综述见 observability/15;eBPF VM 见 ebpf/。南北向 Gateway 见 Envoy Gateway / Gateway API。本系列不承诺 Falco 全书。
一、先排除,再选择(机制判据)
排除树每一叶必须回答一个可证伪的机制问题,而不是「看场景」。
flowchart TD
syscall{"Need process or syscall\ncontext beyond L3/L4?"}
syscall -->|"No"| net{"Need identity-centric\nNetworkPolicy plus Hubble?"}
net -->|"Yes"| cnp["Cilium CNP and Hubble\nno Tetragon required"]
net -->|"No"| other["Out of runtime-security scope"]
syscall -->|"Yes"| btf{"Kernel BTF and required\nconfigs available?"}
btf -->|"No"| nobtf["Do not run Tetragon"]
btf -->|"Yes"| inline{"Need inline Override\nof this operation?"}
inline -->|"No"| rules{"Falco rules library\nand response process enough?"}
rules -->|"Yes"| falco["Falco path"]
rules -->|"No"| audit{"Host audit ledger\nis the compliance target?"}
audit -->|"Yes"| auditd["auditd path"]
audit -->|"No"| staff1{"Can staff operate\nthe five axes?"}
staff1 -->|"No"| defer1["Do not run Tetragon yet"]
staff1 -->|"Yes"| tetObs["Tetragon observe\nwithout Override"]
inline -->|"Yes"| ov{"CONFIG_BPF_KPROBE_OVERRIDE\nand accept remaining TOCTOU?"}
ov -->|"No"| sig{"SIGKILL semantics\nacceptable?"}
sig -->|"No"| defer2["Do not claim enforcement"]
sig -->|"Yes"| staff2{"Can staff operate\nthe five axes?"}
staff2 -->|"No"| defer3["Do not run Tetragon yet"]
staff2 -->|"Yes"| tetEnf["Tetragon with Signal"]
ov -->|"Yes"| staff3{"Can staff operate\nthe five axes?"}
staff3 -->|"No"| defer4["Do not run Tetragon yet"]
staff3 -->|"Yes"| tetOv["Tetragon with Override"]
| 机制判据(问句) | 若「否」 | 倾向 |
|---|---|---|
| 需要进程/syscall/文件/能力上下文,而不是只做东西向 L3/L4? | 不要为品牌装运行时安全 agent | 停在 CNP + Hubble |
| 内核能提供 BTF(及所需 config)? | CO-RE 加载会失败 | 不要跑 Tetragon |
| 需要让这一次内核操作不执行(Override)? | 检测/告警可能已够 | Falco 规则库,或 Tetragon 仅观测 |
| Falco 规则库与响应流程已经够,且不要求 inline Override? | 不必付 TracingPolicy 五轴税 | Falco |
| 合规目标就是主机 audit 账本? | 不要用 TracingPolicy 冒充 auditd | auditd |
| 编制撑得住五轴(血缘、hook、加载键、sink、Override)? | 机制再强也运维不起 | 先缓装,或托管后再说 |
| 接受 SIGKILL 不撤销当前 syscall 副作用? | 不能把「杀进程」写成「调用没发生」 | 有 Override config 再谈强制执行 |
| 身份策略必须在容器启动前生效? | 无 Runtime Hooks 只有 API server 窗口 | 开 hook,或不要对启动瞬间做 enforce 承诺 |
甜区:自管 Kubernetes,已有 Cilium 身份语言或愿意学 TracingPolicy,内核有 BTF,值班能用第 13 篇五轴说话,需要按二进制/参数/Pod 标签观测或(在 config 允许时)Override。Runtime Hooks 按第 15 篇显式打开,而不是假设 DaemonSet Ready 等于身份过滤无窗口。
苦区:无人能区分 JSON denylist 与
tetra getevents;把 Falco 规则文件改写成
TracingPolicy 却不核 hook 类型;无
CONFIG_BPF_KPROBE_OVERRIDE 却把 Override
写进生产门禁;无 BTF 的旧内核上「先装再看」;只用 Hubble
却为「安全套餐」打开 Tetragon 全量 kprobe。
何时不该跑 Tetragon(否证条件)
下列任一成立,排除树上 Tetragon 叶判负(可写进 ADR):
- 编制撑不住五轴——不能用第 13
篇的口令区分无事件、撞名、导出缺口、Override 门闩。
- 需求停在 CNP +
Hubble——要回答的是身份与包路径,不是进程
syscall。Cilium
16 已经收束那一叶。
- Falco 规则库足够,且不要求 inline
Override——用户态规则与生态响应是主路径;CVE-2022-26316
是历史窗口,不是「必须换内核策略机」的充分条件。
- 没有 BTF(且无法提供可用 BTF
文件)——v1.7.0
pkg/btf找不到/sys/kernel/btf/vmlinux或指定文件就无法按 CO-RE 加载。
- 把「装了 Tetragon」当成已具备强制执行——未核 Override config、未核 monitor/enforce 模式、未核 Runtime Hooks。
否证触发后应重跑排除树,而不是口头「安全基线已经包含 Tetragon」。沉没成本不是机制判据:发行版默认装上、POC 转正,都要把现状当假设再走一遍上表。
seccomp 仍是容器基线(第 14 篇),与本叶正交:排除树判负 Tetragon,并不等于关掉 seccomp profile。
二、回收 Cilium 16 的 Tetragon 叶
Cilium 16 在边界表里把 Tetragon 标为续作入口(「本系列不展开」),并在版本钉中写明运行时安全见 Tetragon 系列。该指针在 Cilium 终章交付时是悬空的机制叶:读者知道「还有进程与 syscall 那一层」,但不知道加载键撞名、JSON 与 gRPC 分叉、Override 相对 SIGKILL、无 hook 的 API server 窗口。
本系列交付后,该叶的机制内容如下——两边终章不再悬空:
| Cilium 16 原指针 | 本系列回收位置 | 关闭状态 |
|---|---|---|
| 「运行时安全 / Tetragon」续作入口 | 01–12 机制;13 五轴;14 对照;15 hook;本篇排除树 | 已展开 |
| 「不要用 Hubble 回答进程问题」 | 第 14 篇 CNP/Hubble 表 | 已划界 |
| verifier / JIT / BTF 全书 | ebpf/ | 本系列不重写 |
| 产品能力勾选 | observability/15 | 互补,不替代 |
给读完两边的人一句分工口令:
- 「identity / policy map / Hubble deny」→ cilium/ 第 13 篇
- 「该不该上 eBPF 数据面」→ cilium/16
排除树
- 「exec_id / TracingPolicy / Override / 导出分叉」→
本系列 13
- 「该不该上 Tetragon」→ 本篇排除树
- 「Falco 规则怎么写」→ Falco 文档;本站不另开全书
Cilium 终章承诺的运行时安全续作指针,到此关闭悬空状态。不是「永远不再写安全」,而是:同一句「去看 Tetragon」不应再没有可核对篇章。
三、系列级开放问题(可证伪)
关闭条件必须是测量或正式文档/源码变更,不是路线图幻灯片。下列四项在 v1.7.0 边界内保持开放。
3.1 TOCTOU 的可接受边界
问题:生产策略里,何种 TOCTOU 被 ADR
接受——SIGKILL 后 write() 仍落盘、路径在
selector 匹配与内核使用之间被换绑、无 Runtime Hooks
时容器启动窗口?
为何重要:第 10、13、14 篇表明 Override 与
SIGKILL 保证不同;Bishop & Dilger 1996 与 Garfinkel 2003
给出的是结构,不是「本集群可接受的毫秒数」。
检验:固定一条可数的强制执行策略,对比「函数未执行」(Override)与「进程已死但副作用已发生」(Signal)。
入口:tag
enforcement/_index.md;Garfinkel NDSS 2003
§4.3。
现状:机制已知;可接受边界因威胁模型而异,本系列不编造百分比。
3.2 导出完备性:JSON 与 gRPC 所见集合
问题:file sink 的 allow/deny 与
gRPC/tetra
所见事件能否在运维上对齐成同一完备性证明?
为何重要:第 4、12、13 篇把「SIEM
没有」和「CLI
还有」写成轴四,而不是过滤器坏了。采样、节流(第 11
篇)、field filter 会再切一刀。
检验:同一事故窗口对 file sink 与 gRPC
计数;官方 Caution 已否证「denylist 作用于 tetra」。
关闭条件:上游改变导出语义,或本集群写明「gRPC
仅调试、JSON 才是证据」的 ADR 并配上对账作业。
现状:v1.7.0
语义已钉死分叉;完备性对账仍开放。
3.3 与 Cilium identity 的联合 runbook
问题:故障时先查 Hubble verdict 还是
process_exec / TracingPolicy?identity 数字与
exec_id 如何在同一张工单里引用?
为何重要:两边都可以「看起来像安全事件」;轴用错会改错层。
检验:合成「CNP deny + 容器内
connect」与「CNP 允许 + Override 挡住
connect」,值班是否落到正确系列。
约束:本系列不裁决「先装 Cilium 还是先装
Tetragon」。Cilium 16 的 Ambient
责任界面同样保持开放,两边不要互相冒充关闭。
3.4
v1.7.0 之后:spec.nodeSelector 与 domain
sharding
这两项是 tag 之后 的上游进展,禁止写进 v1.7.0 能力表。列为开放项,供升版时重跑排除树。
spec.nodeSelector
- 合入提交
a75f9d3(完整 SHAa75f9d3878205d7a3e33442e7771e67e9b061163),日期 2026-06-27,标题 k8s: Add nodeSelector to TracingPolicy spec。
- 给
TracingPolicy/TracingPolicyNamespaced增加可选spec.nodeSelector,用于后续按节点标签门控加载;与 v1.7.0 已有的hostSelector(只允许null/{},控制 host vs Pod 工作负载)目的不同。
- v1.7.0 的
k8s-filtering.md没有 nodeSelector 节。升到包含该提交的版本之前,按节点灰度策略只能用别的手段(DaemonSet 调度、分集群),不能假装 CR 字段已存在。
domain sharding(k8s / grpc / static)
- live 文档 Tracing Policy 在
2026-05-21 更新(提交说明
update(docs): update docs about domain sharding):三条加载路径各自进入 k8s / grpc / static domain,并出现tetra tracingpolicy domains一类叙述。
- v1.7.0 文档与
pkg/tracingpolicy未见该机制。 加载键是collectionKey{name, namespace}(pkg/sensors/collection.go),kubectl、gRPC、--tracing-policy文件进入同一 collection map;同键冲突时handler.go返回 already exists(第 6、13 篇)。
- 在钉 v1.7.0 的集群上使用
tetra tracingpolicy domains当排障命令,是把未来文档读成当前事实。升版后应重写第 5–6 篇的撞名叙事:冲突是否还发生在同一 map。
写给后续维护者:升 Tetragon 小版本时,先核这两个开放项是否进入该 tag,再更新本篇「能力/非能力」表,而不是重写排除树的问题顺序。
四、显式关闭:本系列边界
| 题目 | 归属 | 关闭状态 |
|---|---|---|
| verifier / JIT / BTF / Map 内核 | ebpf/ |
外链;本系列不重写 |
| 东西向 identity → map → Hubble | cilium/ |
外链;第 14 篇只对照 |
| 产品级 Hubble / Tetragon / Falco 勾选 | observability/15、linux/ebpf-security |
互补;不采用未核实 CPU/内存数字 |
| 进程血缘 → TracingPolicy → 强制执行 → 五轴 → 选型 | 本系列 | 01–16 覆盖 |
| Gateway API / 南北向 | Envoy Gateway / Gateway API | 本系列不抢;续作入口已挂 |
| Falco 规则库全书 | 上游 Falco 文档 | 不承诺本站 Falco 全系列 |
nodeSelector、domain sharding |
晚于 v1.7.0 的上游 | 开放项 3.4,不是本 tag 能力 |
给读完本系列的人三条收束(ADR 友好)
- 排除树进
ADR:写清卡在哪一叶机制判据;附否证条件(编制减员、需求退回
CNP+Hubble、Falco 规则库已够且不要 Override、内核无
BTF)。示例句:
「若平台不再维护 Tetragon 五轴值班,或不需要进程/syscall 上下文,则 Tetragon 叶必须重跑排除树,禁止以『安全套件已安装』续跑。」 - 若选了 Tetragon:第 13
篇五轴进发布门禁;第 6
篇集合键所有权进变更单(三条路径谁准写入
collectionKey);第 10 篇 Override config 与 TOCTOU 接受度进威胁模型;第 15 篇 Runtime Hooks 进身份强制执行检查;第 12 篇 JSON sink 与 gRPC 分叉进值班——缺一项降级为试验集群。
- 若没选:用第 14 篇机制表做代际复盘;禁止无口径 CPU 截图重开「要不要 Tetragon」争论。需要包路径判断时回 Cilium 终章;需要产品勾选时回 observability/15。
终章立场:Tetragon 值得写 16
篇,是因为失败可命名——execve_map 未命中、BTF
缺失、collectionKey 撞名、JSON 过滤不影响
gRPC、Override 依赖 error injection、无 hook 的 API
窗口。选型若离开这些名字,讨论退回安装量与品牌口号。记住一个动作:先排除,再打开强制执行,再打开
Runtime Hooks——排除自带否证,Override 自带内核 config,Hooks
自带 fail-open/fail-closed。
对平台团队的务实建议:先用第 13 篇在试验命名空间跑通一次真实或演练故障(至少覆盖「无事件」与「JSON 与 tetra 不一致」),再决定是否把 Tetragon 定为默认运行时安全。若演练里卡在「读不懂五轴」,优先补第 1、4、6、10 篇门禁与编制,而不是先堆规则库。排除树的正确用法是缩短错误迁移,而不是证明某品牌永远正确。
若读者时间只够两篇:读 01
全景 建立缺口意识,再读本篇排除树;然后按自己的主轴跳进
06/10/13
之一。完整通读的收益是「症状能落格」;跳读的风险是把
tetra getevents 当成 JSON 证据,或把 SIGKILL
当成 Override。
给维护者:补丁级更新应改版本钉与开放问题进展,而不是重写排除树的问题顺序。若
3.4 随新 tag
关闭,在本篇追加「已关闭项」并链到复盘,避免后人把
nodeSelector 写回 v1.7.0。
回到系列开头的缺口:站内已有 Cilium 数据面、可观测对照与 eBPF VM,缺的是「运行时安全失败如何落格到血缘/hook/加载键/sink/Override」。若读完 16 篇仍只能复述功能清单,说明阅读停在目录;若能在故障里说出「这是轴三集合键撞名」或「这是轴四 Caution」,机制文才算交货。
参考资料
规范 / 官方文档 / 源码(A)
- Tetragon v1.7.0 全文
tag:
docs/content/en/docs/、pkg/sensors/collection.go(collectionKey{name, namespace})、pkg/btf/btf.go - 提交 a75f9d3(2026-06-27):k8s: Add nodeSelector to TracingPolicy spec(晚于 v1.7.0)
- live 文档 domain sharding 更新 2026-05-21(k8s / grpc / static;晚于 v1.7.0 tag 文档)
- Cilium v1.20.0 终章:选型收束
论文 / 谱系
- Garfinkel, T. (2003). Traps and Pitfalls. NDSS 2003
- Bishop, M. & Dilger, M. (1996). Checking for Race Conditions in File Accesses. Computing Systems 9(2)
- Wright, C. et al. (2002). Linux Security Modules. USENIX Security 2002
- McCanne, S. & Jacobson, V. (1993). The BSD Packet Filter. USENIX Winter ’93
站内对照
- 系列目录
- Cilium 16 · 选型收束(Tetragon 原指针)
- 网络可观测性
- eBPF 安全文
- eBPF 内核实现
- 第 13 篇 · 排障
- 第 14 篇 · 对照
- 第 15 篇 · Runtime Hooks
- Envoy Gateway / Gateway API
实验台账
- 本篇无跨方案 benchmark;选型依据为机制排除。开放问题 3.4 的提交哈希与文档日期来自 GitHub,不是本机集群能力。
至此,系列在机制层闭合:从进程血缘与 hook,到策略加载、强制执行、导出分叉、排障五轴、对照与 Runtime Hooks,再到排除树。后续补丁级更新应改版本钉与开放问题进展,而不是重写「先排除再选」的顺序。
→ 上一篇:Runtime Hooks 与容器边界 · 系列目录
读完这篇,下一步读什么
优先读同系列或同问题的下一篇,把单篇消费变成主题集群。
【Tetragon / eBPF】对照替代路径:Falco、auditd、Cilium CNP/Hubble 与 seccomp
从过滤发生在哪一层、能否 inline 阻断对照 Falco、auditd、Cilium CNP/Hubble 与 seccomp;以 Garfinkel NDSS 2003 与 Falco CVE-2022-26316 作为 TOCTOU 谱系,不做 CPU 或内存排行。
Tetragon / eBPF 运行时安全:从进程血缘到 TracingPolicy
补齐站内 Cilium 数据面与可观测对照之上的运行时安全内核层:进程模型、Sensor/Hook、TracingPolicy 与内核过滤、强制执行、事件导出与节流,并以排障与相对 Falco/CNP 的选型收束。
【Tetragon / eBPF】运行时安全全景:缺口、五轴坐标系与 16 篇路线
相对 Cilium 数据面、可观测对照与 Falco 口号,钉清 Tetragon v1.7.0 运行时安全内核缺口;定义进程血缘、Sensor/Hook、策略加载、过滤分层、强制执行五条坐标系,给出 16 篇阅读路线。
【Tetragon / eBPF】进程模型:exec_id、血缘、in_init_tree 与 procfs 回填
钉清 Tetragon v1.7.0 的进程身份:process_exec/exit 字段、exec_id 如何由 node:ktime:pid 生成、execve_map 与用户态 cache 的分工、in_init_tree 如何区分 kubectl exec 注入,以及 fork 时父不在 map 则子不入图的失败路径。