返回首页

Chapter 6.5:Admission Controller

本章你将学会

  • Admission Controller 位于请求链路的什么位置
  • MutatingValidating 的差别是什么
  • 常见内置准入控制器分别干什么
  • 如何用准入机制统一落实安全与规范
  • 一个基于 OPA/Gatekeeper 的完整示例

1. Admission Controller 在请求链路中的位置

Kubernetes 官方对 admission controller 的定义很清楚:它会在请求通过认证与授权之后、资源写入持久化存储之前拦截请求。也就是说,Admission Controller 不是身份验证器,也不是 RBAC 替代品,而是资源进入集群前的最后一道规则门::cite[484]。

一个简化后的请求链路如下:

客户端请求
  -> Authentication(认证)
  -> Authorization(授权)
  -> Admission(准入)
  -> etcd 持久化

这条链路的意义非常大:

  • RBAC 允许“谁能操作”
  • Admission 约束“允许怎样操作”

例如,某个用户可能有权限创建 Deployment,但 Admission 仍然可以拒绝一个使用 :latest 镜像标签、缺少标签、启用特权容器、未设置资源限制的 Deployment::cite[484][485]。

2. Admission Controller 解决什么问题

在没有准入机制时,平台治理通常会遇到这些难题:

  • 同一团队 YAML 风格混乱,标签不统一
  • 有人总是忘记写资源限制
  • 安全规范写在文档里,但没有自动执行
  • 违规资源只能靠人工 code review 才发现

Admission Controller 的作用,就是把这些“应该遵守的规则”真正前置到 API 写入路径上,让规范从“建议”变成“机制”::cite[484]。

3. Mutating 与 Validating 的区别

Kubernetes 支持两大类准入扩展:

类型 作用 典型场景
Mutating 修改请求对象 自动补标签、自动注入 sidecar、补默认字段
Validating 校验请求对象 拒绝特权容器、要求必须有标签、禁止使用 latest

官方文档说明,Admission Webhook 本质上是 HTTP 回调。MutatingAdmissionWebhook 可以先修改对象,再把修改后的对象交给后续流程;ValidatingAdmissionWebhook 则用于判断这个对象最终是否可接受::cite[485]。

3.1 一个最实用的理解方式

  • Mutating:帮你“补”
  • Validating:帮你“卡”

例如:

  • Mutating:自动给 Pod 打上 team=platform
  • Validating:如果没有 team 标签,就拒绝创建

3.2 执行顺序要注意什么

通常来说,Mutating 会先执行,可能会有多轮变更;等对象稳定后,再进入 Validating 阶段。也正因为这样,设计 Mutating 规则时要尽量避免循环修改、幂等性差、顺序依赖太强的问题::cite[485]。

4. 常见内置 Admission Controller

Kubernetes 内置了很多 admission plugin,不同插件负责不同治理目标。下面列出几个最常见、也最值得优先理解的:

控制器 主要作用
NamespaceLifecycle 阻止对象写入不存在或终止中的 namespace
LimitRanger 为资源请求 / 限制提供默认值和约束
ResourceQuota 控制 namespace 资源总量上限
ServiceAccount 为 Pod 关联 ServiceAccount,并处理相关挂载逻辑
DefaultStorageClass 为 PVC 自动补默认 StorageClass
DefaultIngressClass 为 Ingress 自动选择默认 IngressClass
PodSecurity 按 namespace 级策略执行 Pod 安全标准
MutatingAdmissionWebhook 通过外部 Webhook 修改对象
ValidatingAdmissionWebhook 通过外部 Webhook 校验对象
ValidatingAdmissionPolicy 使用内置策略能力做校验

这些插件共同构成了“平台规则执行层”。有的是偏资源治理,有的是偏安全,有的是偏默认行为补全::cite[484]。

5. 内置控制器怎么配合安全治理

把它们放到一起看,会更容易理解平台设计:

  • RBAC:谁能创建 Pod
  • PodSecurity / ValidatingWebhook:这个 Pod 是否足够安全
  • LimitRanger / ResourceQuota:这个 Pod 是否符合资源治理要求
  • ServiceAccount:它会以谁的身份运行

所以 Admission Controller 不是某一个“安全插件”,而是 Kubernetes 治理体系中承上启下的一层。

6. 实操一:用内置能力统一资源规范

我们先看一个非常基础但很常用的例子:通过 LimitRangeResourceQuota 让团队至少写出合理的资源配置。

6.1 完整 YAML

apiVersion: v1
kind: Namespace
metadata:
  name: governance-demo
---
apiVersion: v1
kind: LimitRange
metadata:
  name: default-container-limits
  namespace: governance-demo
spec:
  limits:
    - type: Container
      default:
        cpu: 500m
        memory: 512Mi
      defaultRequest:
        cpu: 100m
        memory: 128Mi
---
apiVersion: v1
kind: ResourceQuota
metadata:
  name: namespace-quota
  namespace: governance-demo
spec:
  hard:
    requests.cpu: "2"
    requests.memory: 2Gi
    limits.cpu: "4"
    limits.memory: 4Gi
    pods: "20"

6.2 应用配置

kubectl apply -f governance-basics.yaml

这虽然不是 Webhook,但已经是准入治理思路的典型实践:当团队没写资源配置时自动补默认值;当 namespace 超出额度时直接拒绝::cite[484]。

7. 实操二:Pod Security 也是 Admission Controller 的一部分

内置的 PodSecurity admission controller 会在 Pod 创建时按照 namespace 标签执行 Pod Security Standards。下面是一个很常见的安全基线命名空间:

apiVersion: v1
kind: Namespace
metadata:
  name: secure-app
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/enforce-version: v1.32
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/audit-version: v1.32
    pod-security.kubernetes.io/warn: restricted
    pod-security.kubernetes.io/warn-version: v1.32

这说明 Admission Controller 完全可以内建承担“统一安全底线”的职责,而不一定一上来就依赖外部 Webhook::cite[484]。

8. Admission Webhook:把规则扩展到你的平台需求

当内置控制器不够时,就可以使用可扩展准入控制:

  • MutatingAdmissionWebhook
  • ValidatingAdmissionWebhook

它们通过 HTTP 回调接收 AdmissionReview 请求,从而让你把组织规则、业务规则、合规规则编码成平台策略::cite[485]。

这类机制特别适合处理:

  • 组织级标签规范
  • 镜像仓库白名单
  • 禁止 latest 标签
  • 强制设置 securityContext
  • 禁止使用特定 hostPath
  • 强制命名规则、Owner 标记、成本中心标签

9. OPA / Gatekeeper:把策略治理做成平台能力

OPA 是通用策略引擎,而 Gatekeeper 是与 Kubernetes 集成更紧密的一套实现。Gatekeeper 通过 admission webhook 执行策略,还提供了 ConstraintTemplateConstraint、审计等能力,让平台管理员可以把策略治理变成声明式对象管理::cite[508]。

Gatekeeper 官方文档强调了几个很关键的点:

  • 它既可以用于 admission 场景,也支持 audit 已存在资源
  • 它提供原生 Kubernetes CRD,用来承载策略模板和实例
  • 它同时支持 validating 与 mutating 能力::cite[508]

10. 实操三:用 Gatekeeper 统一标签规范

这个例子不是最复杂的安全策略,但非常适合入门:要求所有 Namespace 必须带上 ownerenv 标签。这类规则一旦靠人工约定,很容易失效;一旦放进准入机制,就会变成平台统一标准。

10.1 ConstraintTemplate

apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: k8srequiredlabels
spec:
  crd:
    spec:
      names:
        kind: K8sRequiredLabels
      validation:
        openAPIV3Schema:
          type: object
          properties:
            labels:
              type: array
              items:
                type: string
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8srequiredlabels

        violation[{"msg": msg, "details": {"missing_labels": missing}}] {
          provided := {label | input.review.object.metadata.labels[label]}
          required := {label | label := input.parameters.labels[_]}
          missing := required - provided
          count(missing) > 0
          msg := sprintf("you must provide labels: %v", [missing])
        }

10.2 Constraint

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
  name: namespace-must-have-owner-and-env
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Namespace"]
  parameters:
    labels:
      - owner
      - env

10.3 一个会被拒绝的 Namespace

apiVersion: v1
kind: Namespace
metadata:
  name: no-label-ns

10.4 一个能通过的 Namespace

apiVersion: v1
kind: Namespace
metadata:
  name: app-team-a
  labels:
    owner: team-a
    env: prod

这个例子体现的不是“标签有多重要”,而是:Admission 让规范真正变成了自动执行的集群规则。同样的机制,也完全可以用来约束镜像仓库、特权容器、hostPath、必填注解等安全要求::cite[508][266]。

11. 如果要做安全规则,应该怎么设计

下面是一套很实用的分层思路:

目标 更适合的机制
补默认值 MutatingAdmissionWebhook / 内置默认化控制器
卡底线安全规则 PodSecurity / ValidatingAdmissionWebhook / Gatekeeper
组织命名规范 ValidatingAdmissionWebhook / Gatekeeper
资源默认值和额度 LimitRanger / ResourceQuota
更原生的表达式校验 ValidatingAdmissionPolicy

11.1 先做少而硬的规则

准入治理最怕“一口气写几十条规则”,结果开发、运维、平台一起痛苦。更推荐的节奏是:

  1. 先建立少数必须执行的硬规则
  2. 先以 warn/audit 观察影响
  3. 再切换到强制拒绝
  4. 例外场景必须可审计、可回收

11.2 Mutating 规则要特别克制

Mutating 很强,但也最容易让人困惑。因为对象进入集群前被“偷偷改写”,如果没有清晰文档和可观察性,排障会非常痛苦。设计 Mutating 规则时,建议遵守这几条:

  • 幂等
  • 修改最小化
  • 修改结果可预测
  • 避免多个 webhook 相互打架::cite[485]

12. 常见误区

12.1 误区一:有了 RBAC 就不需要 Admission

RBAC 只决定“能不能发请求”,不决定“请求内容是否合规”。两者不是替代关系,而是配合关系::cite[484]。

12.2 误区二:Admission 只适合安全,不适合工程规范

其实标签规范、镜像规范、资源限制、命名规则都很适合通过 Admission 统一执行。

12.3 误区三:所有规则都写成 Mutating

自动帮你修,短期看似方便,长期可能让真实意图变得不可见。能校验拒绝的,优先校验;确实需要补默认值时再用 Mutating。

12.4 误区四:策略没有审计只有拦截

Gatekeeper 之所以常用,一个重要原因就是它不只会“拦”,还会“审”。很多平台策略成熟的标志,并不是拦得多,而是你能看见全局违规面并推动收敛::cite[508]。

13. 本章小结

Admission Controller 是 Kubernetes 治理链路中非常关键的一层。你需要记住:

  • 它位于认证、授权之后,持久化之前::cite[484]
  • Mutating 负责修改对象,Validating 负责最终校验::cite[485]
  • 内置控制器已经可以覆盖很多默认化、配额、安全与规范场景::cite[484]
  • PodSecurity 是内置安全基线,Webhook / Gatekeeper 则让你把组织策略继续扩展下去::cite[484][508]
  • 真正成熟的准入治理,不是规则越多越好,而是规则清晰、分层合理、例外可控、审计可见

到这里,Unit 6 的安全篇就串起来了:RBAC 管权限、ServiceAccount 管身份、PSS 管 Pod 能力边界、Secret 管敏感信息、Admission Controller 负责把规则真正执行进集群。这五部分合在一起,才是 Kubernetes 安全体系真正能落地的样子。


📝 版权声明:本文为原创技术博客,转载请注明出处。

如文章中存在错误或不准确之处,欢迎在评论区指正,感谢您的阅读与支持!

上一篇

6.2:ServiceAccount 与工作负载身份

下一篇

2.1 Pod 详解:最小调度单元