Kustomize 是什么
Kustomize 是 Kubernetes 自带的配置管理工具:在不修改原始 YAML 文件的前提下,用一个小文件 kustomization.yaml 声明「要部署哪些资源、统一加什么 namespace/标签、如何做补丁」,kubectl 会先合并再 apply。
和 Helm 的分工可以这样理解:
| 方式 | 特点 | 常见场景 |
|---|---|---|
纯 YAML + kubectl apply -f |
最直接,改多个文件时要自己记顺序 | 单文件、临时试验 |
| Kustomize | 无模板语言,补丁基于 YAML;kubectl apply -k 内置 |
homelab 自写 manifest、按目录组织服务 |
| Helm | Chart + values,适合第三方发行版 | kube-prometheus-stack、Nexus 等上游 Chart |
Kustomize 从 Kubernetes 1.14 起并入 kubectl,一般不需要单独安装 kustomize 二进制(旧文档里的独立 CLI 仍可用,但日常 kubectl apply -k 即可)。
最小目录结构
一个可部署单元通常是一个目录,根上有 kustomization.yaml,旁边放各资源的 YAML:
blog-stats/
├── kustomization.yaml
├── namespace.yaml
├── configmap.yaml
├── secret.yaml
└── cronjob.yaml
kustomization.yaml 只列出要包含的文件(路径相对本目录):
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- configmap.yaml
- secret.yaml
- cronjob.yaml
部署:
kubectl apply -k homelab/k8s/blog-stats/
等价于对合并后的 manifest 执行一次 kubectl apply;Kustomize 负责生成那份合并结果。本地只想看合并结果、不写入集群时:
kubectl kustomize homelab/k8s/blog-stats/
常用字段
resources
必填(或改用 bases / components 等高级写法)。列出的每个条目可以是单个 YAML 文件,也可以是另一个带 kustomization.yaml 的子目录(嵌套 base)。
namespace
给本层所有资源统一设置 metadata.namespace,避免每个文件重复写:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: kube-prometheus-stack
resources:
- prometheus/additional-scrape-configs.yaml
- prometheus/blackbox-exporter.yaml
- ingress-prometheus-remote-write.yaml
适合「同一目录下多份清单都进同一个命名空间」的场景;若某资源 YAML 里已经写了 namespace,以 Kustomize 合并规则为准(通常由 kustomization.yaml 覆盖或补齐)。
commonLabels / labels
给所有资源加上统一标签,便于筛选、配合 ServiceMonitor 等:
commonLabels:
app.kubernetes.io/part-of: observability
patches / patchesStrategicMerge
在不复制整份 Deployment 的情况下改片段,例如改镜像 tag、加环境变量、改副本数。战略合并补丁(patchesStrategicMerge)适合小改动;复杂条件可用 JSON6902 / RFC6902 风格的 patches。
images
批量替换镜像名与 tag,适合 CI 只改 tag、不改完整 Deployment:
images:
- name: my-app
newTag: v1.2.3
configMapGenerator / secretGenerator
从文件生成 ConfigMap/Secret,并自动加内容哈希后缀,减少「只改 ConfigMap 却未触发滚动」的问题(需与 Deployment 的 name 引用方式配合)。
与 kubectl apply -f 的区别
| 命令 | 行为 |
|---|---|
kubectl apply -f dir/ |
按文件名顺序 apply 目录下所有 YAML,不会读 kustomization.yaml |
kubectl apply -k dir/ |
先执行 Kustomize build,再 apply 合并后的 清单 |
若目录里有 kustomization.yaml,应使用 -k,否则 namespace、补丁、生成器都不会生效。
删除资源时也有对应写法:kubectl delete -k <目录> 会按当前 build 结果删除(仍受 --prune 等行为约束,生产前先在测试命名空间验证)。
homelab 中的用法
配置仓库 w10n-config 里,不少服务按目录 + Kustomize 管理,例如:
homelab/k8s/blog-stats/:CronJob + ConfigMap + Secret,每日拉取博客统计写入 PostgreSQLhomelab/k8s/observability/:Prometheus 额外抓取、Blackbox、自写PrometheusRule、Ingress 等,用顶层namespace: kube-prometheus-stack统一命名空间
日常变更流程通常是:改 YAML → kubectl apply -k <目录> → 用 kubectl get / logs 验证。这与 Argo CD 与 GitOps 持续部署 里「Git 为事实来源」可以并存:Argo 同步的 path 也可以是 Kustomize 目录,由 Argo 在服务端执行 kustomize build 再 apply。
若资源已由 Argo CD 管理,长期用本机 kubectl apply -k 旁路修改会导致 OutOfSync,可能与 selfHeal 互相覆盖;应急与正路对比见 Argo CD CLI 与 kubectl annotate 对比。
和 Helm 如何配合
二者不必二选一。常见组合:
- Helm 装上游栈(监控、Ingress Controller),values 只覆盖必要项
- Kustomize 管自写清单(业务 Deployment、CronJob、自研告警规则),目录进 Git,用
apply -k或 Argo 同步
不建议对同一份 Deployment 既用 Helm 又用 Kustomize 叠加 patch,除非清楚 release 名与对象归属,否则升级 Chart 时容易覆盖手工补丁。
适用与不适用
适合:
- 清单数量适中、以静态 YAML 为主
- 需要按环境(dev/staging/prod)做少量差异(
overlays/目录是官方推荐模式) - 希望 diff 直观、不引入 Helm 模板语法
不太适合:
- 强依赖第三方 Chart 的参数组合(直接用 Helm 更省事)
- 需要复杂模板逻辑(可考虑 Helm 或外部生成器写 YAML 再 kustomize)
延伸阅读
- 官方导读:Introduction to Kustomize
- 多环境结构:Bases and Overlays
- 集群概念总览:k8s;GitOps 部署:Argo CD 与 GitOps 持续部署