tetragon 默认只捕获 execve 系统调用,不捕获 shell 内建命令(如 cd、export)、重定向或管道中的子进程;process_exit 的 status 需右移 8 位才得真实退出码;export 变量变更无法直接观测,需通过 env 字段或 fork/exec 联动间接推断;process_fork 应启用以构建完整进程关系链。

为什么 process_exec 事件没抓到你想要的命令?
Tetragon 默认只捕获 execve 系统调用,不包括 shell 内建命令(如 cd、export)、重定向或管道中的子进程。它看到的是内核真正执行的二进制,不是你敲的那行 bash 命令。
- 如果你运行
echo $PATH,Tetragon 不会触发process_exec—— 因为echo是 shell 内建或已缓存的,且变量展开发生在用户态 -
process_exec只在新进程真正execve()时发出,比如ls -l、/bin/sh -c "sleep 1" - 某些容器运行时(如 containerd)可能用
clone()+execve组合,但 Tetragon 仍只对后者打点
# 正确能捕获的示例: $ /bin/bash -c "date" # Tetragon 会报告 /bin/bash 和 /bin/date 两次 process_exec
process_exit 的 status 字段怎么解读?
process_exit 里的 status 不是直接的退出码,而是原始 waitpid 返回的 16 位整数,需用 WEXITSTATUS() 宏解包(即 status >> 8)。直接当退出码用会错。
- 若进程被信号终止(如
kill -9),status & 0x7F是信号编号,WIFEXITED(status)为 false - Tetragon 导出的 json 中,
status是十进制整数,比如 256 表示正常退出码 1(256 = 1 - 未设置
wait4()或子进程变成僵尸前就退出,process_exit可能延迟或丢失(尤其高并发短命进程)
常见误读:"status": 35584 → 实际退出码是 35584 >> 8 == 139,对应 SIGSEGV(139 = 128 + 11)
如何让 export 变量变更也被观测到?
Tetragon 本身不监听环境变量修改,因为 export 是 shell 内建操作,不触发系统调用。要间接捕获,得靠上下文关联:
- 在
process_exec事件中检查env字段(需启用envprobe,且进程 exec 时带完整环境) - 启用
process_fork+process_exec联动:父进程(如 bash)fork 后,子进程 exec 前的环境可反映 export 结果 - 更可靠的方式是用 eBPF 额外挂载
tracepoint:syscalls:sys_enter_execve并读取argv和envp,但 Tetragon 默认不导出全部 envp(默认截断)
注意:env 字段在 Tetragon 输出里是数组,但只包含 exec 时传入的 key=value 字符串,不会告诉你哪条 export 语句改了它
模板里要不要加 process_fork?
加,但别只为“看到 fork”。它的价值在于补全父子关系链,否则 process_exec 和 process_exit 是孤立事件,无法判断谁启动了谁、谁等谁退出。
-
process_fork提供parent_pid和child_pid,配合process_exec的pid可构建进程树 - 不加 fork 模板时,你看到一个
curl的 exec 和 exit,但不知道它是 cron 启的还是 systemd 启的 - 性能影响极小(fork 是轻量系统调用),但日志量会上升;若只关心顶层容器进程,可过滤掉 UID > 0 的 fork(排除普通用户进程干扰)
典型漏配:只监听 exec/exit,结果发现某个 process_exit 找不到对应的 exec —— 很可能是 exec 发生在 fork 之后、而 fork 事件被过滤掉了