登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  科技周边 >  业界新闻

Kubernetes ValidatingAdmissionPolicy 怎样减少准入 Webhook 依赖

来源:17golang原创

时间:2026-10-29 06:24:44 355浏览 收藏

我第一次认真拆准入 Webhook,是因为一个看似很小的校验规则也要经过独立服务、证书、超时和重试。规则本身只是“Deployment 的副本数不能超过某个值”,却把一次 API 请求变成了对外部服务可用性的依赖。

如果校验只需要读取请求对象,判断字段、标签、命名空间或用户信息,并返回允许或拒绝,那么 Kubernetes 的 ValidatingAdmissionPolicy 往往更合适。它用 CEL 在 API 服务器侧做声明式校验,再由 ValidatingAdmissionPolicyBinding 决定作用范围和处置动作。这样可以减少一部分 Webhook,但不是把所有 Webhook 都替换掉。

判断标准很简单:规则能否仅凭 Admission 请求及声明好的参数完成?能,就优先考虑 ValidatingAdmissionPolicy;需要调用外部系统、修改对象或执行复杂副作用,就保留相应的 Webhook 或其他扩展机制。

官方地址:https://kubernetes.io/docs/reference/access-authn-authz/validating-admission-policy/

先把“校验规则”和“外部能力”分开

ValidatingAdmissionPolicy 适合的是确定性的验证:字段是否存在、数值是否在范围内、标签组合是否满足约束、请求者是否属于某个用户组,以及对象和旧对象之间是否满足关系。CEL 表达式可以访问 Admission 请求中的对象字段,Binding 再把策略绑定到具体资源和命名空间。

我会先把旧 Webhook 的逻辑分成三类:

逻辑类型更适合的承载方式判断理由
只读请求对象的字段校验ValidatingAdmissionPolicy不需要网络调用,规则可以声明化
依赖外部 CMDB、镜像服务或授权中心保留 Webhook校验结果依赖 API 服务器之外的数据
需要修改对象内容使用对应的变更机制ValidatingAdmissionPolicy 的职责是验证,不是改写对象
需要副作用或复杂状态机保留专用服务不应把外部流程硬塞进 CEL
API 请求、ValidatingAdmissionPolicy、CEL、Binding 与准入 Webhook 外部依赖的静态职责关系说明图
图1:ValidatingAdmissionPolicy 与准入 Webhook 的职责边界说明图,不是 Kubernetes 控制台截图,也不是运行证据。

策略负责写规则,Binding 负责决定在哪里生效

一个常见误区是只创建 ValidatingAdmissionPolicy,然后期待它自动拦截请求。官方文档明确要求至少有策略和对应的 ValidatingAdmissionPolicyBinding,Binding 还需要配置一个或多个 validationActions。

下面这个例子只限制带有 team.example.com/owner 标签的 Deployment,并把副本数上限写成策略规则。代码中的注释只解释关键配置,便于后续维护。

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
  name: deployment-replica-limit
spec:
  failurePolicy: Fail # CEL 或策略配置出错时拒绝请求,适合必须守住的硬约束
  matchConstraints:
    resourceRules:
      - apiGroups: ["apps"]
        apiVersions: ["v1"]
        operations: ["CREATE", "UPDATE"] # 只检查创建和更新,不影响读取
        resources: ["deployments"]
  validations:
    - expression: "object.spec.replicas 

这里的拆分很重要:策略描述“什么算不合规”,Binding 描述“对谁生效以及失败后怎么处理”。如果一开始不想改变发布链路,可以把动作先设成 Warn 或 Audit,观察规则命中范围后再切换到 Deny。官方支持的动作包括 Deny、Warn 和 Audit,其中 Deny 与 Warn 不应同时使用。

用 CEL 和 matchConditions 收窄误伤范围

外部 Webhook 难维护,常常不是规则太复杂,而是匹配范围太宽。迁移到策略后,我更愿意先缩小资源、操作和命名空间,再用 matchConditions 过滤系统请求。所有匹配条件都为真时,策略才会继续评估。

spec:
  matchConditions:
    - name: exclude-leases # 避免把租约心跳纳入业务策略
      expression: "request.resource.group != 'coordination.k8s.io' || request.resource.resource != 'leases'"
    - name: exclude-node-users # 节点身份的系统请求不套用团队业务规则
      expression: "!(\"system:nodes\" in request.userInfo.groups)"
  validations:
    - expression: "has(object.metadata.labels) && 'team.example.com/owner' in object.metadata.labels"
      message: "Deployment 必须带有 owner 标签"

这里要特别留意故障策略。failurePolicy: Fail 表示策略配置错误或 CEL 评估出错时拒绝请求;Ignore 则让请求继续,但跳过这次策略。对核心安全约束,我会选择 Fail 并把表达式写得更窄;对试运行或非关键治理规则,可以先用 Ignore 或通过 Binding 使用 Warn、Audit。

需要不同环境阈值时,把参数放进 Binding

如果开发、测试、生产的阈值不同,不必复制三份 CEL。策略可以声明 paramKind,Binding 通过 paramRef 找到参数资源,表达式使用 params 读取阈值。这样规则保持稳定,环境差异落在参数对象和 Binding 范围上。

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
  name: deployment-replica-limit-by-environment
spec:
  failurePolicy: Fail # 参数或表达式出错时不放行,避免静默绕过限制
  paramKind:
    apiVersion: rules.example.com/v1
    kind: ReplicaLimit
  matchConstraints:
    resourceRules:
      - apiGroups: ["apps"]
        apiVersions: ["v1"]
        operations: ["CREATE", "UPDATE"]
        resources: ["deployments"]
  validations:
    - expression: "object.spec.replicas 

parameterNotFoundAction 不能省略思考:Allow 会把找不到参数当成通过,Deny 会让它进入策略的故障处理路径。对生产限制来说,参数对象丢失通常比一次请求失败更值得暴露,因此我更倾向显式使用 Deny,并给参数资源配置清楚的权限与生命周期。

Binding、命名空间筛选、matchConditions、参数资源与故障动作的静态关系说明图
图2:Binding、参数资源与故障策略的关系说明图,不是集群运行截图,也不是实际请求结果。

减少 Webhook 依赖时,别把边界推得太远

ValidatingAdmissionPolicy 最适合“请求进来后,根据已知字段给出确定判断”的场景。它不能替代所有准入扩展,也不应该为了减少服务数量而承载外部查询或复杂副作用。

  • 可以优先迁移:副本数、资源字段、标签组合、命名空间范围、用户组和对象新旧值关系等纯校验。
  • 谨慎迁移:需要大量参数、复杂表达式或跨团队维护的策略。先用 Warn/Audit 观察,再决定是否 Deny。
  • 保留 Webhook:需要查外部数据库、镜像签名服务、CMDB、实时配额,或者需要修改对象和触发副作用的逻辑。

我的落地清单是:先盘点旧 Webhook 的每条规则;为每条规则标出数据来源和失败影响;把纯校验拆成策略与 Binding;先用小范围命名空间和非阻断动作观察;最后才扩大范围并给关键规则设置明确的 failurePolicy 和参数缺失策略。这样减少的是不必要的网络依赖与运维面,而不是把 Webhook 当成必须消失的技术。

常见问题

只创建 ValidatingAdmissionPolicy 为什么没有效果?

因为还需要对应的 ValidatingAdmissionPolicyBinding,Binding 至少要指定 policyName 和 validationActions,并按需要设置资源或命名空间范围。

ValidatingAdmissionPolicy 能调用外部 HTTP 服务吗?

不要把它当作外部调用机制。它适合基于请求和声明参数做 CEL 校验;需要外部数据时,应评估保留 Webhook 或调整数据注入方式。

failurePolicy 和 validationActions 有什么区别?

failurePolicy 处理策略配置或表达式评估错误;validationActions 处理校验结果不满足时如何反馈,包括拒绝、警告或写入审计。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>