用 Kyverno 自动化 Confidential Containers 基础设施,让应用团队不再操心底层细节

2026-05-19 30 预计阅读时间:1 分钟
来源:cncf.io AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:10 分钟

Confidential Containers(CoCo)为容器工作负载提供了一层关键的安全隔离——即使在平台部分不可信的环境下,也能通过硬件可信执行环境(如 AMD SEV-SNP、Intel TDX)保护运行中的数据。但现实是:要让一个普通 Pod 跑在 CoCo 环境里,应用团队往往需要手动指定 runtimeClass、添加节点选择器、配置加密参数等一堆基础设施细节。这些细节既容易出错,又把安全策略的执行责任推给了不该承担它的人。Kyverno 的策略引擎恰好能解决这个问题——用声明式策略把 CoCo 的基础设施配置自动化,让应用团队只管写业务代码。

CoCo 的部署痛点在哪

一个标准的 Kubernetes Pod 要跑在 CoCo 环境中,至少需要以下改动:

  1. 指定 runtimeClass:必须设为 kata-cc 或对应运行时类,否则 Pod 仍跑在普通 runc 容器里。
  2. 节点调度约束:CoCo Pod 只能调度到启用了对应硬件特性的节点上,需要添加 nodeSelector 或亲和性规则。
  3. 镜像加密配置:某些场景下容器镜像需要加密拉取,涉及额外的 annotation 或 secret 引用。

应用开发者本该只关心业务逻辑,但现在却被迫理解底层安全架构。更麻烦的是,如果某个团队忘了加 runtimeClass,CoCo 的保护就形同虚设——Pod 照常运行,但没有任何机密性保障,且这种"静默失败"很难被发现。

Kyverno 如何接管这些配置

Kyverno 是 Kubernetes 原生的策略引擎,支持三种核心动作:验证(validate)、变更(mutate)、生成(generate)。在 CoCo 场景中,变更策略是主力——它能在 Pod 创建时自动注入所需的基础设施字段,应用团队提交的原始 YAML 完全不需要改动。

核心思路:

  • 应用团队提交一个普通 Pod 或 Deployment,不带任何 CoCo 相关字段。
  • Kyverno 的变更策略根据标签或命名空间等条件,自动为 Pod 注入 runtimeClassnodeSelector 和必要的 annotation。
  • 验证策略作为兜底,确保关键工作负载不会遗漏 CoCo 配置。

实战:用 Kyverno 策略自动注入 CoCo 配置

下面给出三个可以直接复制使用的 Kyverno 策略,覆盖最常见的 CoCo 自动化场景。

策略一:自动注入 runtimeClass

任何带 confidential-containers.io/enabled: "true" 标签的命名空间中的 Pod,自动设置 runtimeClassNamekata-cc

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: inject-coco-runtimeclass
spec:
  rules:
    - name: mutate-runtimeclass
      match:
        any:
          - resources:
              kinds:
                - Pod
              namespaceSelectors:
                matchLabels:
                  confidential-containers.io/enabled: "true"
      mutate:
        patchStrategicMerge:
          spec:
            runtimeClassName: kata-cc

使用前确保集群中已安装 CoCo 运行时类:

# 检查 runtimeClass 是否存在
kubectl get runtimeclass kata-cc

# 如果不存在,先创建(CoCo 安装脚本通常会自动创建)
kubectl apply -f - <<EOF
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: kata-cc
handler: kata-cc
overhead:
  podFixed:
    memory: "120Mi"
    cpu: "250m"
scheduling:
  nodeSelector:
    confidential-containers.io/runtime: "kata-cc"
EOF

策略二:自动添加节点选择器

CoCo Pod 必须调度到支持机密计算的节点。以下策略自动注入 nodeSelector

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: inject-coco-node-selector
spec:
  rules:
    - name: mutate-node-selector
      match:
        any:
          - resources:
              kinds:
                - Pod
              namespaceSelectors:
                matchLabels:
                  confidential-containers.io/enabled: "true"
      preconditions:
        all:
          - key: "{{ request.object.spec.runtimeClassName }}"
            operator: Equals
            value: "kata-cc"
      mutate:
        patchStrategicMerge:
          spec:
            nodeSelector:
              confidential-containers.io/runtime: "kata-cc"

注意 preconditions 确保只在 runtimeClass 已被设为 kata-cc 的 Pod 上追加节点选择器,避免对普通 Pod 误操作。如果两个策略同时生效,Kyverno 会按策略优先级顺序依次变更,最终 Pod 同时拥有 runtimeClassNamenodeSelector

策略三:验证兜底——阻止未启用 CoCo 的工作负载进入敏感命名空间

变更策略处理了"自动加上配置",但还需要验证策略防止"静默绕过"——确保标记为敏感的命名空间中,所有 Pod 都必须使用 CoCo 运行时:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: enforce-coco-runtimeclass
spec:
  validationFailureAction: Enforce
  rules:
    - name: require-coco-runtimeclass
      match:
        any:
          - resources:
              kinds:
                - Pod
              namespaceSelectors:
                matchLabels:
                  confidential-containers.io/enabled: "true"
      validate:
        message: "此命名空间要求所有 Pod 必须使用 kata-cc runtimeClass 以启用 Confidential Containers。"
        pattern:
          spec:
            runtimeClassName: "kata-cc"

validationFailureAction: Enforce 意味着不合规的 Pod 直接被拒绝创建,而不是仅记录告警。

完整部署流程

把以上策略组合起来,一个典型的部署流程如下:

# 1. 给目标命名空间打标签
kubectl label namespace sensitive-workloads confidential-containers.io/enabled=true

# 2. 安装 Kyverno(如果集群中还没有)
kubectl apply -f https://github.com/kyverno/kyverno/releases/download/v1.12.0/install.yaml

# 3. 应用三个策略
kubectl apply -f inject-coco-runtimeclass.yaml
kubectl apply -f inject-coco-node-selector.yaml
kubectl apply -f enforce-coco-runtimeclass.yaml

# 4. 应用团队提交一个普通 Deployment(无需任何 CoCo 字段)
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-sensitive-app
  namespace: sensitive-workloads
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-sensitive-app
  template:
    metadata:
      labels:
        app: my-sensitive-app
    spec:
      containers:
        - name: app
          image: myregistry.io/my-sensitive-app:v1.0
          ports:
            - containerPort: 8080
EOF

# 5. 验证 Kyverno 已自动注入配置
kubectl get deployment my-sensitive-app -n sensitive-workloads -o jsonpath='{.spec.template.spec.runtimeClassName}'
# 期望输出: kata-cc

kubectl get deployment my-sensitive-app -n sensitive-workloads -o jsonpath='{.spec.template.spec.nodeSelector}'
# 期望输出包含: confidential-containers.io/runtime=kata-cc

应用团队提交的 Deployment 中完全没有 CoCo 相关字段,但最终运行的 Pod 已经具备全部机密计算配置。

需要注意的边界与风险

  • 性能开销:CoCo 运行时(Kata Containers)有额外的内存和 CPU overhead,上述 RuntimeClass 定义中已声明了 120Mi / 250m 的固定开销。调度和容量规划时必须把这个开销算进去。
  • 策略冲突:如果集群中已有其他变更策略修改 Pod 的 nodeSelector,需要确认 Kyverno 的策略优先级和合并逻辑不会产生冲突。建议用 patchStrategicMerge 而非 patchJson6902,前者对 map 类型的字段会合并而非覆盖。
  • 镜像加密的局限:CoCo 的镜像加密拉取(image decryption)需要额外配置 key broker 和 secret 引用。Kyverno 可以通过生成策略(generate)自动创建关联的 Secret,但 key broker 的部署本身不在 Kyverno 的职责范围内,需要单独处理。
  • 调试难度:CoCo Pod 运行在虚拟机隔离环境中,传统的 kubectl execkubectl logs 行为会有差异。团队在迁移到 CoCo 前应先在测试环境验证调试流程。

落地建议

  1. 分阶段推进:先在非生产命名空间启用变更策略,观察注入结果和 Pod 运行状态;确认无误后再在敏感命名空间启用验证策略(Enforce 模式)。
  2. 命名空间驱动:用命名空间标签作为策略的触发条件,比逐个 Pod 打标签更易维护。新建敏感命名空间时只需打一个标签,所有工作负载自动获得 CoCo 保护。
  3. 监控策略执行:Kyverno 自带策略报告(PolicyReport)资源,定期检查可以发现变更失败或验证拦截的情况: bash kubectl get policyreport -n sensitive-workloads
  4. 与 GitOps 配合:Kyverno 策略本身是 Kubernetes 草案资源,可以纳入 Argo CD 或 Flux 的管理流程,确保策略变更也经过审批和版本控制。

把 CoCo 的基础设施配置从应用团队手中剥离出来,交给 Kyverno 自动执行,既减少了人为遗漏的风险,也让机密计算的采纳门槛大幅降低。应用开发者写的是普通 Deployment,跑出来的却是受硬件级隔离保护的 Pod——这才是安全基础设施该有的样子。


相关推荐