Kubernetes 集群数量增多后,配置管理最先暴露的问题往往不是技术选型,而是目录混乱。同一个应用在开发环境只有 2 个副本、内存 512Mi,到生产环境变成 10 个副本、内存 4Gi,镜像地址也从内部仓库的每日构建切换成正式版本。如果每个环境都复制一份完整 YAML,改一个健康检查参数就要同步五六个文件,遗漏几乎不可避免。Kustomize 的解决方式不是引入模板语法,而是把公共配置保留在 base 目录,环境差异通过 overlay 目录中的小片段补丁覆盖,最终渲染出各环境所需的完整清单。这种思路与 kubectl 原生的 -k 参数天然集成,不需要额外安装渲染引擎。

理解 base 与 overlay 的分层模型
base 目录中存放的是所有环境都会用到的资源定义,例如 Deployment、Service、ServiceAccount 等。这里不应该出现具体环境的字段,比如镜像标签、副本数、域名、资源配额。把这些公共内容收敛到 base 后,环境差异只需要在 overlay 目录中描述。overlay 不是一份完整清单,而是一组修改指令,它告诉 Kustomize 在渲染时如何对 base 进行补充或替换。
一个典型的目录结构如下:
.
├── base
│ ├── deployment.yaml
│ ├── service.yaml
│ └── kustomization.yaml
└── overlays
├── dev
│ ├── replicas.yaml
│ └── kustomization.yaml
├── staging
│ ├── replicas.yaml
│ └── kustomization.yaml
└── prod
├── replicas.yaml
└── kustomization.yaml
base/kustomization.yaml 负责声明该目录下哪些资源需要被纳入管理,通常会用 resources 字段列出 deployment.yaml 和 service.yaml。而 overlays/dev/kustomization.yaml 则通过 resources 字段指向 ../../base,再通过 patches 或 replicas 等字段覆盖差异。Kustomize 渲染时先加载 base,再依次应用 overlay 中的修改,整个过程是确定性的,不会像模板渲染那样依赖外部变量。
用补丁实现环境差异覆盖
最简单的情况是只改副本数。可以在 overlay 中声明 replicas 字段,直接覆盖 Deployment 的副本数,但生产环境通常还需要修改资源限制、环境变量、节点选择器等。此时更适合使用补丁文件。Kustomize 支持两种主要补丁方式:strategic merge patch 和 JSON 6902 patch。前者基于 Kubernetes 对象的字段语义进行合并,对列表类字段的合并规则更符合直觉;后者用 JSON Patch 语法精确指定操作,适合复杂结构或需要按索引替换的场景。
比如 base/deployment.yaml 中定义了一个 Nginx Deployment,副本数为 2。生产环境需要将副本数改为 10,并添加一个环境变量。可以在 overlays/prod 下创建一个 deployment-patch.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 10
template:
spec:
containers:
- name: nginx
env:
- name: LOG_LEVEL
value: info
在 overlays/prod/kustomization.yaml 中通过 patchesStrategicMerge 引用这个文件,Kustomize 会把该片段与 base 中的 Deployment 合并。注意这里的合并不是整体覆盖,而是只修改 replicas 和 env 中对应的部分,base 中原有的容器镜像、端口等字段仍然保留。这种局部修改能力是多环境管理的核心,也是直接复制完整 YAML 无法获得的。
如果补丁需要处理更精确的位置,例如修改某个特定索引的容器,可以使用 patchesJson6902。它需要指定 target 的 group、version、kind 和 name,然后给出 path 和 value。JSON 6902 补丁的优点是可控性更强,但可读性稍差。一般建议优先使用 strategic merge patch,只有遇到合并语义不符合预期时才切换到 JSON 6902。
生成器与镜像替换减少重复
多环境配置里经常出现的重复内容还包括 ConfigMap、Secret 和镜像地址。Kustomize 提供了 configMapGenerator 和 secretGenerator,可以从文件或字面量生成 ConfigMap 与 Secret,并自动为名称追加内容哈希。这样做的好处是配置变更后 Pod 会自动滚动重启,不需要手动修改 Deployment 中的注解。生成器声明的配置不直接写入 YAML,而是在构建时生成,减少了手工维护的清单数量。
configMapGenerator:
- name: app-config
files:
- application.properties
- name: env-config
literals:
- LOG_LEVEL=info
- FEATURE_FLAG=on
环境差异中的镜像地址可以用 images 字段统一替换。比如 base 中使用占位镜像 nginx:latest,生产 overlay 可以写为:
images:
- name: nginx
newName: registry.ipipp.com/prod/nginx
newTag: 1.24.0
注意这里的 name 匹配的是 Deployment 中 containers 里 image 字段的仓库名,而不是容器名。Kustomize 会查找所有使用 nginx 开头的镜像并替换为新名称和新标签,这在多团队协作时非常方便。namePrefix 和 nameSuffix 则用于给资源名称添加环境前缀或后缀,例如为每个 overlay 设置 namePrefix: dev-,可以避免不同环境部署到同一个命名空间时产生资源名冲突。
多集群实践与 GitOps 集成
当环境数量从三个增加到十几个集群时,目录设计需要更清晰。常见做法是按集群用途或环境类型组织 overlay,例如 overlays/dev/cluster-a、overlays/prod/cluster-b。也可以按团队或区域划分,再在各自目录中引用相同的 base。无论采用哪种结构,都应该保证 base 中不包含任何集群特定字段。如果一个 Deployment 的镜像地址在不同集群中不同,就把它放到 overlay,而不是复制一份 base 到新目录。
Kustomize 与 GitOps 工具非常契合。Argo CD 可以直接监听 Git 仓库中的 Kustomize 目录,检测到变更后自动执行构建并同步到目标集群。这样多环境配置的审计记录就完全落在 Git 提交历史中,谁改了什么、什么时候改的、改在哪个集群都一目了然。相比之下,直接使用 kubectl apply 修改运行中的集群容易产生配置漂移,时间长了很难还原真实状态。
在多集群场景中还需要注意权限边界。开发人员可能只被允许修改 dev 和 staging 的 overlay,生产 overlay 的合并请求需要运维或平台团队审批。Kustomize 本身不提供权限控制,但 Git 仓库的分支保护、CODEOWNERS 文件以及 CI 流水线可以完成这个任务。构建时可以通过 kustomize build overlays/prod 命令输出最终清单,在 CI 中做静态检查或安全扫描,确认无误后再由 Argo CD 同步。
Kustomize 配置管理中的常见误区
第一个误区是把 Kustomize 当成模板引擎使用。Kustomize 没有 if、else、循环等逻辑,也不支持在 YAML 中嵌入变量占位符然后从 values 文件渲染。它的设计目标是声明式覆盖,所有差异都要提前写成补丁或字段。这种限制看起来不灵活,但换来的是可预测性:构建结果只取决于 base、overlay 和 Kustomize 版本,不会因为环境变量不同而产生意外输出。如果确实需要复杂的条件逻辑,应该考虑 Helm 或者用 CI 生成 Kustomize 文件后再提交。
第二个误区是忽略 ConfigMap 生成器的哈希机制。直接修改 ConfigMap 的 YAML 文件不会触发 Deployment 滚动更新,因为 Pod 模板没有变化。但 configMapGenerator 会在名称后追加哈希,例如 app-config-7d58c9f6,这样 ConfigMap 内容变化时名称也变化,Deployment 引用新名称后 Pod 才会重建。如果手动用普通 ConfigMap,就需要自行在 Deployment 中添加版本注解或重启逻辑,容易遗漏。
第三个误区是环境目录层级过深,导致引用关系难以追踪。虽然 Kustomize 支持多层 overlay 叠加,但在实际项目中建议保持两层或三层:base 一层,环境一层,最多在环境下面再按集群拆分。层级太多会让补丁顺序变得复杂,排查问题时需要反复查看多个 kustomization.yaml。保持扁平的目录结构反而更容易让新成员理解。
Kustomize多环境配置Kubernetes修改时间:2026-09-17 13:20:26