Cilium / eBPF
数据面内核 已把东西向包路径钉到 identity 与 map;可观测性
· 网络观测 与 linux/ebpf-security
对照过 Tetragon 与 Falco。Cilium
选型收束 把 Tetragon
标为运行时安全续作,但停在排除树叶。中间仍缺一层:一次安全事件如何经进程血缘与
hook、TracingPolicy 选择器如何在内核过滤、Override 与
SIGKILL 各自停在哪一步、导出过滤为何与 tetra
所见不一致,以及相对 Falco / auditd / 仅
NetworkPolicy+Hubble 何时不该上 Tetragon。
本文只做三件事:钉缺口、定义后续 15
篇共用的五条坐标系,并给出阅读路线。难点不在「会不会 Helm 装
Tetragon」,而在控制面意图与内核路径交界上的可核对字段——exec_id、hook
类型、加载集合键、JSON allow/deny 与 gRPC 的分流、Override
相对 Signal 的保证。
本篇在系列中的位置
篇目 核心内容 第 1 篇 · 运行时安全全景 缺口、五轴坐标系、16 篇路线 第 2 篇 · 进程模型 exec_id、血缘、in_init_tree、procfs 回填系列目录 关键问题、阅读路径、全部价值点
版本锚定:Tetragon v1.7.0(源码 tag v1.7.0,发布 2026-04-29)。机制叙述对齐该 tag 下的
docs/content/en/docs/、bpf/、pkg/、api/v1/tetragon/。tetragon.io/docs/是滚动站点,不以 live 文档冒充本版本。无真实 Tetragon 节点则不粘贴伪造tetra getevents/ JSON 输出。spec.nodeSelector与 domain sharding 晚于该 tag,不作为本系列能力。
一、相对站内已有内容,缺口在哪
下表列出各已有系列的视角,以及本系列补的格子。规则是:不重写已有内容,只填真正空着的格子。
| 已有内容 | 视角 | 本系列补什么 |
|---|---|---|
| cilium/ 01–16 | 东西向 identity / map / kube-proxy 替代 / Hubble | 进程与 syscall 安全事件面;不重写 CNI |
| cilium/16 | 点名 Tetragon,停损线 | 成系列展开策略 → hook → 强制执行 |
| observability/15、linux/ebpf-security | 工具对照、快速启用清单 | 机制路径、失败模式、排障坐标系 |
| ebpf/ 01–21 | verifier、JIT、BTF、Map | 不重写 VM;只写 Tetragon 如何用这些原语 |
| Falco / auditd 站内提及 | 对照口号 | 机制差:过滤位置、阻断语义、TOCTOU |
结论:读者知道「Tetragon 用 eBPF
做运行时安全」、会贴一条 TracingPolicy
YAML,但不知道事件卡在选择器还是导出过滤、为何
tetra getevents 仍看到
denylist「已滤掉」的事件、Override 与 SIGKILL
各自停在哪一步、三条加载路径(kubectl CR /
tetra gRPC / --tracing-policy
文件)撞名时为何「改了 CR 不生效」。本系列补「eBPF
运行时安全内核」那一格。
与通识教程的差别也在这里:多数「在 K8s 上装
Tetragon」文章停在 process_exec
示例与一条文件打开策略;本系列追问 策略 apply
成功之后丢失/误阻断仍落在哪一层,以及
血缘空洞、hook 未挂上、加载路径撞名、JSON 与 gRPC
集合不一致、Override
不可用各自如何表现。深度来自可证伪的阶段划分,而不是更长的功能清单。
本系列刻意不写 Helm values 百科、每个发行版 CIS benchmark
逐条映射、verifier 形式化算法全书、完整 MITRE
规则库、未实测跨方案 CPU 排行。站内 linux/ebpf-security
对照表里的资源占用数字本系列不引用——那些数字未经本仓库实测,也不能从
v1.7.0
官方文档核出。官方已经钉死、本系列会反复回指的机制差只有这一条:JSON
export allow/deny 不影响 gRPC /
tetra(v1.7.0 events.md
Caution)。若目标只是「把 DaemonSet 跑起来」,官方
Quickstart 与 observability/15 已够;若目标是「失败落在哪张
map / 哪个 hook、导出为何对不齐」,则必须沿五轴下钻。
二、五条坐标系(后续章节回指)
后面每一篇都落到下面某一条轴上。本篇钉名字、关键锚点与失败表象;具体生命周期、源码与事件停顿点在对应篇展开。排障口诀:先点名轴,再下钻模块——不要一上来改 TracingPolicy YAML 或重装 DaemonSet。
flowchart LR
proc["execve_map plus process cache"] --> hook["Hook Sensor"]
hook --> sel["In-kernel selector"]
load["Load paths kubectl gRPC file"] --> sel
sel --> act["Action Override Signal Post"]
act --> ring["Ring to agent"]
ring --> split{"Sink"}
split -->|"JSON allow deny"| json["tetragon.log"]
split -->|"gRPC unfiltered"| grpc["tetra getevents"]
图:一次运行时安全事件沿五轴从进程状态走到 sink 分流。节点为英文,避免窄框折行;正文用中文解释每条轴。
| 轴 | 可核对锚点 | 失败表象 | 主篇 |
|---|---|---|---|
| 进程血缘 | exec_id /
parent_exec_id(GetProcessID:base64(node:ktime:pid))、execve_map、用户态
process
cache、in_init_tree、flags(含
procFS) |
短命进程无父、kubectl exec 不像 init
子孙、进程不在 map |
02、13 |
| Sensor/Hook | 内置 process sensor(__base__);kprobe /
tracepoint / uprobe / USDT / LSM / fentry(v1.7.0) |
策略已 apply 无事件、无 BTF、hook 名写错 | 03、05 |
| 策略加载 | 三条路径:kubectl CR、tetra gRPC
add、--tracing-policy 文件;集合键
name+namespace |
改了 CR 不生效(实际是文件/gRPC 侧同名集合)、Namespaced vs cluster 撞名 | 05–06 |
| 过滤分层 | 内核 selector vs JSON export allow/deny vs field/redaction | tetra 仍看见 denylist「已滤」事件 |
04、07 |
| 强制执行 | Override(需
CONFIG_BPF_KPROBE_OVERRIDE)vs
Sigkill/Signal;monitor vs
enforce;TOCTOU |
SIGKILL 后 syscall 副作用已发生;Override 不可用却当阻断 | 10、13 |
进程血缘轴
定义:Tetragon 如何给一次执行分配跨节点、跨 PID 复用仍可核对的身份,以及父子关系在内核 map 与用户态 cache 之间如何衔接。
PID 会被内核复用。v1.7.0 的回答是
exec_id:用户态 GetProcessID
把导出用节点名、内核 ktime 与 PID 拼成
node:ktime:pid,再做标准 Base64(见 第 2
篇)。内核侧权威状态在 execve_map(按 TGID
索引);JSON 里的 process / parent
来自用户态 LRU cache 的富化。agent 启动时还会从 procfs
回填已存在进程,事件 flags 带
procFS。
「短命进程看不到父」或「kubectl exec 进来的
shell 被当成容器业务进程」优先落本轴,而不是先怀疑
TracingPolicy
YAML。本轴不承诺零缺口血缘:fork 时若父不在
execve_map,子进程根本不会入图——这是失败路径,不是实现细节。
Sensor/Hook 轴
定义:哪些 BPF 程序在哪些内核/用户态点上挂着,以及 TracingPolicy 动态 hook 相对内置进程传感器覆盖什么。
| 可核对锚点 | 含义 |
|---|---|
__base__ sensor |
进程生命周期:execve
tracepoint、wake_up_new_task fork、exit
kprobe、execve_map |
spec.kprobes / tracepoints /
uprobes / usdts /
lsmhooks / fentries |
TracingPolicy 动态 hook(CRD @ v1.7.0) |
| BTF / CO-RE | 加载失败时事件为零,表象像「策略没匹配」 |
「策略已 apply 但没有任何 kprobe 事件」优先查本轴的符号名、syscall ABI 前缀、LSM 是否启用、fentry 是否被内核接受,而不是先改选择器。Verifier / JIT 算法外链 ebpf/,本系列只写 Tetragon 选用的 hook 角色与内核依赖。
策略加载轴
定义:一条 TracingPolicy 从哪条路径进入同一 collection map,以及同名集合如何互相覆盖或静默失败。
v1.7.0 文档列出三条路径:Kubernetes kubectl
施加 CR、tetra 经 gRPC add/delete、daemon
启动时的 --tracing-policy /
--tracing-policy-dir 文件。集合键是
name + namespace(cluster-scoped
策略的 namespace 为空)。domain sharding(k8s / grpc
/ static)不是 v1.7.0 机制,不要用后版本 CLI
去解释本版本撞名。
「改了 CR 不生效」优先怀疑另一条路径已经占用同名集合,而不是先怀疑 YAML 缩进。展开见第 5–6 篇。
过滤分层轴
定义:内核选择器丢掉的事件,与 JSON 导出 allow/deny 丢掉的事件,不是同一集合。
内核 selector 在 hook 内决定 Post / NoPost / Override /
Signal(第 7 篇)。JSON 文件 sink 另有 allowlist /
denylist。v1.7.0 events.md 的 Caution
写死:这两类导出过滤不作用于
gRPC,因此默认的 tetra getevents 仍能看见
denylist「已滤」事件。Field filter 与 redaction
又是另外两层,且 redaction 发生在进程对象构造时,会进入所有
sink。
「SIEM 里没有、tetra
里还有」优先落本轴,而不是先认定策略没挂上。展开见 第 4
篇。
强制执行轴
定义:匹配之后 Tetragon 保证什么、明确不保证什么。
Override 让被 hook
的函数不执行并返回指定错误,依赖
CONFIG_BPF_KPROBE_OVERRIDE。Sigkill
/ Signal
终止进程,官方文档写明不保证当前 syscall
不做完(典型是 write()
已把字节送进内核)。monitor / enforce mode
改变动作是否真正发出。TOCTOU
是系统调用拦截类工具的经典失败模式,不是 Tetragon 独有的实现
bug。
「策略匹配了但文件已经被写出去」优先落本轴的保证边界,而不是先加大选择器范围。展开见第 10、13 篇。
三、坐标系背后的三个不变量
相对「用户态规则引擎读 /proc 或
ptrace」与「只在 CNI 上做 NetworkPolicy」,Tetragon
运行时安全同时钉住三条不变量:
- 进程身份以
exec_id为键,不以瞬时 PID 为键:PID 复用由 ktime 与节点名拆开;代价是必须解释 map 未命中、procfs 回填与 fork 失败路径。 - 能在 hook 完成的过滤尽量留在 BPF 里:选择器在内核丢事件,导出过滤在用户态再丢一次。代价是两层过滤的可见集合可以不一致——这是设计,不是 CLI 故障。
- 强制执行发生在具体 hook 的语义里,而不是「安全产品已阻断」的口号里:Override 与 Signal 的保证不同;syscall 入口拦截继承 Garfinkel 指出的 TOCTOU。代价是排障必须问「拦在函数入口还是进程退出」,不能问「Tetragon 开了没有」。
排障时先问「哪条不变量被触碰」,再落到对应轴。例如:kubectl exec
注入的进程看起来像业务子孙 → 不变量 1;denylist 之后
tetra 仍刷屏 → 不变量 2;SIGKILL 后副作用已落盘
→ 不变量 3。
这三条不变量也解释了系列边界:本系列不重写 verifier 证明义务(那是 eBPF VM 层),也不写 Cilium 东西向 policy map(那是 CNI 数据面层)。我们只在 Tetragon 运行时安全里追问:给定这三条约束,v1.7.0 如何实现、何处失败、与系统调用拦截的经典假设差在哪。
四、设计谱系:过滤虚拟机 → 系统调用拦截 → 生产分叉
McCanne & Jacobson, USENIX Winter 1993(经典 BPF:内核过滤虚拟机)
→ 扩展 BPF(通用内核可编程;站内 ebpf/ 展开 verifier/JIT)
→ Garfinkel, NDSS 2003(系统调用拦截的陷阱:TOCTOU、/proc 窗口、覆盖不全)
→ Tetragon:eBPF hook + 进程 map + TracingPolicy(工程系统)
→ 仍争:内核过滤完整性 vs 用户态规则可移植性;导出完备性 vs 观测税
Höiland-Jørgensen et al.(The eXpress Data Path, CoNEXT 2018)把可编程点推到网卡驱动最早路径,是 Cilium 东西向数据面的学术对照,不是本系列主线。本系列的执行面是 kprobe / tracepoint / LSM / fentry 这类安全与追踪 hook,不是 XDP。不要把「eBPF 很快」从数据包路径直接搬到 syscall 拦截路径上——工作负载、缓存效应与失败模式都不同。
- 经典 BPF(McCanne & Jacobson, USENIX Winter 1993)定义「在内核里用受限虚拟机过滤」的范式;今天的 eBPF 是能力与安全模型都大幅扩展后的后代,细节见 ebpf/。
- 系统调用拦截的陷阱(Garfinkel, NDSS
2003)列出 TOCTOU、通过
/proc重建进程树的竞态、以及「以为拦了入口其实副作用已发生」。Tetragon 用内核 map 跟踪执行,消除的是「每次事件再扫一遍/proc」这条路径,不消除 Garfinkel 的全部陷阱。 - 生产分叉(v1.7.0):内置
__base__进程传感器维持execve_map;TracingPolicy 把策略写成可加载的 hook 集合;JSON 与 gRPC 分成两套可见集合。fentry、hostSelector、matchParentBinaries已在该 tag;spec.nodeSelector与 domain sharding 尚未进入。
| 维度 | 经典 / 早期 | Tetragon v1.7.0 默认叙事 | 开放分叉 |
|---|---|---|---|
| 进程身份 | PID、/proc 快照 |
exec_id + execve_map |
启动窗口与 fork 未命中时血缘残缺 |
| 过滤位置 | 用户态规则 / 审计日志 | hook 内 selector + 用户态导出过滤 | 两层集合能否对齐 |
| 阻断 | 杀进程、seccomp 否决 | Override vs Signal | TOCTOU 可接受边界 |
| 对照工具 | auditd、Falco 用户态规则 | 同一节点上的 eBPF 运行时安全 | 规则库生态 vs 内核路径税 |
五、开放争论(先立靶,后各章拆)
| 争论 | A 侧 | B 侧 | 本系列落点 |
|---|---|---|---|
| 内核过滤完整性 vs 用户态规则可移植性 | hook 内丢事件,攻击窗口短 | Falco 规则库与用户态表达更易搬迁 | 第 4、7、14 篇 |
| 内核进程树 vs procfs 快照 | 短命进程在 exit 前可被 map 看见 | 启动前回填仍走 /proc,有窗口 |
第 2、13 篇 |
| Override 正确性 vs SIGKILL 简便 | 函数不执行 | 不依赖 CONFIG_BPF_KPROBE_OVERRIDE |
第 10 篇 |
| 「必须 Tetragon」营销 vs Falco / 仅 CNP | 统一进程+syscall 面 | 规则库或网络策略在部分威胁模型下够用 | 第 14–16 篇 |
不在第 1 篇宣布胜负;每组争论要求后续篇给出可核对机制或选型边界,而不是「看业务场景」空话。
对「内核路径 vs
用户态规则」额外钉一句:本系列不比较未实测的 CPU
排行榜,只比较失败模式是否可归因到五轴中的某一层。若安全产品把过滤与阻断藏在黑盒里,工程师就失去了
exec_id / hook / sink
分流这类抓手——这是架构选择,不是性能排名。
六、16 篇路线与阅读建议
flowchart TD
overview["01 Overview"] --> proc["02 Process Model"]
proc --> hooks["03 Sensors Hooks"]
hooks --> export["04 Event Export"]
export --> agent["05 Agent Lifecycle"]
agent --> tp["06 TracingPolicy"]
tp --> sel["07 Selectors"]
sel --> k8s["08 K8s Identity"]
k8s --> faces["09 File Net Cap"]
faces --> enf["10 Enforcement"]
enf --> thr["11 Throttling"]
thr --> ops["12 Ops SIEM"]
ops --> trouble["13 Troubleshoot"]
trouble --> vs["14 vs Alternatives"]
vs --> rth["15 Runtime Hooks"]
rth --> select["16 Selection"]
overview --> select
| 路径 | 篇目 | 适合 |
|---|---|---|
| 必读核心 | 1 → 2 → 6 → 7 → 10 → 13 | 快速建立坐标系 |
| 事件与导出 | 3 → 4 → 11 → 12 | 管道与丢失归因 |
| 对照选型 | 1 → 14 → 16 | 路径选型 |
| 完整通读 | 1 → … → 16 | 系统掌握 |
先修:熟悉 Pod / 系统调用直觉;可选 cilium/01、ebpf/01;对照 observability/15、linux/ebpf-security。
阅读时建议随身带一张「轴 →
锚点」卡片:短命进程无父先问血缘;策略已 apply 无事件先问
hook / 加载;tetra 与 JSON
对不上先问过滤分层;杀了进程仍落盘先问强制执行。把现象翻译成轴,比翻译成「重启
tetragon DaemonSet」更接近本系列目标。
五个关键问题到第 1 篇结尾仍然够用:后续每一篇应能把问题收束到某一轴上的可核对锚点。若一篇写完仍只能回答「看场景」,说明证据或机制还不够。本系列对跨方案 CPU 排名正是如此处理的。
本系列明确不写:Helm values 百科;把 live 文档的后版本能力写成 v1.7.0;伪造命令输出;把 Cilium NetworkPolicy / Hubble 数据面再讲一遍。
七、小结
- 定位:补 cilium/、observability/15 与 ebpf/ 之间的 Tetragon 运行时安全内核层,不重写产品百科或 verifier 全书。
- 五轴:进程血缘 / Sensor·Hook / 策略加载 / 过滤分层 / 强制执行;每轴有可核对锚点。
- 三不变量:
exec_id为键、尽量在 hook 过滤、阻断语义绑定具体 hook。 - 谱系:经典 BPF → 系统调用拦截陷阱 → Tetragon v1.7.0 生产分叉。XDP 论文只作数据面对照。
- 路线:核心「1→2→6→7→10→13」;导出「3→4」;选型「1→14→16」。
下一篇进入血缘轴:没有 exec_id 与
execve_map
的语言,后面的选择器、导出分流和「偶发无父」都无处锚定。
八、参考资料
规范 / 官方文档(A)
- Tetragon v1.7.0 Events —
docs/content/en/docs/concepts/events.md@ tag v1.7.0(JSON 路径、gRPC Unix socket、export Caution)。 - Tetragon v1.7.0 Tracing Policy —
docs/content/en/docs/concepts/tracing-policy/_index.md@ tag v1.7.0(三条加载路径)。 - Tetragon v1.7.0 Hook points —
docs/content/en/docs/concepts/tracing-policy/hooks.md@ tag v1.7.0。
源码(A)
cilium/tetragontag v1.7.0:pkg/process/process_id_linux.go(GetProcessID)、bpf/lib/process.h(execve_map)、pkg/sensors/base/base.go(__base__)、pkg/k8s/apis/cilium.io/v1alpha1/tracing_policy_types.go(fentries等 CRD 字段)、api/v1/tetragon/tetragon.proto。
核心论文
- McCanne & Jacobson, The BSD Packet Filter, USENIX Winter 1993 —— 内核过滤虚拟机范式。
- Garfinkel, Traps and Pitfalls: Practical Problems in
System Call Interposition Based Security Tools, NDSS
2003 —— TOCTOU、
/proc窗口、拦截完整性。 - Höiland-Jørgensen et al., The eXpress Data Path, CoNEXT 2018 —— 网络数据面对照,非本系列主线。
实验 / 工具
- 本篇无集群命令输出;不写 pps / CPU% 数字,不粘贴伪造
tetra输出。
站内对照
- 系列目录
- Cilium / eBPF 数据面内核
- Cilium 选型收束(Tetragon 指针)
- 网络可观测性:Hubble / Tetragon 对照
- eBPF 安全:Falco / Tetragon
- eBPF 内核实现
读完这篇,下一步读什么
优先读同系列或同问题的下一篇,把单篇消费变成主题集群。
Tetragon / eBPF 运行时安全:从进程血缘到 TracingPolicy
补齐站内 Cilium 数据面与可观测对照之上的运行时安全内核层:进程模型、Sensor/Hook、TracingPolicy 与内核过滤、强制执行、事件导出与节流,并以排障与相对 Falco/CNP 的选型收束。
【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 则子不入图的失败路径。
【Tetragon / eBPF】Sensor 与 Hook:进程传感器、kprobe、tracepoint、uprobe、LSM 与 fentry
钉清 Tetragon v1.7.0 内置 __base__ 进程传感器与 TracingPolicy 动态 hook 的分工:kprobe/kretprobe、tracepoint/rawtp、uprobe/USDT、LSM 与 fentry 各自能观察什么、依赖哪些内核能力,以及选错 hook 类型时的失败表象。
【Tetragon / eBPF】Agent 生命周期:BTF、安装形态与三条策略加载路径
钉清 Tetragon v1.7.0 agent 从 BTF/CO-RE 发现到 sensor 挂载的失败表象;对照 DaemonSet 与主机安装;说明默认 gRPC Unix socket 与 kubectl/gRPC/静态文件三条路径如何进入同一 collection map。