第 11 篇 解释事件在节流与环缓冲上消失。本篇回答运维侧两个对称的问题:Prometheus 上的计数器能证明什么;日志管道接到文件之后仍看不见的原因是不是 SIEM 配错了。 v1.7.0 把一批指标改名,并把默认 gRPC 从 TCP 换成 Unix socket。把旧仪表盘和旧客户端原样接到新 agent,会同时出现「merge 指标消失」和「第三方采不到事件」。
本篇在系列中的位置
篇目 核心内容 第 11 篇 · 节流与观测税 丢事件的内核/队列层 第 12 篇 · 运维与导出工程 metrics、轮转、SIEM 与 gRPC 地址 第 13 篇 · 排障坐标系 按五轴归因 系列目录 全部篇目
版本锚定:Tetragon v1.7.0(2026-04-29)Upgrade notes +
pkg/metrics/+pkg/exporter/。JSON 默认路径以 tagevents.md为准:/var/run/cilium/tetragon/tetragon.log。无真实节点则不粘贴伪造/metrics或 dashboard 截图。不写 Splunk / Elasticsearch 产品步骤。
一、v1.7.0
metrics:merge 从两条计数器收成一条带 status
的计数器
Upgrade notes · Metrics:
- 删除
tetragon_generic_kprobe_merge_errors_total - 删除
tetragon_generic_kprobe_merge_ok_total - 替换为
tetragon_generic_kprobe_merge_total,标签status取ok或error;另有curr_type、prev_type(enter或exit)、curr_fn、prev_fn
源码
pkg/metrics/kprobemetrics/kprobemetrics.go 与
notes 一致:MergeTotal 的 Help 是 “The total
number of attempts to merge a kprobe and kretprobe
event.”;status 约束为 ok /
error;MergeOkInc /
MergeErrorsInc 都打到同一计数器。旁边仍有
tetragon_generic_kprobe_merge_pushed_total(推入待合并队列的次数),notes
没有删除它。
升版检查:Grafana / 告警若仍搜旧的
_errors_total /
_ok_total,查询会空,不表示 merge
不再发生。应改为:
tetragon_generic_kprobe_merge_total{status="error"}
tetragon_generic_kprobe_merge_total{status="ok"}
该指标证明的是 kprobe 与 kretprobe
事件能否配对,不是「策略是否匹配」或「JSON
是否写出」。status="error"
升高时,用户态看到的可能是残缺的 enter 或
exit,而不是完整的一次调用。把它当成第 9 篇的 hook
选错,坐标系又偏了。curr_fn /
prev_fn
用来区分是哪两个探测点在抢同一条合并槽;curr_type
/ prev_type 区分当前与前一条是 enter 还是
exit。告警若只看 status
总和,会把互不相关的函数搅在一起。
MergePushed
计数的是「先放下、稍后合并」的次数。它升高只说明合并队列在工作,不说明最终
ok。配对失败时,第 11 篇的环缓冲丢失与本节的
merge error 仍要分开看:前者是根本没进 agent,后者是进了但
enter/exit 对不上。
pkg/metrics/consts 把 Prometheus namespace
钉成 tetragon,因此上文计数器都以
tetragon_
开头。eventmetrics.RegisterHealthMetrics 注册
flags / notify overflow / BPF collector / missing process
info;InitEventsMetrics 把
events_total 与
policy_events_total 注册到另一条
registry。刮取时若只看见 health 组、看不见
events_total,先查该 scrape 对应的 registry
是否注册了 InitEventsMetrics 那一组,不要假设
merge 更名把它们删了。v1.7.0 Upgrade notes
没有删除 events_total。
同一次发布还点名(Upgrade notes / changelog,本篇只列与导出运维直接相关的):
| 指标或行为 | v1.7.0 口径 |
|---|---|
tetragon_process_cache_early_deletions_total |
新增,观察 process cache GC 过早删除(第 13 篇血缘轴) |
tetragon_overhead_program_seconds_total |
修复为按秒报告,不再误把纳秒当秒(PR #4830) |
tetragon_debug_events_total |
把非致命问题从错误里分开(PR #4416) |
pkg/exporter/metrics.go
给文件导出路径另备一套计数器,与 merge
无关:
| 指标 | Help 口径 |
|---|---|
tetragon_events_exported_total |
已导出事件总数 |
tetragon_events_exported_bytes_total |
已导出字节 |
tetragon_events_last_exported_timestamp |
最近一次导出的时间戳 |
tetragon_export_ratelimit_events_dropped_total |
导出层限流丢掉的事件 |
最后一项与第 11 篇 Post.rateLimit
不是同一层:Exporter.Send() 在 JSON encode
之前看用户态 rateLimiter,拒绝则
rateLimitDropped.Inc() 并返回。SIEM
若只读文件,会同时少掉这些事件;gRPC
听众不受这个计数器约束。
第 11 篇已列的 tetragon_observer_ringbuf_*
在升版后名字不变,仍是管道丢失的第一选择。本篇不重复公式,只强调:merge_total
回答配对;ringbuf lost 回答没进 agent;events_exported_total
回答文件 sink 写出了多少。 三者不能互相替代。
二、JSON 轮转:SIEM 只能看见文件 sink
tag events.md:默认部署把 JSON 写到
/var/run/cilium/tetragon/tetragon.log,可供
fluentd、logstash 一类工具采集;文件会轮转并压缩。路径与
live 站点后版本的目录迁仓说明不是一回事,本系列按 tag
文档钉这一条。
实现上 pkg/exporter/exporter.go 用
cilium/lumberjack/v2
写文件。NewExporter 读
option.Config.ExportFilename 与
ExportFileRotationInterval:间隔为负则直接报错;大于
0 则 time.AfterFunc 调
lumberjack.Logger.Rotate()。Send()
的顺序是:导出层 rateLimiter(失败则只加
export_ratelimit_events_dropped_total)→
encoder.Encode →
events_exported_total++ 并刷新
events_last_exported_timestamp。SetLogParams
允许在运行时改
MaxSize、MaxBackups、RotationInterval(经
event log gRPC 参数;本篇不展开该
API)。daemon-configuration 示例用 drop-in
export-filename 把路径改成
/var/log/tetragon/tetragon.log——这是覆盖默认,不是第二条默认。
tag events.md 写默认部署会轮转并压缩。Helm
chart 的具体 exportFileCompress
默认值以安装时的 chart 为准,本篇不把 live
chart 表格写成 v1.7.0 事实。运维能核对的是:进程是否以
lumberjack 打开了
ExportFilename;采集器是否跟随 rotate
后的新文件。
events_last_exported_timestamp 适合做「文件
sink 是否还在写」的存活探针。它不证明 SIEM
已摄入:采集器可以停在旧 inode 上,而 Tetragon 已经 rotate
到新文件。这是日志管道的经典 inode 问题,不是 TracingPolicy
失败。
必须连同第 4 篇 Caution 再读一遍:allowlist
/ denylist 只作用于文件
sink。gRPC 与 tetra getevents
仍是未经过这层过滤的流。因此:
| 接线 | 看见的集合 |
|---|---|
采集 tetragon.log 的 SIEM |
经过 export allow/deny、field filter、redaction、导出层 rate limit、轮转窗口里仍在磁盘上的文件 |
tetra getevents / 自写 gRPC 客户端 |
不受 JSON allow/deny 约束 |
| agent 停机且未开 persistent 观测 | 两边都没有新事件;第 10 篇
--keep-sensors-on-exit 只留下强制执行 |
SIEM「少事件」时先问三句:文件路径是否仍是 tag
文档那条(或你显式改过的
export-filename);allow/deny
是否把该类事件裁掉;轮转后采集器是否还指着已压缩/已改名的
inode。不要先改 TracingPolicy。
events.md 里的 allowlist
形态(文档示例):每行一个 JSON
对象,行之间为 OR,对象内字段为 AND。denylist 优先于
allowlist。只配 allowlist 时导出是 default-deny。
{"event_set": ["PROCESS_EXEC", "PROCESS_EXIT"], "namespace": ["foo"]}
{"event_set": ["PROCESS_KPROBE"]}上面配置在 JSON
文件里会留下:(EXEC 或 EXIT) 且 namespace=foo,或者任意
PROCESS_KPROBE。同一事件若仍出现在
tetra getevents 里,符合
Caution,不是采集器坏了。
同一份 events.md 还描述 field filter 与
redaction:按 protobuf field mask 做 INCLUDE /
EXCLUDE;redaction 用 RE2
捕获组把参数/环境变量替换成 "*****"。这些同样
只改文件里的 JSON 形态,不改 gRPC
流上的对象(过滤分层仍以第 4 篇为准)。SIEM
侧若发现「有事件但字段空了」,先查 field
filter,再查策略是否没取到该参数。文档 redaction 例子会把
"--password=foo" 写成
"--password=*****"——本篇不把它扩成密文处理教程。
本篇不写某个厂商的 source / sourcetype / ingest
pipeline。工程边界是:日志产品只消费 Tetragon
愿意写进文件的那一子集。 若审计要求「与
tetra 所见一致」,文件 sink 满足不了,必须接
gRPC,并接受第 4 篇已经写出的过滤分层。
导出完备性仍是开放问题:JSON 与 gRPC 所见集合在配置
allow/deny 之后故意不对齐。升版改 socket
之后,第三方若静默失败,SIEM 会表现为「突然没日志」,而
tetra
在节点上仍然有事件——这是客户端连错地址,不是节流。
三、gRPC
默认地址:localhost:54321 不再是 v1.7.0
缺省
Upgrade notes · Helm Values:
把 agent 默认
server-address从localhost:54321改为/var/run/tetragon/tetragon.sock。该 socket 对节点上的 root 用户在同一路径可用。所有连接到 agent 的第三方程序都要更新这个地址。
events.md 把默认 helm 安装写成
unix:///var/run/tetragon/tetragon.sock,可用
--server-address 覆盖。daemon-configuration
给出两种写法:--server-address unix:///var/run/tetragon/tetragon.sock,或
drop-in 文件
/etc/tetragon/tetragon.conf.d/server-address
内容为同一 URI。tetra 未指定
--server-address 时会尝试探测本机 daemon
配置。文档 caution:Unix socket 仅限特权用户。
flowchart LR
agent["Tetragon agent"]
agent -->|"file sink allow deny redaction"| json["tetragon.log lumberjack"]
json --> siem["Log pipeline SIEM"]
agent -->|"gRPC unfiltered"| sock["unix:///var/run/tetragon/tetragon.sock"]
sock --> tetra["tetra getevents"]
sock --> third["Third-party gRPC client"]
破坏面(机制,非某 SDK 的 changelog):
- 仍拨
localhost:54321的 sidecar、operator、自研 collector 会连接拒绝或连到空端口。 - 相对路径写错成
unix://var/run/...(少一杠)时,URI 解析与 Tetragon 期望的unix:///var/run/...不一致。 - 非 root 容器没有权限打开该 socket,表现为「gRPC 没事件」,JSON 文件可能仍在写。
- 把 socket 路径从宿主机 mount 进 sidecar 时,路径必须与 agent 实际 listen 的 path 一致;Upgrade notes 写该 socket「对节点上 root 在同一路径可用」,没有承诺任意容器命名空间都能看见它。
events.md 里仍出现
--set tetragon.grpc.address=localhost:54321 的
helm 示例:那是显式改回 TCP 的方法,不是
v1.7.0 的默认。第三方文档若还写死 54321,以 Upgrade notes
为准。需要 TCP 时必须显式配置,并接受「监听在 localhost 上的
gRPC 谁能连」与 Unix socket
特权模型不同——本篇不评价哪种更安全,只要求客户端与 agent
用同一地址族。
同一次 Events/gRPC 节还删除了 legacy
stacktrace-tree:GetStackTraceTree
gRPC、tetra stacktrace-tree、相关
protobuf。栈要改走 TracingPolicy Post 的
kernelStackTrace /
userStackTrace(见
examples/tracingpolicy/stack_traces.yaml)。已废弃的
EnableTracingPolicy /
DisableTracingPolicy 现在会返回错误,除非打开
enable-deprecated-tracingpolicy-grpc。这些都会让「旧客户端」在升到
v1.7.0 后失败;本篇只点名,不重写第 5、6 篇的加载路径。
四、一张表:升版后运维信号怎么用
| 问题 | 优先看 | 不能证明 |
|---|---|---|
| 旧 Grafana 面板空了 | merge 指标是否仍用已删除的两个名字 | 策略未加载 |
SIEM 比 tetra 事件少 |
第 4 篇
Caution;allow/deny;events_exported_total |
内核选择器没匹配 |
tetra 与 SIEM 都少 |
第 11 篇 THROTTLE / ringbuf lost | 单纯「导出路径写错」 |
| 第三方客户端全断 | server-address 是否仍是 54321 |
JSON 轮转坏了 |
| 轮转后出现空洞 | lumberjack 文件名与采集
inode;export_ratelimit_events_dropped_total |
Override 没生效 |
| 有事件但参数被星号替换 | redaction filter | hook 没取到参数 |
事故回顾时建议排成三列,缺哪列就进哪一层,不要从 YAML 改起:
| 列 | 证据 |
|---|---|
| 内核是否发生 | 策略加载成功、hook 符号存在、enforcement mode(第 10 篇) |
| agent 是否见到 | tetragon_events_total、ringbuf
received/lost、THROTTLE |
| 文件是否写出 | events_exported_total、allow/deny、轮转后的路径 |
不写具体 dashboard。可核对的工程动作是:把告警表达式迁到
tetragon_generic_kprobe_merge_total{status=...};把
gRPC 客户端改为
unix:///var/run/tetragon/tetragon.sock;把 SIEM
的输入钉在 tag 文档的文件路径,并承认它与 gRPC
不是同一集合。
tetragon_events_total(pkg/metrics/eventmetrics
的 EventsProcessed)计数的是 agent
处理过的事件类型,带 process labels。它高于
events_exported_total 时,差额可能来自 JSON
过滤、导出限流、或根本没开文件导出。不要用
events_total 当 SIEM 摄入量的代理。
升版清单(只含本篇范围,不是完整 Upgrade notes):
- 改 scrape 与告警里的 merge 指标名。
- 改第三方
--server-address/ 客户端 target。 - 删掉
tetra stacktrace-tree与GetStackTraceTree调用。 - 确认
EnableTracingPolicy/DisableTracingPolicy客户端是否依赖已强制报错的 API。 - 核对 JSON 路径仍是
/var/run/cilium/tetragon/tetragon.log或你显式设置的export-filename。
五、学术谱系、争论与开放问题
本篇偏运维,论文只收一条与「监视器看见的集合」有关的线。Garfinkel(NDSS 2003)整篇的前提是:安全工具声称观察到的系统调用集合,必须和内核实际发生的集合有可陈述的关系。Tetragon 把过滤拆到内核选择器、cgroup-rate、环缓冲、JSON allow/deny、导出限流多层之后,没有任何一层的计数器单独等于「真实发生」。merge_total 是配对尝试;exported_total 是文件写出;ringbuf lost 是没进用户态。导出完备性——能否对一次事故重建「内核发生 / agent 见到 / SIEM 见到」三列——仍开放。
争论:文件 sink 简便 vs gRPC 完整
| 侧 | 主张 | 代价 |
|---|---|---|
只采 tetragon.log |
适配现有日志管道;allow/deny 可降量 | 与 tetra 所见故意不一致;轮转与 inode
跟踪 |
| 只采 gRPC | 看见未经 JSON 过滤的流 | v1.7.0 默认 Unix socket 打断旧 TCP 客户端;权限模型更严 |
没有文献规定 SIEM 必须接哪一侧。可检验命题是:事故回顾时能否说明缺口落在哪一层(第 13 篇口诀:先点名轴)。
开放问题:
- 三列对齐:内核发生、agent
见到、文件写出能否用同一套关联 id 对账。入口:第 4 篇
Caution;本篇
events_exported_totalvsringbuf_*。 - 升版指标迁移:删除的 merge 计数器会让历史告警静默。入口:v1.7.0 Upgrade notes Metrics。
- 停机窗口:persistent enforcement 留下阻断、导出管道为空(第 10 篇限制)。SIEM 如何记录「强制执行仍在、事件没有」。
六、小结
- v1.7.0 删除
tetragon_generic_kprobe_merge_errors_total与_ok_total,改用tetragon_generic_kprobe_merge_total的status标签。 tetragon_events_exported_*只描述文件导出;export_ratelimit_events_dropped_total是文件路径上的又一次丢弃。- SIEM 接到日志文件就只看见文件 sink;JSON denylist 挡不住
tetra。 - 默认 gRPC 为
unix:///var/run/tetragon/tetragon.sock,原localhost:54321客户端会断。 - 本篇不提供 Splunk/ELK 配置;下一篇用五轴把「无事件 / 误阻断 / 导出缺口」收成排障口诀。
七、参考资料
规范 / 官方文档(A)
- Tetragon v1.7.0 GitHub Release Upgrade
notes(Metrics 更名;默认
server-address;stacktrace-tree 删除)。 - Tetragon v1.7.0 Events —
docs/content/en/docs/concepts/events.md(JSON 路径/var/run/cilium/tetragon/tetragon.log;allow/deny Caution;gRPC URI)。 - Tetragon v1.7.0 Daemon configuration — Unix socket
写法与
export-filenamedrop-in 示例。
源码(A)
pkg/metrics/kprobemetrics/kprobemetrics.go(MergeTotal、status/curr_type/prev_type)@ v1.7.0pkg/metrics/consts/consts.go(MetricsNamespace = "tetragon")@ v1.7.0pkg/exporter/metrics.go、pkg/exporter/exporter.go(导出计数器;lumberjack 轮转;rateLimitDropped)@ v1.7.0pkg/observer/metrics.go(ringbuf 计数器,与第 11 篇交叉)@ v1.7.0
核心论文
- Garfinkel. Traps and Pitfalls: Practical Problems in System Call Interposition Based Security Tools. NDSS 2003(监视集合与真实发生的关系;本篇用于导出完备性,不重复 §4.3 全文)。
站内对照
实验台账
- 未采集本机
/metrics;不伪造 scrape。轮转行为以源码Rotate()与 tagevents.md为准。
→ 上一篇:节流与观测税 · 系列目录 · 下一篇:排障坐标系
读完这篇,下一步读什么
优先读同系列或同问题的下一篇,把单篇消费变成主题集群。
【Tetragon / eBPF】事件导出路径:JSON、gRPC、tetra 与过滤边界
钉清 Tetragon v1.7.0 事件离开 agent 之后的分流:文件 JSON、gRPC 与把 JSON 再喂给 tetra 不是同一集合;官方 Caution 写明 allow/deny 只作用于 file sink;field filter 与 redaction 各在哪一层生效。
【Tetragon / eBPF】Agent 生命周期:BTF、安装形态与三条策略加载路径
钉清 Tetragon v1.7.0 agent 从 BTF/CO-RE 发现到 sensor 挂载的失败表象;对照 DaemonSet 与主机安装;说明默认 gRPC Unix socket 与 kubectl/gRPC/静态文件三条路径如何进入同一 collection map。
【Tetragon / eBPF】TracingPolicy:CRD、三条加载路径与 collectionKey
钉清 TracingPolicy 与 TracingPolicyNamespaced 的差异;给出 v1.7.0 CRD 字段总表(含 fentries);说明 kubectl、gRPC、静态文件如何共用 collectionKey;并写明 Enable/Disable gRPC 在默认配置下返回错误。
【Tetragon / eBPF】运行时安全全景:缺口、五轴坐标系与 16 篇路线
相对 Cilium 数据面、可观测对照与 Falco 口号,钉清 Tetragon v1.7.0 运行时安全内核缺口;定义进程血缘、Sensor/Hook、策略加载、过滤分层、强制执行五条坐标系,给出 16 篇阅读路线。