Kustomize — 不动原 YAML 的 K8s 配置叠加器
是什么
Kustomize 是 Kubernetes 的配置叠加工具——你写一份基础 YAML,再为每个环境(dev / staging / prod)写一份”差异说明”,运行时把两者合并出最终 YAML。整个过程不修改源文件,也不引入模板语法。
日常类比:
- 像点咖啡——基础是”大杯拿铁”(base),改”少糖加燕麦奶”是 patch(overlay),最终交给店员的还是一杯具体咖啡
- 像穿衣服——里层是 T 恤(base),冷了套外套、雨天加雨衣(overlay),不会因为加件衣服就重织 T 恤
它从 Kubernetes 1.14(2019 年)起内置进 kubectl,用法是 kubectl apply -k <目录>,不需要另装。GitHub 11k star。
为什么重要
K8s 部署最常见的痛是多环境差异管理:
- dev 跑 1 个副本、staging 跑 3 个、prod 跑 10 个
- 镜像 tag 每个环境不一样
- prod 要加资源 limit、加
livenessProbe、加nodeSelector - 环境变量 / Secret 引用各不相同
三种主流解法:
- 复制三份完整 YAML——简单但难维护,改一处要同步三份
- helm 模板——用 Go template 把 YAML 写成
replicas: {{ .Values.replicaCount }},灵活但 YAML 不再是合法 YAML - Kustomize——base 永远是合法 YAML,差异写在外面的 patch 里
不理解 Kustomize 绕不开下面这些场景:
- 看公司 argocd 仓库时一半项目用 Kustomize 一半用 Helm,得知道差别
- fork 一个开源 K8s 项目,想本地改 namespace / 加 label,不想动上游文件
kubectl apply -k这条命令在所有现代 K8s 教程里都会出现
核心要点
抓住三个概念就够:
Base——一个目录,放完整可部署的原始 YAML:
base/ kustomization.yaml # 列出本目录里参与构建的资源 deployment.yaml service.yamlkustomization.yaml 长这样:
resources: - deployment.yaml - service.yamlOverlay——另一个目录,引用 base + 声明差异:
overlays/prod/ kustomization.yaml replica-patch.yamloverlays/prod/kustomization.yaml:
resources: - ../../basepatchesStrategicMerge: - replica-patch.yamlnamespace: prodcommonLabels: env: prodPatch——只写差异的那部分 YAML:
apiVersion: apps/v1kind: Deploymentmetadata: name: webspec: replicas: 10跑 kubectl apply -k overlays/prod,Kustomize 会读 base 的 deployment.yaml,把 replicas 字段改成 10,namespace 设成 prod,所有资源加上 env=prod label,再交给 kubectl apply。base 文件一个字没动。
实践案例
案例 1:dev / prod 跑同一份 base
myapp/ base/ kustomization.yaml deployment.yaml # replicas: 1 overlays/ dev/ kustomization.yaml # 只引用 base prod/ kustomization.yaml patch.yaml # replicas: 10kubectl apply -k myapp/overlays/dev → 1 副本;kubectl apply -k myapp/overlays/prod → 10 副本。两边共享同一份 deployment.yaml,没有任何复制。
案例 2:批量改 namespace + 加 label
namespace: my-teamcommonLabels: team: platformresources: - deployment.yaml - service.yaml不用 sed,三行声明完成”把所有资源搬到 my-team namespace 并打上 label”。
案例 3:fork 上游项目只维护差异
resources: - https://raw.githubusercontent.com/some/operator/v1.2.3/install.yamlnamespace: my-clusterimages: - name: registry.example.com/operator newName: my-registry.local/operator升级时只改 URL 里的版本号,本地零文件维护。
踩过的坑
-
patch 语法两套混淆:
patchesStrategicMerge按 K8s 字段语义合并(list 按 key 合并);patchesJson6902是 RFC 6902 JSON Patch(按路径增删改)。新人常用错——改 list 想覆盖某一项,strategic 是按 key 合并不是替换,结果 list 里多一项。 -
kubectl 内置版本落后:
kubectl里的 kustomize 通常落后 standalone 几个版本,新功能(如 components / openapi)可能没有。生产建议装独立kustomizeCLI,CI 里用它生成 YAML 再 apply。 -
不要在 base 里写”环境无关”是个谎:base 看似纯净,但
image: nginx:latest这种隐含决策也是一种环境绑定。真实项目里 base 经常被迫保留某个环境的默认值。 -
没有 if / else / loop:想根据 environment 做条件渲染做不到,得拆成多个 overlay 或上 Helm。复杂业务逻辑场景 Kustomize 不够用。
适用 vs 不适用场景
适用:
- 一份基础部署 + 多环境差异(dev / staging / prod)
- 给一批资源批量改 namespace / 加 label / 改镜像
- fork 上游项目只维护本地补丁
- GitOps 仓库(argocd 原生支持
-k,无需额外配置)
不适用:
- 需要条件渲染 / 循环 / 字符串拼接 → 用 helm
- 需要打包发布给第三方安装 → Helm 有 Chart 仓库生态(helm 配 Artifact Hub)
- 完全动态的运行时配置(基于集群状态调整)→ 写 Operator
- 跨集群复制 + 漂移检测 → 上 argocd 这类 GitOps 工具
历史小故事(可跳过)
- 2017 年:Google 内部团队提出 Kustomize 概念,作为 K8s SIG-CLI 项目开源
- 2019 年:Kubernetes 1.14 起 kustomize v2.0.3 内置进
kubectl,命令kubectl apply -k成为官方一等公民 - 后续:standalone CLI 和 kubectl 内置版本平行演进;Argo CD / Flux CD 等 GitOps 工具原生支持 Kustomize 目录
学到什么
- 配置管理可以”叠加”而非”替换”——保留源文件不动,差异写在外面,可读性 / 可审计性远高于模板替换
- 声明式 > 命令式——
namespace: prod一行声明,胜过sed -i 's/namespace: .*/namespace: prod/' *.yaml - K8s-aware 工具的优势——按 Deployment / Service 字段语义合并,不像通用文本工具会破坏 YAML 结构
- 够用就好的设计取舍——故意不加 if/else 是为了避免变成”另一个 Helm”,复杂场景留给真正的模板工具
延伸阅读
- 官方教程:Kustomize - Tutorials(有交互式 demo)
- 入门视频:Kubernetes Kustomize Tutorial
- vs Helm 对比:Kustomize vs Helm
- helm —— K8s 应用包管理事实标准(模板派)
- kubernetes —— Kustomize 服务的对象
- argocd —— GitOps 工具,原生支持 Kustomize
关联
- kubernetes —— Kustomize 处理的是 K8s YAML
- helm —— 解决同一问题的另一条路(模板派 vs 叠加派)
- argocd —— GitOps 部署工具,把 Kustomize 输出推到集群
- terraform —— IaC 同类思想,但管理对象是云资源而非 K8s 对象
反向链接
- argocd —— Argo CD — Kubernetes GitOps 工具
- flux —— Flux — 让 Git 当 Kubernetes 集群的真理来源
- helm —— Helm — Kubernetes 包管理器
- k3s —— k3s — 把完整 K8s 塞进一个 60 MB 的二进制
- kubernetes —— Kubernetes — 容器编排平台
- skaffold —— Skaffold — K8s 本地开发的 build-deploy 自动循环
- tilt —— Tilt — K8s 微服务本地开发的”文件保存即上线”
- velero —— Velero — Kubernetes 集群备份与迁移