别把平台策略只做成闸门:Kubernetes Guardrails 的渐进式落地

2026-10-01 38 预计阅读时间: 1 分钟
来源: cncf.io AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:10 分钟

Kubernetes 策略工具的语言天然带有“阻断”色彩:Gatekeeper 像一道门,准入控制器负责拦截,策略失败通常意味着拒绝请求;Kyverno 的 validationFailureAction: Enforce 虽然听起来更中性,最终结果仍然是部署失败。

问题不在于阻断本身,而在于平台团队是否把“拒绝”当成了唯一手段。成熟的策略体系更像公路护栏:默认帮助团队保持在安全路径上,提前暴露偏差,只在风险足够明确时才真正封路。

策略不应该只有允许和拒绝

准入阶段的强制策略适合处理确定性高、后果严重且修复方式清晰的问题,例如:

  • 禁止特权容器;
  • 禁止使用明显危险的宿主机挂载;
  • 限制生产环境可使用的镜像仓库;
  • 阻止创建违反组织安全基线的公网入口。

但很多治理要求没有这么清晰。成本标签缺失、推荐副本数、镜像版本规范、资源配额建议等问题,通常更适合先报告和提醒。如果一开始就阻断,平台团队很容易制造三类副作用:

  1. 误报直接变成事故。 策略规则或资源匹配范围有误时,所有部署都可能停摆。
  2. 开发者只看到错误,不知道下一步。 一句“admission denied”不能代替迁移文档、修复命令和责任人信息。
  3. 例外转入地下。 当正式豁免流程太慢,团队会复制资源、换命名空间,甚至寻找绕过控制面的路径。

因此,可以把策略分成三个级别:

级别 行为 适合的问题
Observe 记录、生成报告和指标 新规则、资产盘点、影响未知的问题
Warn 在 CI、CLI 或部署界面提示,但不阻断 有明确建议、短期允许不合规的问题
Enforce 在准入阶段拒绝请求 高风险、低误报、已有修复路径的问题

策略从 Observe 升级到 Enforce,应该是一次有数据支持的发布,而不是在 YAML 中改一个字段就直接上线。

用 Kyverno 演示“先审计,后强制”

下面是一个可以改造的最小示例。假设集群已经安装 Kyverno,目标是在 policy-demo 命名空间中要求 Pod 包含 app.kubernetes.io/name 和 owner 标签。示例使用常见的 ClusterPolicy 写法;不同 Kyverno 版本的字段可能有变化,上线前可运行 kubectl explain clusterpolicy.spec 核对当前 CRD。

先创建测试命名空间:

kubectl create namespace policy-demo

保存以下内容为 required-labels.yaml。关键点是先使用 Audit,让不合规资源被记录,而不是被拒绝:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-workload-labels
  annotations:
    policies.kyverno.io/title: Require workload ownership labels
    policies.kyverno.io/category: Platform Governance
spec:
  validationFailureAction: Audit
  background: true
  rules:
    - name: check-required-labels
      match:
        any:
          - resources:
              kinds:
                - Pod
              namespaces:
                - policy-demo
      validate:
        message: >-
          Pods must define app.kubernetes.io/name and owner labels.
          See the internal workload onboarding guide or contact the platform team.
        pattern:
          metadata:
            labels:
              app.kubernetes.io/name: '?*'
              owner: '?*'

应用策略并创建一个不合规的 Pod:

kubectl apply -f required-labels.yaml
kubectl run unlabeled \
  --namespace policy-demo \
  --image=nginx:1.27 \
  --restart=Never

kubectl get pod -n policy-demo
kubectl get policyreport -n policy-demo

在审计模式下,Pod 应该仍能创建,违规信息则进入策略报告。平台团队可以先观察:有多少工作负载不合规、涉及哪些团队、规则是否误伤自动生成的 Pod,以及修复成本有多高。

确认规则稳定并完成通知后,再切换为强制模式:

kubectl patch clusterpolicy require-workload-labels \
  --type=json \
  -p='[{"op":"replace","path":"/spec/validationFailureAction","value":"Enforce"}]'

现在可以分别验证失败和成功路径:

kubectl delete pod unlabeled -n policy-demo --ignore-not-found

# 预期:被策略拒绝
kubectl run unlabeled \
  --namespace policy-demo \
  --image=nginx:1.27 \
  --restart=Never

# 预期:创建成功
kubectl run labeled \
  --namespace policy-demo \
  --image=nginx:1.27 \
  --restart=Never \
  --labels=app.kubernetes.io/name=demo,owner=platform

实际推广时,不要直接把匹配范围从测试命名空间扩大到整个集群。可以按非生产环境、低风险业务、生产业务的顺序逐步启用,并为每一步设置回滚条件。

Guardrail 还需要一条“铺好的路”

策略错误消息再清楚,也只是指出哪里不能走。平台团队还需要提供一条成本更低的合规路径,例如:

  • 在 Helm chart 或项目模板中默认生成必需标签;
  • 在 CI 中提前运行策略测试,不等请求到达集群才报错;
  • 给错误信息附上修复示例、文档位置和支持渠道;
  • 在内部开发者平台中展示策略报告,而不是只留在 Kubernetes CRD 中;
  • 对常见例外提供有时限、可审计的申请流程。

一个好的例外至少应包含以下信息:

exception:
  policy: require-workload-labels
  namespace: legacy-payments
  owner: payments-team
  reason: migration tool cannot add labels yet
  ticket: SEC-1842
  expiresAt: 2025-06-30

这段 YAML 是一种流程数据模型示例,并非某个策略引擎的通用 API。重点是例外必须有负责人、原因、追踪记录和到期时间。永久豁免如果没有复查机制,最终会把策略掏空。

强制策略也是生产依赖

一旦策略进入准入链路,它就不再只是安全配置,而是 Kubernetes API 可用性路径的一部分。平台团队需要像维护生产服务一样考虑:

  • 策略评估增加了多少准入延迟;
  • webhook 不可用时采用 fail-open 还是 fail-closed;
  • 策略升级失败时如何快速回滚;
  • 是否会匹配系统命名空间、控制器生成的资源或紧急修复任务;
  • 策略报告和拒绝次数是否进入监控;
  • 紧急豁免是否有审计记录。

failurePolicy: Fail 能在策略服务不可用时维持严格控制,却可能阻塞整个集群的资源变更;Ignore 能优先保证可用性,但会留下短暂的控制空窗。选择取决于策略保护的风险等级,不能为所有 webhook 使用同一个答案。

建议至少跟踪这些指标:

  • 每条策略的审计命中数与拒绝数;
  • 按命名空间或团队统计的违规分布;
  • 例外数量、平均存续时间和过期数量;
  • admission webhook 的错误率与 P95 延迟;
  • 策略从 Audit 升级到 Enforce 的周期;
  • 强制启用后部署失败率是否异常上升。

上线前的检查清单

平台策略可以阻断,但不应以阻断为设计起点。准备将一条规则升级为强制策略时,可以逐项确认:

  • 规则解决的是明确风险,而不只是风格偏好;
  • 已在 Audit 或 dry-run 模式中运行足够时间;
  • 已处理控制器生成资源、系统命名空间等边界情况;
  • 拒绝消息包含具体原因和修复方法;
  • 项目模板和 CI 已提供合规默认值;
  • 例外有负责人、审批记录和失效时间;
  • 有监控、回滚命令和紧急处置流程;
  • 受影响团队知道何时开始强制执行。

真正有效的 guardrail 并不追求“拒绝了多少部署”,而是减少开发者走错路的机会。只有那些高风险、低歧义并且已有清晰替代路径的问题,才值得在准入阶段成为一道真正的门。


相关推荐