【Tetragon / eBPF】K8s 身份感知策略:Namespaced、选择器与 hostSelector
内容提要
本文介绍Tetragon v1.7.0中TracingPolicy的选择器与内核过滤机制。TracingPolicyNamespaced仅作用于特定命名空间的Pod,podSelector和containerSelector分层匹配工作负载,hostSelector仅支持null或空值。无OCI hook时依赖API server可能产生竞态窗口。policyfilter默认在裸二进制关闭、Helm开启,关闭时需过滤的策略会加载失败而非静默全匹配。
延伸解读
策略不生效?先查 policyfilter 开关
很多“策略只打中部分 Pod”或“主机进程被误杀”的问题,根源不在 matchArgs,而在身份过滤链路。v1.7.0 中 policyfilter 默认在裸二进制关闭、Helm 开启。若关闭,需要 namespace 或 selector 过滤的策略会直接加载失败,日志出现 policyfilter is disabled,而不是静默全匹配。跨安装形态搬配置时,务必显式对齐 --enable-policy-filter 或 Helm 值。
hostSelector 的坑:v1.7.0 只认 null 和 {}
v1.7.0 的 hostSelector 不支持任意标签,只能为 null(默认)或 {}(匹配全部主机)。想排除主机,应保持 hostSelector 为 null,并显式写 podSelector;而不是写负向表达式。TracingPolicyNamespaced 禁止非空 hostSelector,否则触发 CRD 校验错误。注意 nodeSelector 是 v1.7.0 之后的能力,本篇不适用。
containerSelector 的 repo 字段有前提
policyfilter 运行时同时支持容器 name 和 repo 选择器,但 repo 依赖 ImageID 能按 @ 拆出前缀。若节点上 ImageID 不含 @,repo 可能为空字符串,导致选择器匹配失败。写策略时优先用稳定的容器 name;用 repo 前先确认运行时 ImageID 格式,避免策略静默不生效。
无 OCI hook 时的竞态窗口
官方文档明确:无 OCI hook 时,Tetragon 依赖 API server 信息 best-effort 应用策略。这会在容器启动与策略生效之间产生窗口,短生命周期容器或 informer 延迟时尤其明显。若要求“第一拍”就生效,需配置 OCI hook(见第 15 篇),仅加 podSelector 不够。
Q&A
Tetragon v1.7.0 中 TracingPolicyNamespaced 与集群级 TracingPolicy 的主要区别是什么?
TracingPolicyNamespaced 只作用于其所在 Kubernetes 命名空间内的 Pod,而集群级策略作用于整个集群。同名策略可以在不同命名空间各有一份,且与集群级空命名空间键不冲突。此外,TracingPolicyNamespaced 禁止非空 hostSelector,即不能匹配主机工作负载。
Tetragon v1.7.0 中 podSelector 和 containerSelector 是如何配合工作的?
podSelector 用于选择策略生效的 Pod,containerSelector 在 podSelector 的基础上进一步选择容器。如果只指定 podSelector 而 containerSelector 为 nil,则默认匹配 Pod 内所有容器。containerSelector 支持 name 和 repo 字段,其中 name 是容器名,repo 是从镜像 ImageID 中提取的仓库名。
在 Tetragon v1.7.0 中,hostSelector 支持哪些值?如何实现仅匹配主机工作负载?
在 v1.7.0 中,hostSelector 仅支持 null(默认)和 {}(空对象)。null 表示不显式选择主机,{} 表示匹配所有主机工作负载。要实现仅匹配主机,需设置 hostSelector: {},并保持 podSelector 和 containerSelector 为默认 null。
Tetragon 在没有 OCI hook 时如何应用命名空间策略?存在什么风险?
没有 OCI hook 时,Tetragon 会依赖 Kubernetes API server 的信息以 best-effort 方式应用策略。这可能导致短生命周期容器、启动竞态或 informer 延迟造成窗口,使策略可能晚于进程开始执行,从而漏掉部分事件。
policyfilter 在 Tetragon v1.7.0 中默认是开启还是关闭?关闭时加载需要过滤的策略会怎样?
policyfilter 在裸二进制中默认关闭,但在 Helm 安装中默认开启。关闭时,不需要过滤的全局策略仍可加载,但需要 namespace 或 selector 过滤的策略会加载失败,并出现 'policyfilter is disabled' 错误,而不是静默变成全匹配。
Tetragon v1.7.0 中 containerSelector 的 repo 字段是如何提取的?有什么注意事项?
repo 字段是从容器的 ImageID 中按 @ 分割取前半部分得到的(digest 形式)。如果运行时给出的 ImageID 不含 @,repo 可能为空字符串,导致选择器匹配失败。因此建议优先使用稳定的容器 name,使用 repo 前需确认节点上 ImageID 格式。