深色模式
Kustomize 基础与 overlay
摘要:本文面向需要在多环境间复用同一套 Kubernetes YAML、又不想引入模板引擎的工程师。覆盖 Kustomize 的 base/overlay 模型、
kustomization.yaml关键字段、生成器(Generator)与补丁(patch),并对比它与 Helm 的取舍。
适用版本与前提
- Kustomize:自 Kubernetes v1.14 起内置于
kubectl(kubectl apply -k);独立 CLIkustomize当前为 v5.x - Kubernetes:v1.25+
- 前提:已有可工作的原生 YAML(Deployment / Service 等)
背景与问题
Helm 用"模板 + 参数"生成 manifest;Kustomize 走另一条路:不引入模板语言,而是对现成的 Kubernetes YAML 做"声明式定制"。它的核心命题是——"同一套资源,如何为每个环境派生出变体,而不复制整套 YAML"。
典型场景:dev/staging/prod 共用同一个 Deployment 定义,只差副本数、资源配额、域名、镜像 tag。Kustomize 让你在 base/ 放一份"真源",在 overlays/<env>/ 放差异补丁,环境间零复制。
Kustomize 与 Helm 不是替代关系
选择标准(本文经验判断):要分发给多团队、参数化复杂的"通用包"用 Helm;维护同一套 YAML 的多环境变体、希望避免模板语法、贴近原生 YAML 的,用 Kustomize。二者也可组合(Argo CD 先 Helm 渲染再 Kustomize 叠加,或反之)。
核心概念:base 与 overlay
- base:一组资源及其共享配置的"真源",本身可被直接构建,但设计上是为了被 overlay 引用。
- overlay:引用一个或多个 base,并对其施加定制(改副本数、加前缀、注入 patch),每个 overlay 对应一个环境/变体。
- kustomization.yaml:每个目录一个,声明"这个目录如何被 kustomize 处理"。
kustomization.yaml 关键字段
yaml
# base/kustomization.yaml
resources:
- deployment.yaml
- service.yaml1
2
3
4
2
3
4
yaml
# overlays/prod/kustomization.yaml
resources:
- ../../base # 引用 base 目录
namePrefix: prod- # 所有资源名加前缀
namespace: production # 统一设置命名空间
labels:
- pairs:
env: production
includeSelectors: true # 同时改 selector,避免匹配失效
patches:
- path: replica-and-resources.yaml # 改副本数 + 资源
- target:
kind: Deployment
name: my-nginx
patch: |-
- op: replace
path: /spec/replicas
value: 51
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
namePrefix、namespace、labels、commonAnnotations 这类"横切字段"会被自动注入到所有资源及其 selector 上——这正是手写 YAML 最容易出错(改了 name 忘了改 selector)的地方,Kustomize 自动处理。
生成器(Generator)
ConfigMap / Secret 的内容常随环境变化且不应手填。Kustomize 用 configMapGenerator / secretGenerator 从文件或字面量生成,并自动追加内容哈希后缀,保证内容变更时生成新对象、触发滚动更新:
yaml
# overlays/prod/kustomization.yaml
configMapGenerator:
- name: app-config
files:
- config.properties
literals:
- LOG_LEVEL=INFO
generatorOptions:
disableNameSuffixHash: false # 默认带哈希后缀1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
哈希后缀的回滚陷阱
生成器默认带内容哈希后缀(如 app-config-8mbdf7882g)。若你的 Deployment 用 configMapRef 引用,内容变了会生成新 ConfigMap 并触发滚动更新——这是期望行为;但若其它地方硬编码了旧名字,会引用不到。需要稳定名字时用 generatorOptions.disableNameSuffixHash: true,但要自行承担"改了配置却不触发更新"的风险。
补丁(patch)机制
Kustomize 支持两种 patch 风格:
- Strategic Merge Patch(默认):写一份"局部 YAML",按字段合并。
- JSON6902 Patch:精确的
op/add/replace/remove,适合删除字段或改数组元素。
yaml
# overlays/prod/replica-and-resources.yaml(strategic merge)
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
replicas: 5
template:
spec:
containers:
- name: my-nginx
resources:
limits:
memory: 512Mi
requests:
cpu: 100m1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
推荐"小补丁做一件事":一个 patch 改副本数,另一个 patch 改内存限制,便于审阅与组合。
多环境 overlay 结构
目录示例:
text
app/
├── base/
│ ├── kustomization.yaml
│ ├── deployment.yaml
│ └── service.yaml
└── overlays/
├── dev/kustomization.yaml
├── staging/kustomization.yaml
└── prod/kustomization.yaml1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
生产实践
步骤 1:本地渲染校验
bash
kubectl kustomize overlays/prod # 仅渲染,不 apply
# 或等价独立 CLI
kustomize build overlays/prod1
2
3
2
3
步骤 2:应用
bash
kubectl apply -k overlays/prod --namespace production1
生产危险
kubectl apply -k 是对整个 overlay 应用,会创建/更新/删除其中声明的资源。执行前用 kubectl kustomize 确认产物,并结合 --dry-run=server 校验服务端接受度。误用 overlay 目录(如把 dev 当 prod)会造成环境错配。
进阶:Components(可复用片段)
Kustomize v3.7+ 引入 components——可在多个 overlay 间复用的"补丁包"(如统一的监控注解、网络策略),避免 overlay 间复制 kustomization 片段。
故障排查
namePrefix后 Service 找不到 Pod:未用includeSelectors: true,selector 没同步加前缀。base/overlay 里涉及 selector 的定制务必让 Kustomize 自动处理。- patch 报 "no matches for kind":patch 的
target字段(kind/name/apiVersion)与 base 资源不匹配;strategic merge 还要求 name 一致。 - 生成器名字带哈希导致引用错位:见上文哈希后缀陷阱。
Kustomize 与 Helm 取舍(再强调)
| 维度 | Kustomize | Helm |
|---|---|---|
| 是否引入新语言 | 否,纯 YAML 字段 | 是,Go template |
| 多环境 | overlay 目录天然隔离 | values 文件切换 |
| 资源生成(ConfigMap/Secret) | 内置 Generator | 需用模板/helper |
| 复杂逻辑 | 弱(仅 patch) | 强(条件/循环/函数) |
| GitOps 友好度 | kubectl 原生 -k,一等公民 | Argo CD/Flux 均支持渲染 |
版本相关
components 需要 Kustomize v3.7+(对应 kubectl v1.19+ 内置版本)。老集群内嵌的 kustomize 版本较旧,复杂特性可能不支持,生产前用 kubectl version 与 kustomize version 核对。
FAQ
Q:base 能直接 apply 吗? A:可以。base 是合法的可构建单元,通常作为"默认/参考"配置;overlay 在其上做环境定制。很多团队让 staging overlay 几乎等于 base,仅 prod 做强化。
Q:Kustomize 能做条件渲染吗? A:不能直接做(没有 if)。条件类需求要么拆 overlay,要么回归 Helm。这是 Kustomize 刻意的设计取舍——保持简单、贴近声明式。
参考资料
- Kubernetes: Declarative Management of Objects Using Kustomize(官方文档),访问日期:2026-10-08。
- Kustomize Official Site / Docs,访问日期:2026-10-08(站点部分路径重定向,核心概念以 kubernetes.io 官方任务文档为准)。
- Kustomize Glossary(官方文档),访问日期:2026-10-08。