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
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
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
app-config),则策略将无法匹配实际生成的资源(如 app-config-6c8b9d)。策略应使用标签选择器或通配符模式来适配这种动态命名。
2.5 Kustomize 资源合并流程总览
下图展示了 Kustomize 从加载基础资源到输出最终清单的完整流程,以及策略引擎可能介入的检查点:
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 实践建议:为策略适配做好准备
- 使用
commonLabels建立可预测的标签体系:策略引擎通常依赖标签选择器来匹配资源。在 Kustomize 中统一添加app.kubernetes.io/managed-by: kustomize等标签,可以简化策略的编写。 - 避免在策略中硬编码生成器输出的名称:由于
configMapGenerator和secretGenerator会添加哈希后缀,策略应使用标签选择器或正则表达式来匹配这些资源。 - 在补丁阶段提前验证:如果使用 Kyverno,可以在 Kustomize 的补丁应用后、输出最终清单前,通过 Kyverno 的
mutate规则进行二次校验,确保补丁不会引入不合规的配置。 - 理解补丁的幂等性:多次应用同一个补丁应产生相同的结果。策略引擎在审计时,应能识别补丁的重复应用不会导致资源状态漂移。