Kustomize 现代化使用教程与最佳实践

为什么选择 Kustomize?

Kustomize 是 Kubernetes 原生的配置管理工具(自 k8s 1.14 起内置于 kubectl)。与 Helm 的模板引擎(Template)不同,Kustomize 采用 Overlay(叠加) 的机制。

  • 无模板(Template-free):不需要学习复杂的模板语法(如 Go Template),直接操作原生的 YAML。

  • 声明式(Declarative):所有的修改都通过 YAML 文件声明,非常适合 GitOps 工作流。

  • 基础与覆盖(Base & Overlay):维护一份基础配置(Base),通过补丁(Overlay)派生出开发、测试、生产等不同环境。


核心概念与目录结构

一个符合现代最佳实践的 Kustomize 项目结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
~/my-project
├── base # 【基础层】存放通用的资源定义
│ ├── deployment.yaml
│ ├── service.yaml
│ └── kustomization.yaml
└── overlays # 【覆盖层】存放各环境的差异化配置
├── dev # 开发环境
│ ├── patch-replicas.yaml
│ └── kustomization.yaml
└── prod # 生产环境
├── patch-resources.yaml
└── kustomization.yaml

基础层(Base)配置

我们在 base 目录中定义所有环境共用的资源。

准备资源文件

base/deployment.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
# 注意:副本数等差异化配置可以在这里留空或设默认值,在 overlay 中覆盖
replicas: 1
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: nginx:1.14.2
ports:
- containerPort: 80

base/service.yaml

1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: Service
metadata:
name: my-app
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 80

编写 Base 的 kustomization.yaml

注意:在旧版本中常使用 commonLabels,但在新版本中推荐使用更灵活的 labels 字段。

base/kustomization.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

# 包含的资源文件
resources:
- deployment.yaml
- service.yaml

# 【更新点】使用 labels 替代 commonLabels
# includeSelectors: true 表示这些标签也会被添加到 selector 中
labels:
- pairs:
app: my-app
includeSelectors: true

覆盖层(Overlay)与多环境管理

overlays 目录中,我们引用 base 并进行环境特定的修改。

开发环境 (Dev)

Dev 环境通常需要:添加后缀、修改副本数、开启调试变量。

注意:旧版本使用 bases 引用上层目录,新版本(v2.1.0+)已废弃 bases,统一使用 resources 引用目录

overlays/dev/kustomization.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

# 【更新点】使用 resources 引用 base 目录
resources:
- ../../base

# 命名空间和名称前缀
namespace: my-project-dev
namePrefix: dev-

# 【更新点】统一使用 patches 字段
# 替代了旧的 patchesStrategicMerge 或 patchesJson6902
patches:
- path: patch-replicas.yaml
target:
kind: Deployment
name: my-app

# 镜像修改(推荐方式,无需修改 deployment.yaml)
images:
- name: nginx
newTag: "1.19-alpine"

overlays/dev/patch-replicas.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 1
template:
spec:
containers:
- name: app
env:
- name: ENV
value: "development"

生产环境 (Prod)

Prod 环境通常需要:资源限制(CPU/Mem)、更高的副本数、ConfigMap 管理。

overlays/prod/kustomization.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- ../../base

namespace: my-project-prod

# 直接在 kustomization.yaml 中内联 Patch(适合简单修改)
patches:
- target:
kind: Deployment
name: my-app
patch: |-
- op: replace
path: /spec/replicas
value: 3

# 【高级功能】ConfigMap Generator
# Kustomize 会自动为 ConfigMap 名称添加哈希后缀
# 当内容变化时,哈希变化,Deployment 也会自动滚动更新
configMapGenerator:
- name: app-config
files:
- config.properties

常用命令与工作流

预览渲染结果 (Build)

在部署前,务必检查生成的 YAML 是否符合预期。

1
2
3
4
5
# 查看开发环境渲染结果
kubectl kustomize overlays/dev

# 或者使用独立 CLI 工具(如果安装了)
kustomize build overlays/dev

部署 (Apply)

自 Kubernetes 1.14 起,kubectl 原生支持 Kustomize。

1
2
3
4
5
# 部署到集群
kubectl apply -k overlays/prod

# 删除资源
kubectl delete -k overlays/prod

命令行修改 (Imperative)

除了手动编辑文件,Kustomize 也支持使用命令修改 kustomization.yaml,这在 CI/CD 脚本中非常有用(参考 izsk.me 的实践)。

1
2
3
4
5
6
7
# 切换到 dev 目录
cd overlays/dev

# 修改镜像标签(常用于 CI 流水线中更新镜像版本)
kustomize edit set image nginx=nginx:1.20

# 此时 kustomization.yaml 中的 images 字段会被自动更新

版本变更总结 (常见坑点排查)

避坑指南:

旧字段/旧写法新字段/推荐写法说明
commonLabelslabelslabels 提供了更细粒度的控制,支持 includeSelectors: false 等选项。
bases: [...]resources: [...]bases 字段已废弃。现在引用文件或目录统一都用 resources
patchesStrategicMergepatches虽然旧字段仍兼容,但 patches 字段统一了 Strategic Merge Patch 和 JSON Patch,且支持内联写法,更加推荐。
imageTagsimagesimages 字段支持更改 newNamenewTagdigest,功能更全。
手写 ConfigMapconfigMapGenerator强烈推荐使用 Generator。它能给 ConfigMap 加哈希后缀(如 app-config-h57fk2),配置变更时自动触发 Pod 重启,是 Kustomize 的杀手级特性。

总结

Kustomize 的核心哲学是复用叠加。通过上述结构:

  1. Base 保持了应用最纯净的定义。

  2. Overlays 明确地管理了环境差异。

  3. kubectl apply -k 简化了部署流程。

这种方式完全符合 GitOps 的理念:将环境差异代码化,每一次变更都可追踪、可回滚。

参考: