在 Kubernetes 日常运维中,同一套应用往往要在开发、测试、生产多套环境间反复拷贝 YAML,稍不注意就出现配置漂移。Kustomize 是 kubectl 自带的声明式配置管理工具,它不引入模板语言,而是用 base 与 overlay 的方式”补丁式”复用配置,让多环境差异化部署变得可控、可审计、可回滚。
一、为什么需要 Kustomize
设想一个常见场景:你在开发环境用一份 Deployment,上线生产时要把镜像 tag 改掉、副本数从 1 加到 3、加上资源限制与 Ingress。最直接的做法是 copy 一份 YAML 再手动改——但这正是配置地狱的起点:两份文件会逐渐分叉,谁也说不清生产到底用了哪份。Helm 用 Go template 解决复用,灵活却学习曲线陡、调试时满屏报错难以定位。Kustomize 走另一条更朴素的路:把”基础配置”和”环境差异”彻底分开,环境文件只描述”改了什么”,而不是把整份配置重写一遍。这种声明式、纯 YAML 的思路天然契合 GitOps,每一次变更都在 Git 历史里可追溯,也更容易做代码评审。
二、核心概念:base 与 overlay
理解 Kustomize 只需抓住两个词。base 是应用的”标准形态”,包含 Deployment、Service 等与环境无关的通用资源;overlay 则是某个具体环境(如 prod)对 base 的定制,它通过一个 kustomization.yaml 引用 base,再叠加自己需要的修改。关键在于:一个 base 可以被 dev、test、prod 多个 overlay 同时复用,而 base 本身只维护一份。这从根本上消灭了”拷贝后分叉”的问题——差异永远显式地写在 overlay 里,任何人打开 prod 目录都能立刻看清生产环境到底和基准差在哪里。当某个配置需要在所有环境统一调整时,你只需改 base 一处,所有环境自动继承。
三、快速上手:第一个 kustomization.yaml
先看 base 目录结构,它和普通 K8s 清单目录几乎一样,只是多了一个 kustomization 清单:
base/
├── deployment.yaml
├── service.yaml
└── kustomization.yaml
base/kustomization.yaml 只声明”我包含哪些资源”,并用 commonLabels 给所有资源统一打标签,省去逐个手写 label 的麻烦:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
commonLabels:
app: myapp
此时执行 kubectl kustomize base 就能看到注入了标签后的完整 YAML,它和手写的效果完全一致,但维护成本更低。
四、常用字段:images / patches / replicas
overlay 最常用的三个字段各有分工。images 不用改 base 里的 image 字段,直接在这里统一替换镜像名与 tag;replicas 覆盖副本数;patches 则能对任意字段做 JSON Patch 或 Strategic Merge 式的修改。比如生产环境要换镜像、提到 3 副本、并补上资源限制:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
images:
- name: myapp
newName: registry.example.com/myapp
newTag: v1.4.2
replicas:
- name: myapp
count: 3
patches:
- target:
kind: Deployment
name: myapp
patch: |-
- op: add
path: /spec/template/spec/containers/0/resources
value:
requests: { cpu: 100m, memory: 128Mi }
limits: { cpu: 500m, memory: 256Mi }
注意 patches 默认用 RFC 6902 JSON Patch,路径写错就会构建失败——这正是为什么一定要先用 kubectl kustomize 本地渲染核对。
五、多环境 overlay 实战
推荐的目录结构是一份 base、多份 overlay。生产 overlay 还可通过 namePrefix、namespace 做资源隔离,并挂载独立的 Ingress 资源:
overlays/prod/
├── kustomization.yaml
└── ingress.yaml
# overlays/prod/kustomization.yaml
resources:
- ../../base
- ingress.yaml
namePrefix: prod-
namespace: myapp-prod
部署时一步到位:先在本地渲染核对,再应用到集群:
kubectl kustomize overlays/prod
kubectl apply -k overlays/prod
apply -k 中的 -k 即 kustomize,kubectl 会先构建出最终 YAML 再下发,无需任何额外二进制。
六、Kustomize 与 Helm 怎么选
两者并非互斥,很多成熟团队的做法是:用 Helm 管理第三方中间件(如数据库、网关)的 Chart,用 Kustomize 收口自有业务的多环境配置。选型可参考下表:
| 维度 | Kustomize | Helm |
|---|---|---|
| 配置方式 | 声明式补丁(overlay) | Go 模板渲染 |
| 学习成本 | 低(纯 YAML) | 中(需学 template 语法) |
| 多环境 | overlay 目录原生支持 | 多 values 文件 |
| 调试体验 | 渲染结果即所见 | 模板报错较难定位 |
| 生态 | kubectl 内置 | Chart 仓库极其丰富 |
经验法则:自有业务、环境差异为主,优先 Kustomize;要复用社区成熟部署、参数化复杂度高,选 Helm。
七、ConfigMap 与 Secret 的 Kustomize 管理
配置与密钥是环境差异的重灾区。Kustomize 提供 configMapGenerator 与 secretGenerator,自动生成带哈希后缀的资源,并在引用处注入,实现”配置变了、Pod 自动滚动更新”。
configMapGenerator:
- name: myapp-config
files:
- app.properties
literals:
- LOG_LEVEL=INFO
secretGenerator:
- name: myapp-secret
files:
- secrets/db.password
生成的 ConfigMap 名会带内容哈希,base 里的 Deployment 用 configMapKeyRef 引用逻辑名即可——Kustomize 会在构建时把引用自动改写到带哈希的真实名称,彻底避免”改了配置但 Pod 没重启”的经典事故。
八、接入 GitOps:Argo CD 与 Flux
Kustomize 是 GitOps 的事实标准输入之一。Argo CD 与 Flux 都原生支持把 path 直接指向 overlay 目录,Git 一提交,控制器就自动把集群状态对齐到仓库里的声明。这让”环境差异”第一次拥有了版本控制:回滚一个环境,本质上就是 git revert 一次 overlay。配合 Jenkins 流水线 做镜像构建、用 K8s HPA 做弹性伸缩,就形成了从代码到集群的完整交付闭环。若用 GitHub Actions 跑 CI,可以把 kubectl kustomize 的渲染结果作为校验产物,在合并前就暴露 base 与 overlay 之间的引用冲突。
九、远程 base 与组件化复用
当多个服务共享同一套基础配置时,可以把 base 推到独立 Git 仓库,用 resources 指向远程地址,实现跨仓库复用:
resources:
- github.com/your-org/k8s-bases//webapp?ref=v1.2.0
通过 ?ref= 锁定版本,既享受复用红利,又不被上游随意改动击穿。组件化让”公司级基线”(如统一的安全上下文、资源配额、探针模板)沉淀为一处,新服务接入只需写极薄的 overlay。
十、常见坑与排障
实践中最容易踩的坑,以及对应处理方式整理如下:
| 现象 | 根因 | 处理 |
|---|---|---|
| apply 后配置没变 | ConfigMap 未用 Generator,Pod 未滚动 | 改用 configMapGenerator 注入哈希名 |
| Service 找不到后端 | 加了 namePrefix 后标签/选择子不一致 | overlay 统一加 namePrefix,引用自洽 |
| patch 构建失败 | JSON Patch 路径写错 | 先 kustomize 本地渲染再 apply |
| 远程 base 拉取慢/失败 | 网络或 ref 不存在 | 锁定 ref、检查仓库权限 |
此外,老版本 kubectl 内置的 Kustomize 能力较弱,建议 1.21+,或直接用独立 kustomize CLI 保证行为一致。和 Docker Compose 编排 配合时,本地用 Compose 起依赖服务做联调、集群用 Kustomize 管理多环境,是中小团队性价比很高的组合。
十一、小结
Kustomize 用”不重复、只描述差异”的极简理念,让 Kubernetes 多环境配置回归清爽。它不取代 Helm,而是与之互补:标准化底座用 Helm,环境收口用 Kustomize。把配置交给 Git、交给声明式,每一次发布都可追溯、可回滚,这才是可持续的云原生运维之道。当你厌倦了在 YAML 之间来回拷贝与手动 diff 时,Kustomize 会是你最顺手的那个工具。




