摘要

  • ValidatingAdmissionPolicyBinding 将策略、潜在的资源范围、可选参数和声明动作连在一起,但它不是某一次 API 请求的结果凭据。
  • Kubernetes 文档把资源匹配、参数解析、表达式计算、故障处理、动作选择和最终响应明确区分。
  • 可追溯的治理应把“看见某个绑定”与“证明某个请求被如何处理”保存为两类记录。

准入策略绑定很容易让人产生一种完成感。配置中有策略名称、有资源选择条件,也有 Deny、Warn 或 Audit 等动作;从页面上看,控制似乎已经落地。可是,这些字段首先描述的是可能适用的规则和预设的处置方式。它们没有给出请求主体、请求时间、被检查对象、匹配路径、表达式结果,或 API 服务器最后保存和返回了什么。因此,“绑定存在”与“控制已经执行”之间,仍有一段不能靠想象填补的证据链。

Kubernetes 对这段链的第一处边界写得很具体。ValidatingAdmissionPolicyBinding 把 ValidatingAdmissionPolicy 与参数化资源相连;绑定的 matchResources 会同策略的 matchConstraints 取交集。也就是说,一项请求须先满足策略侧的条件,绑定才可能进一步选择它。这个规则说明将来哪类请求可能被求值,却没有说明任何一个具体对象确实进入了交集。某个相关请求可能从未出现;请求可能未匹配;它还可能在之后的流程中被别的控制器改变或拒绝。仅凭绑定就写出“工作负载被拦截”,等于把这些未知步骤都写成了既成事实。

参数引用也不能被压缩成一个结论。绑定可以指向为策略提供参数的资源,文档同时区分该资源存在与不存在的状态。若引用的参数缺失,绑定可能被视为配置不当,策略的故障策略随之变得相关。这里涉及的是策略、绑定、参数对象和故障设置几个不同的控制面。它们的组合值得盘点,但不能直接证明请求获得了允许或拒绝的结果,更不能说明某个业务资产的风险已经被处置。

failurePolicy 与验证表达式返回 false 的差别尤其重要。Kubernetes 将前者用于解析、类型检查、运行时或配置错误;表达式计算为 false 时如何处置,则由绑定中的 validationActions 决定。Deny 表示验证失败会导致请求被拒绝;Warn 向请求客户端报告警告;Audit 将失败信息写入该请求的审计事件。它们不是同义的“已保护”标签。分别对应错误处理、表达式失败后声明的动作,以及与一项请求相关的可见效果。没有请求证据,就不能确定某个动作实际发生,更不能确定它是最终决定因素。

准入所处的位置进一步限制了推断。Kubernetes 说明,准入控制发生在认证和授权之后、持久化之前;变更和验证阶段彼此不同,任一阶段的拒绝都会结束该请求。绑定本身并不告诉读者此前授权是否允许、变更阶段是否修改过对象、另一项验证是否作出拒绝,或对象是否最终被保存。读取操作更是绕过准入层。由此可见,绑定清单不是集群全部访问、修改或保留结果的历史。

更窄的证据也因此更有价值。Kubernetes 文档中的验证失败审计注释关联一项 API 请求,并指出策略、绑定、失败表达式和已采取动作。它支持的是“这项请求留下了这条与验证有关的审计证据”这一有限命题,而不是“所有匹配请求都如此”或“整个集群因此安全”。边界不是缺点;它让后来的人能够复查证据来自哪里。

Daniel Kade 建议把两类信息并排保存。配置记录应包含策略和绑定的身份与版本、观察时间、范围条件、参数引用、故障设置和声明动作。结果记录则应包含请求身份与时间、匹配或跳过条件、参数状态、表达式计算、选择的动作、客户端响应以及持久化或拒绝的证据。这样的分离不是 Kubernetes 强制的数据模型。它只是阻止一份清楚的声明被误写成一次已经发生的执行结果。

来源

  1. Kubernetes API 参考 — ValidatingAdmissionPolicyBinding
  2. Kubernetes API 参考 — ValidatingAdmissionPolicy
  3. Kubernetes 教程 — 准入策略
  4. Kubernetes 文档 — 准入控制器
  5. Kubernetes 文档 — 审计注释