Skip to content

准入与策略

准入控制发生在请求写入集群之前。用户或控制器把资源提交给 API Server 后,请求会经过认证、鉴权,再进入准入阶段。准入控制可以给资源补默认值、拒绝不符合规则的对象,或者把对象改写成符合集群要求的形式。

RBAC 解决“谁能做什么”,准入策略解决“允许创建什么样的资源”。一个用户有权限创建 Pod,不代表它可以创建特权容器、使用任意镜像、挂载宿主机根目录,或者把 Service 暴露成不受控的 LoadBalancer。

一、准入链路

Mutating Admission 可以修改对象,比如注入 sidecar、补 label、设置默认资源限制。Validating Admission 负责校验,不符合规则就拒绝。

准入策略常见于这些场景:

场景规则示例
镜像来源只能使用内部 Harbor 或指定仓库
安全上下文禁止 privileged、hostPID、hostNetwork
资源限制容器必须设置 requests/limits
标签规范namespace 或 workload 必须带 appenv
存储限制禁止使用 hostPath 或限制 StorageClass
入口规范Ingress/Gateway 必须使用指定域名后缀和 TLS

二、Pod Security Admission

Pod Security Admission 是 Kubernetes 内置的 Pod 安全策略机制,按 namespace 标签启用。

常见级别:

级别说明
privileged基本不限制,适合系统组件或受控命名空间
baseline阻止明显危险的权限
restricted更严格,要求非 root、限制能力和特权

给 namespace 加标签:

bash
kubectl label ns demo \
  pod-security.kubernetes.io/enforce=baseline \
  pod-security.kubernetes.io/audit=restricted \
  pod-security.kubernetes.io/warn=restricted

enforce 会直接拒绝不符合规则的 Pod;warn 返回警告;audit 写入审计日志。策略刚接入时,先用 warn/audit 观察现有工作负载,再逐步收紧 enforce,能减少突然阻断发布的风险。

三、ValidatingAdmissionPolicy

较新的 Kubernetes 版本支持内置的 ValidatingAdmissionPolicy,用 CEL 表达式写校验规则。它适合处理一些不需要外部系统参与的规则。

示例:禁止默认 namespace 创建业务 Pod:

yaml
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
  name: deny-default-namespace-pods
spec:
  matchConstraints:
    resourceRules:
      - apiGroups: [""]
        apiVersions: ["v1"]
        operations: ["CREATE"]
        resources: ["pods"]
  validations:
    - expression: "object.metadata.namespace != 'default'"
      message: "Pod should not be created in default namespace"

绑定策略:

yaml
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
  name: deny-default-namespace-pods
spec:
  policyName: deny-default-namespace-pods
  validationActions:
    - Deny

内置策略不需要额外部署 webhook 服务,故障面更小。但复杂规则、外部查询、镜像签名校验这类场景,通常还是用专门策略引擎。

四、Kyverno 和 Gatekeeper

Kyverno 和 Gatekeeper 都是常见策略引擎。

工具特点
Kyverno规则写成 Kubernetes YAML,支持校验、变更、生成、镜像校验
Gatekeeper基于 OPA/Rego,策略表达能力强,适合已有 OPA 体系

Kyverno 示例:要求容器设置 requests 和 limits:

yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-resources
spec:
  validationFailureAction: Enforce
  rules:
    - name: require-requests-limits
      match:
        any:
          - resources:
              kinds:
                - Pod
      validate:
        message: "CPU and memory requests/limits are required"
        pattern:
          spec:
            containers:
              - resources:
                  requests:
                    cpu: "?*"
                    memory: "?*"
                  limits:
                    cpu: "?*"
                    memory: "?*"

策略上线前最好先跑 audit 模式,看现有资源会命中多少。直接 enforce 可能导致存量应用无法滚动更新。

五、镜像策略

镜像策略常见规则:

规则原因
禁止 latest无法追溯和回滚
限制仓库域名防止直接拉公网未知镜像
要求 digest 或签名确认镜像内容未被替换
阻止高危漏洞镜像降低供应链风险
禁止明文 Secret 打进镜像防止敏感信息扩散

镜像签名和 SBOM 通常和 CI/CD、Harbor、Cosign、Trivy 这类工具联动。准入阶段负责兜底:没有通过构建扫描或签名校验的镜像,不允许进入集群。

六、排查准入拒绝

准入拒绝通常直接体现在 kubectl apply 输出里:

text
Error from server: error when creating "pod.yaml": admission webhook "validate.kyverno.svc" denied the request: CPU and memory requests/limits are required

排查顺序:

bash
kubectl get validatingwebhookconfigurations
kubectl get mutatingwebhookconfigurations
kubectl get validatingadmissionpolicy
kubectl get events -A --sort-by=.lastTimestamp
kubectl logs -n kyverno deploy/kyverno-admission-controller

如果 webhook 服务不可用,API Server 写请求可能被卡住或失败。策略引擎本身也要监控:Pod 状态、webhook 延迟、错误率、证书有效期、规则同步状态。

七、策略记录

策略不适合只存在集群里。规则 YAML、启用范围、audit/enforce 状态、例外名单、变更记录都要进 Git。策略变更影响发布入口,出现“应用突然发不上去”时,需要能查到是哪条规则挡住了。

几个适合纳入基线的策略:

类型基线
命名空间禁止业务资源落到 default
镜像限制内部仓库,禁止 latest
资源要求 requests/limits
安全禁止 privileged、hostPath、hostNetwork
标签要求 appenvowner 等基础标签

准入策略是集群最后一道写入门槛。规则写得太松,危险资源容易进来;规则写得太死,正常发布会被卡住。更稳的方式是规则有审计、有例外、有变更记录。