2. Kustomize 基础回顾:kustomization.yaml 结构、resources、patches、configMapGenerator 等核心字段

在深入控制平面准入策略与 Kustomize 的适配之前,必须牢固掌握 Kustomize 的核心声明式配置模型。Kustomize 通过一个名为 kustomization.yaml 的清单文件,描述如何从一组基础资源(Base)生成、定制并输出最终的 Kubernetes 资源清单。本章将系统回顾其核心字段与工作流。

2.1 kustomization.yaml 顶层结构

kustomization.yaml 是 Kustomize 的入口文件,采用 YAML 格式。其顶层字段定义了资源来源、定制策略和生成器行为。以下是一个典型的结构示例:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

# 资源来源
resources:
  - deployment.yaml
  - service.yaml
  - namespace.yaml

# 名称前缀/后缀
namePrefix: prod-
nameSuffix: -v2

# 通用标签
commonLabels:
  app.kubernetes.io/managed-by: kustomize
  environment: production

# 通用注解
commonAnnotations:
  oncall: "sre-team"

# 补丁(Patches)
patches:
  - path: increase_replicas.yaml
    target:
      kind: Deployment
      name: web-app

# 配置映射生成器
configMapGenerator:
  - name: app-config
    files:
      - config/app.properties

# 密钥生成器
secretGenerator:
  - name: db-credentials
    literals:
      - username=admin
      - password=s3cret

# 镜像更新
images:
  - name: nginx
    newTag: 1.25.3

# 资源副本数
replicas:
  - name: web-app
    count: 5
关键理解:Kustomize 遵循“声明式覆盖”原则——你不需要修改原始 YAML,而是通过 kustomization.yaml 描述“如何修改”。这种模式天然适合与策略引擎(如 OPA/Gatekeeper、Kyverno)协同工作,因为策略可以在资源合并的各个阶段进行校验。

2.2 resources 字段:定义基础资源

resources 字段是 Kustomize 的起点,它列出所有需要被纳入最终输出的原始 Kubernetes 资源文件。这些文件可以是本地路径,也可以是远程 URL(通过 https:// 或 git:// 协议)。

资源来源类型 示例 说明
本地文件 resources: [ deployment.yaml ] 直接引用当前目录或子目录下的 YAML 文件
本地目录(Kustomization) resources: [ ./base/ ] 引用另一个包含 kustomization.yaml 的目录作为子基础
远程 URL resources: [ https://raw.githubusercontent.com/... ] 从 Git 仓库或 HTTP 服务器拉取资源清单

资源合并顺序:Kustomize 按照 resources 列表中声明的顺序加载资源,但最终输出时会按 Group/Version/Kind 排序。这意味着补丁的生效顺序与资源加载顺序无关,而是由 patches 字段中的 target 选择器决定。

2.3 patches 字段:声明式定制

patches 是 Kustomize 最强大的定制机制。它允许你通过补丁文件或内联补丁,对已加载的资源进行增、删、改操作。Kustomize 支持两种补丁策略:Strategic Merge Patch (SMP) 和 JSON Patch (RFC 6902)。

2.3.1 Strategic Merge Patch (SMP)

SMP 是 Kustomize 的默认补丁方式,它基于 Kubernetes 原生资源的结构化合并逻辑。补丁文件只需包含要修改的字段,Kustomize 会自动将其合并到目标资源中。

# patches/increase_replicas.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 10

在 kustomization.yaml 中引用:

patches:
  - path: patches/increase_replicas.yaml
    target:
      kind: Deployment
      name: web-app

2.3.2 JSON Patch (RFC 6902)

当需要执行更精细的操作(如删除字段、替换数组元素)时,可以使用 JSON Patch 语法。补丁文件以数组形式描述操作序列。

# patches/remove_label.yaml
- op: remove
  path: /metadata/labels/unused-label
- op: replace
  path: /spec/replicas
  value: 5

在 kustomization.yaml 中通过 patchesJson6902 字段引用:

patchesJson6902:
  - target:
      kind: Deployment
      name: web-app
    path: patches/remove_label.yaml
策略适配要点:当使用 OPA/Gatekeeper 或 Kyverno 对 Kustomize 输出进行准入校验时,patches 阶段是策略冲突的高发区。例如,一个补丁可能试图将 replicas 设置为 10,但策略要求最大副本数为 5。理解补丁的合并顺序和覆盖规则,是编写兼容性策略的前提。

2.4 configMapGenerator 与 secretGenerator:动态生成配置资源

configMapGenerator 和 secretGenerator 是 Kustomize 的生成器字段,用于从文件、字面量或环境变量动态创建 ConfigMap 和 Secret 资源。它们解决了手动编写 ConfigMap/Secret YAML 的繁琐问题,并自动处理名称哈希以避免配置更新时的滚动更新问题。

生成器字段 数据来源 输出资源类型 名称哈希行为
configMapGenerator files, literals, envs ConfigMap 默认追加哈希后缀(如 app-config-6c8b9d)
secretGenerator files, literals, envs Secret 默认追加哈希后缀(如 db-credentials-f72h4k)

示例:从文件生成 ConfigMap

configMapGenerator:
  - name: app-config
    files:
      - config/app.properties
      - config/logback.xml

示例:从字面量生成 Secret

secretGenerator:
  - name: db-credentials
    literals:
      - username=admin
      - password=s3cret
    type: Opaque
策略影响:生成器产生的资源名称包含不可预测的哈希值。如果准入策略中硬编码了 ConfigMap 或 Secret 的名称(例如 app-config),则策略将无法匹配实际生成的资源(如 app-config-6c8b9d)。策略应使用标签选择器或通配符模式来适配这种动态命名。

2.5 Kustomize 资源合并流程总览

下图展示了 Kustomize 从加载基础资源到输出最终清单的完整流程,以及策略引擎可能介入的检查点:

Kustomize 资源合并流程与策略检查点 1. 加载基础资源 resources 字段 2. 应用生成器 configMapGenerator / secretGenerator 3. 应用补丁 patches / patchesJson6902 4. 后处理 namePrefix / commonLabels / images 5. 输出最终清单 kustomize build 输出 策略引擎(OPA/Gatekeeper / Kyverno)检查点 • 检查点 A:加载基础资源后 —— 校验基础资源是否违反基线策略(如禁止 privileged 容器) • 检查点 B:生成器执行后 —— 校验生成的 ConfigMap/Secret 命名是否符合命名规范 • 检查点 C:补丁应用后 —— 校验补丁是否引入安全风险(如暴露 NodePort)

2.6 核心字段对比总结

下表汇总了 Kustomize 核心字段的作用、执行阶段及其对策略适配的影响:

字段 作用 执行阶段 策略适配关注点
resources 定义基础资源来源 阶段 1(加载) 基础资源本身是否合规
configMapGenerator 动态生成 ConfigMap 阶段 2(生成器) 生成后的名称哈希、数据内容校验
secretGenerator 动态生成 Secret 阶段 2(生成器) 敏感数据编码、命名规范
patches 声明式修改资源 阶段 3(补丁) 补丁是否违反安全策略、覆盖顺序
patchesJson6902 JSON Patch 操作 阶段 3(补丁) 操作路径是否正确、是否误删关键字段
namePrefix 为所有资源添加名称前缀 阶段 4(后处理) 策略中的资源名称匹配规则
commonLabels 为所有资源添加标签 阶段 4(后处理) 标签是否与策略选择器冲突
images 更新容器镜像标签 阶段 4(后处理) 镜像来源是否允许、标签是否固定
replicas 设置副本数 阶段 4(后处理) 副本数是否在策略允许范围内

2.7 实践建议:为策略适配做好准备

  1. 使用 commonLabels 建立可预测的标签体系:策略引擎通常依赖标签选择器来匹配资源。在 Kustomize 中统一添加 app.kubernetes.io/managed-by: kustomize 等标签,可以简化策略的编写。
  2. 避免在策略中硬编码生成器输出的名称:由于 configMapGenerator 和 secretGenerator 会添加哈希后缀,策略应使用标签选择器或正则表达式来匹配这些资源。
  3. 在补丁阶段提前验证:如果使用 Kyverno,可以在 Kustomize 的补丁应用后、输出最终清单前,通过 Kyverno 的 mutate 规则进行二次校验,确保补丁不会引入不合规的配置。
  4. 理解补丁的幂等性:多次应用同一个补丁应产生相同的结果。策略引擎在审计时,应能识别补丁的重复应用不会导致资源状态漂移。
下一步:在掌握了 Kustomize 的核心字段和合并流程后,第 3 章将深入分析 Kustomize 资源合并的详细机制,包括多层级覆盖、变量替换和 Helm 集成,为后续策略适配打下更坚实的基础。