MutatingAdmissionPolicy 实践指南用声明式策略替代 Mutating Webhook【免费下载链接】websiteKubernetes website and documentation repo:项目地址: https://gitcode.com/GitHub_Trending/webs/websiteKubernetes 的 MutatingAdmissionPolicy 是一种在 API server 内部执行的声明式准入策略用 CEL 表达式在资源写入前直接修改对象解决注入默认值、强制字段这类必须部署外部 Mutating Webhook 才能完成的需求。本文面向需要治理集群资源形态的开发者与运维读完后你能判断它是否适合你的场景并部署出第一个可验证的策略。前提条件集群版本建议 v1.36该版本起特性默认开启且你具备集群管理员权限。先判断它适合解决哪类问题传统的 Mutating Admission Webhook 需要你自己维护一套组件一个能收到准入请求的 HTTPS 服务、证书轮换、服务发现、超时与故障兜底。而 MutatingAdmissionPolicy 把修改资源这件事收敛成两个 Kubernetes 原生对象逻辑用 CEL 写在策略里由 API server 进程内执行不再依赖额外服务。它解决的核心问题就一句话在资源创建或更新进入 etcd 之前自动改写对象内容。两者的边界先划清楚维度MutatingAdmissionPolicyMutating Webhook执行位置API server 进程内集群内/外部的独立服务需要部署的组件无只有两个声明式对象Webhook 服务、证书、LB/Service故障影响受failurePolicy约束无网络依赖Webhook 不可用时按 failurePolicy 处理请求表达能力CEL 表达式 两种 patch 类型任意编程逻辑可访问外部系统一句话选型能用 CEL 表达清楚的字段级修改优先考虑策略需要查询外部系统或复杂业务逻辑的仍用 Webhook。它也不是替代品全集——ValidatingAdmissionPolicy 负责只拦不改两者可以组合使用。搭一个能跑的最小策略一条完整生效的策略由两个对象组成缺一不可MutatingAdmissionPolicy描述改什么——匹配规则和 mutation 表达式MutatingAdmissionPolicyBinding描述对谁生效——通过spec.policyName引用策略名可选地用spec.matchResources收窄范围、用spec.paramRef挂参数。下面是一组官方示例仓库内 content/en/examples/access/manifest-admission-control/default-pod-security-baseline.yaml用途新建的 Namespace 如果没设置 Pod 安全等级标签就自动补上baseline。它覆盖了策略最常用的字段apiVersion: admissionregistration.k8s.io/v1 kind: MutatingAdmissionPolicy metadata: name: default-pod-security-baseline spec: matchConstraints: resourceRules: - apiGroups: [] apiVersions: [v1] operations: [CREATE] resources: [namespaces] matchConditions: - name: exclude-system-namespaces expression: !object.metadata.name.startsWith(kube-) - name: no-existing-label expression: !(pod-security.kubernetes.io/enforce in object.metadata.labels) mutations: - patchType: ApplyConfiguration applyConfiguration: expression: Object{metadata: Object.metadata{labels: {pod-security.kubernetes.io/enforce: baseline}}}配套的 Binding 只有一行关键字段apiVersion: admissionregistration.k8s.io/v1 kind: MutatingAdmissionPolicyBinding metadata: name: default-pod-security-baseline spec: policyName: default-pod-security-baseline几个容易看漏的点matchConstraints.resourceRules是粗筛API 组、版本、操作、资源名必须能匹配上才会继续评估matchConditions是细筛CEL 全部为真才执行 mutation按命名空间标签筛选不要写在matchConditions里——条件表达式中拿不到命名空间对象应使用matchConstraints或 Binding 的matchResources.namespaceSelector。用参数把策略和取值分开如果注入的值不想硬编码可以给策略加paramKind再由 Binding 的paramRef指向一个具体的参数资源。官方示例用一个 ConfigMap 承载默认值见 default-pod-security-configurable.yaml# 策略侧声明参数类型mutation 里直接用 params 变量 spec: paramKind: apiVersion: v1 kind: ConfigMap mutations: - patchType: ApplyConfiguration applyConfiguration: expression: Object{metadata: Object.metadata{labels: {pod-security.kubernetes.io/enforce: params.data.default}}}# Binding 侧指定参数资源的位置 spec: policyName: default-pod-security-configurable paramRef: namespace: kube-system name: default-pod-security-standard parameterNotFoundAction: Allow# 参数本体改这个 ConfigMap 就等于改策略行为 apiVersion: v1 kind: ConfigMap metadata: namespace: kube-system name: default-pod-security-standard data: default: baseline这样一套策略 参数 Binding的组合同一策略可以为不同命名空间注入不同的默认值不需要复制策略对象。注意参数资源要先创建Binding 才正常工作。两种 mutation 写法怎么选spec.mutations是一个列表每项二选一ApplyConfiguration或JSONPatch。选择标准很简单——给字段设值/补默认值用前者按 JSON 路径做增删改用后者。ApplyConfiguration声明式合并语义接近 Server-Side Apply。表达式必须用Object{...}构造写我想让对象长什么样。约束不能整体替换 map/array 这类原子结构有删掉未列出值的风险。JSONPatchRFC 6902 标准操作序列精确定位路径。表达式返回一个JSONPatch{...}数组每个元素含opadd/replace/remove/move/copy/test、path、value。用 JSONPatch 给 Pod 追加一个 initContainer官方示例见 content/en/examples/mutatingadmissionpolicy/json-patch-example.yamlmutations: - patchType: JSONPatch jsonPatch: expression: [ JSONPatch{ op: add, path: /spec/initContainers/-, value: Object.spec.initContainers{ name: mesh-proxy, image: mesh-proxy/v1.0.0, restartPolicy: Always } } ]两个实用细节路径尾部加/-表示向数组末尾追加不加-即/-前的裸-是向开头插入写 sidecar/initContainer 注入时别搞反标签键里含/或~时path 必须用jsonpatch.escapeKey()转义例如example.com/environment要写成jsonpatch.escapeKey(example.com/environment)否则会拼错路径。CEL 表达式里可用的请求上下文变量变量含义object本次请求的对象DELETE 时为 nulloldObject集群中已有对象CREATE 时为 nullparamsBinding 引用的参数资源策略声明了paramKind时可用namespaceObject对象所属 Namespace集群级资源为 nullrequest请求属性操作、用户等variables策略级复合变量按名字懒求值再次提醒matchConditions中不能用namespaceObject和variables只能用object、oldObject、request、params。另外apiVersion、kind、metadata.name、metadata.generateName、metadata.labels可以直接从对象根路径访问其余 metadata 字段不可访问。行为控制还有两个字段值得配置failurePolicy表达式求值出错时怎么办。Fail拒绝整个请求安全类策略选它Ignore跳过本次 mutation 让请求继续增强类策略选它reinvocationPolicy设为IfNeeded时本策略修改后的对象会继续走后续准入流程避免多个 mutation 互相覆盖的场景。如何验证策略生效、常见报错验证分三步看状态、试请求、确认结果。确认策略被 API server 接受且无冲突kubectl get mutatingadmissionpolicy default-pod-security-baseline -o yaml重点看status.conditionsReadyTrue表示表达式编译通过可以执行出现Conflicted说明它与别的策略在同一请求上产生冲突需要调整匹配范围。用 server-side dry-run 预览修改效果不落盘kubectl create ns demo-check --dry-runserver -o yaml如果策略生效输出对象里应出现pod-security.kubernetes.io/enforce: baseline标签。真实创建一个资源再检查最终状态kubectl create ns demo-real kubectl get ns demo-real --showLabels⚠️ 排错时按这个顺序查能覆盖绝大多数不生效Binding 缺失或名字对不上spec.policyName必须与策略的metadata.name完全一致引用不存在的策略时Binding 会被直接忽略操作类型不支持mutation 只对 CREATE、UPDATE、CONNECT 生效matchResources里写了 DELETE 也没用匹配条件错位先核对resourceRules的 apiGroups/apiVersions/resources再逐个核对matchConditions的 CEL 真值参数缺失策略声明了paramKind但paramRef指向的 ConfigMap/CR 不存在Binding 视为配置错误按failurePolicy处理请求被其他环节拦掉用--dry-runserver -o yaml对比无策略/有策略两次输出差异就是 mutation 的实际效果。还有一类硬性边界要记住通过 REST API 创建的 mutation 策略不能修改准入配置对象本身ValidatingAdmissionPolicy、MutatingAdmissionPolicy 及其 Binding也不能碰 TokenReview、SelfSubjectAccessReview 等认证鉴权虚拟资源——前者是防止循环依赖后者是防止把集群锁死在认证路径上。如果你的需求恰好是在静态清单里对全集群生效的内置策略那属于 manifest-based admission control 的范畴与本节讨论的 API 策略是两条路。什么时候该迁移、什么时候该坚持 Webhook适合直接用策略的场景注入默认标签/注解、补全 securityContext 默认值、给新对象打治理标签、按简单条件改写字段。共同特征是输入都在请求上下文里逻辑用 CEL 写得出来不需要外部数据。仍需 Webhook 的场景修改结果取决于外部系统查 CMDB、拉取配置中心、需要复杂多步业务逻辑、或已有成熟的 Webhook 平台且改造成本高于收益。从 Webhook 迁移的建议路径先在目标命名空间用 Binding 的namespaceSelector把策略灰度到小范围与线上 Webhook 并存观察一段时间两边对同一字段的修改顺序不可控避免同时改同一字段确认status.conditions稳定为 Ready、dry-run 输出符合预期后再收敛 Webhook 的覆盖范围。上线前的检查项# 集群版本 v1.36特性默认开启 kubectl version # 策略与 Binding 都在 kubectl get mutatingadmissionpolicies kubectl get mutatingadmissionpolicybindings # 灰度验证在测试命名空间执行 kubectl create ns policy-check --dry-runserver -o yaml后续延伸阅读官方概念文档 有完整的字段与 CEL 变量说明策略实操教程 覆盖了 Validating 与 Mutating 两类策略的完整演练流程。【免费下载链接】websiteKubernetes website and documentation repo:项目地址: https://gitcode.com/GitHub_Trending/webs/website创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考