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
13
14
15
16
17
18
19
20
21
22
23
~/my-project
├── base # 【基础层】存放通用的资源定义
├── app # 开发环境
├── deployment.yaml
├── service.yaml
└── └── kustomization.yaml
└── overlays # 【覆盖层】存放各环境的差异化配置
├── dev # 开发环境
├── common
├── config.properties
├── secret.env
└── └── kustomization.yaml
├── app
├── ...
└── └── kustomization.yaml
└── prod # 生产环境
├── common
├── config.properties
├── secret.env
└── └── kustomization.yaml
├── app
├── ...
└── └── kustomization.yaml

基础层(Base)配置

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

准备资源文件

base/app/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/app/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/app/kustomization.yaml

1
2
3
4
5
6
7
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

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

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

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

开发环境 (Dev)

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

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

overlays/dev/app/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
26
27
28
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

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

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

patches:
- path: patch-replicas.yaml
target:
kind: Deployment
name: my-app

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

# includeSelectors: true 表示这些标签也会被添加到 selector 中
labels:
- pairs:
app: my-app
includeSelectors: true

overlays/dev/app/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/Secret 管理。

overlays/prod/app/config.properties

1
2
xxx=xxx
...

overlays/prod/app/secret.env

1
2
xxx=xxx
...

overlays/prod/app/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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- ../../base
- ../common

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

# 服务特定的 SecretsecretGenerator:
- name: sapi-test-secret
envs:
- secret.env
# 禁止自动添加hash后缀的行为
options:
disableNameSuffixHash: true

# includeSelectors: true 表示这些标签也会被添加到 selector 中
labels:
- pairs:
app: my-app
includeSelectors: true

常用命令与工作流

kubectl kustomize (功能单一)

kubectl 仅集成了 Kustomize 的 Build(构建) 功能。它没有复杂的子命令,基本只用于将 Kustomize 配置文件转换成标准的 Kubernetes YAML。

指令说明
kubectl kustomize <dir>核心指令:读取指定目录的 kustomization.yaml 并输出渲染后的资源到终端。
kubectl apply -k <dir>常用扩展:直接构建并应用到集群(这是最常用的方式)。
kubectl delete -k <dir>根据 Kustomize 配置批量删除集群中的资源。
kubectl diff -k <dir>对比本地 Kustomize 渲染结果与集群运行中资源的差异

kustomize (独立 CLI,功能丰富)

独立版工具将功能划分为几个大类,支持对配置文件进行增删改查

核心构建 (Build)

  • kustomize build <dir>: 最基础指令,等同于 kubectl kustomize <dir>。支持更多参数(如 --enable-alpha-plugins)。

编辑指令 (Edit) - kubectl 不支持

这是独立版最强大的地方,允许你通过命令行直接修改 kustomization.yaml 文件。

  • kustomize edit add resource <file>: 向配置中添加资源文件。

  • kustomize edit set image <name=newimage:tag>: 修改镜像名称或版本。

  • kustomize edit set namespace <name>: 修改全局命名空间。

  • kustomize edit add configmap <name> --from-file=<path>: 快速添加 ConfigMap 生成器。

  • kustomize edit set label <key:value>: 批量添加标签。

初始化与创建 (Create/Completion)

  • kustomize create: 在当前目录自动创建一个初始化的 kustomization.yaml

  • kustomize completion: 生成 Bash/Zsh 的命令行自动补全脚本。

查看与格式化 (Fn/Inspect)

  • kustomize fn: 运行 KRM 函数(高级特性,用于处理资源树)。

核心指令映射表

如果习惯了 kubectl,想转到 kustomize 独立工具,可以参考这个映射:

目标操作kubectl 命令kustomize 独立命令
查看渲染结果kubectl kustomize ./overlays/devkustomize build ./overlays/dev
修改镜像版本手动改 YAMLkustomize edit set image myapp=v2.0
添加新文件手动改 YAMLkustomize edit add resource service.yaml
初始化目录手动创建文件kustomize create --autodetect

总结

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

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

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

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

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

参考: