Kustomize 实战:K8s 声明式配置管理

在 Kubernetes 日常运维中,同一套应用往往要在开发、测试、生产多套环境间反复拷贝 YAML,稍不注意就出现配置漂移。Kustomize 是 kubectl 自带的声明式配置管理工具,它不引入模板语言,而是用 base 与 overlay 的方式”补丁式”复用配置,让多环境差异化部署变得可控、可审计、可回滚。

一、为什么需要 Kustomize

设想一个常见场景:你在开发环境用一份 Deployment,上线生产时要把镜像 tag 改掉、副本数从 1 加到 3、加上资源限制与 Ingress。最直接的做法是 copy 一份 YAML 再手动改——但这正是配置地狱的起点:两份文件会逐渐分叉,谁也说不清生产到底用了哪份。Helm 用 Go template 解决复用,灵活却学习曲线陡、调试时满屏报错难以定位。Kustomize 走另一条更朴素的路:把”基础配置”和”环境差异”彻底分开,环境文件只描述”改了什么”,而不是把整份配置重写一遍。这种声明式、纯 YAML 的思路天然契合 GitOps,每一次变更都在 Git 历史里可追溯,也更容易做代码评审。

二、核心概念:base 与 overlay

理解 Kustomize 只需抓住两个词。base 是应用的”标准形态”,包含 Deployment、Service 等与环境无关的通用资源;overlay 则是某个具体环境(如 prod)对 base 的定制,它通过一个 kustomization.yaml 引用 base,再叠加自己需要的修改。关键在于:一个 base 可以被 dev、test、prod 多个 overlay 同时复用,而 base 本身只维护一份。这从根本上消灭了”拷贝后分叉”的问题——差异永远显式地写在 overlay 里,任何人打开 prod 目录都能立刻看清生产环境到底和基准差在哪里。当某个配置需要在所有环境统一调整时,你只需改 base 一处,所有环境自动继承。

三、快速上手:第一个 kustomization.yaml

先看 base 目录结构,它和普通 K8s 清单目录几乎一样,只是多了一个 kustomization 清单:

base/
├── deployment.yaml
├── service.yaml
└── kustomization.yaml

base/kustomization.yaml 只声明”我包含哪些资源”,并用 commonLabels 给所有资源统一打标签,省去逐个手写 label 的麻烦:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - deployment.yaml
  - service.yaml

commonLabels:
  app: myapp

此时执行 kubectl kustomize base 就能看到注入了标签后的完整 YAML,它和手写的效果完全一致,但维护成本更低。

四、常用字段:images / patches / replicas

overlay 最常用的三个字段各有分工。images 不用改 base 里的 image 字段,直接在这里统一替换镜像名与 tag;replicas 覆盖副本数;patches 则能对任意字段做 JSON Patch 或 Strategic Merge 式的修改。比如生产环境要换镜像、提到 3 副本、并补上资源限制:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - ../../base

images:
  - name: myapp
    newName: registry.example.com/myapp
    newTag: v1.4.2

replicas:
  - name: myapp
    count: 3

patches:
  - target:
      kind: Deployment
      name: myapp
    patch: |-
      - op: add
        path: /spec/template/spec/containers/0/resources
        value:
          requests: { cpu: 100m, memory: 128Mi }
          limits:   { cpu: 500m, memory: 256Mi }

注意 patches 默认用 RFC 6902 JSON Patch,路径写错就会构建失败——这正是为什么一定要先用 kubectl kustomize 本地渲染核对。

五、多环境 overlay 实战

推荐的目录结构是一份 base、多份 overlay。生产 overlay 还可通过 namePrefix、namespace 做资源隔离,并挂载独立的 Ingress 资源:

overlays/prod/
├── kustomization.yaml
└── ingress.yaml

# overlays/prod/kustomization.yaml
resources:
  - ../../base
  - ingress.yaml
namePrefix: prod-
namespace: myapp-prod

部署时一步到位:先在本地渲染核对,再应用到集群:

kubectl kustomize overlays/prod
kubectl apply -k overlays/prod

apply -k 中的 -k 即 kustomize,kubectl 会先构建出最终 YAML 再下发,无需任何额外二进制。

六、Kustomize 与 Helm 怎么选

两者并非互斥,很多成熟团队的做法是:用 Helm 管理第三方中间件(如数据库、网关)的 Chart,用 Kustomize 收口自有业务的多环境配置。选型可参考下表:

维度KustomizeHelm
配置方式声明式补丁(overlay)Go 模板渲染
学习成本低(纯 YAML)中(需学 template 语法)
多环境overlay 目录原生支持多 values 文件
调试体验渲染结果即所见模板报错较难定位
生态kubectl 内置Chart 仓库极其丰富

经验法则:自有业务、环境差异为主,优先 Kustomize;要复用社区成熟部署、参数化复杂度高,选 Helm。

七、ConfigMap 与 Secret 的 Kustomize 管理

配置与密钥是环境差异的重灾区。Kustomize 提供 configMapGenerator 与 secretGenerator,自动生成带哈希后缀的资源,并在引用处注入,实现”配置变了、Pod 自动滚动更新”。

configMapGenerator:
  - name: myapp-config
    files:
      - app.properties
    literals:
      - LOG_LEVEL=INFO

secretGenerator:
  - name: myapp-secret
    files:
      - secrets/db.password

生成的 ConfigMap 名会带内容哈希,base 里的 Deployment 用 configMapKeyRef 引用逻辑名即可——Kustomize 会在构建时把引用自动改写到带哈希的真实名称,彻底避免”改了配置但 Pod 没重启”的经典事故。

八、接入 GitOps:Argo CD 与 Flux

Kustomize 是 GitOps 的事实标准输入之一。Argo CD 与 Flux 都原生支持把 path 直接指向 overlay 目录,Git 一提交,控制器就自动把集群状态对齐到仓库里的声明。这让”环境差异”第一次拥有了版本控制:回滚一个环境,本质上就是 git revert 一次 overlay。配合 Jenkins 流水线 做镜像构建、用 K8s HPA 做弹性伸缩,就形成了从代码到集群的完整交付闭环。若用 GitHub Actions 跑 CI,可以把 kubectl kustomize 的渲染结果作为校验产物,在合并前就暴露 base 与 overlay 之间的引用冲突。

九、远程 base 与组件化复用

当多个服务共享同一套基础配置时,可以把 base 推到独立 Git 仓库,用 resources 指向远程地址,实现跨仓库复用:

resources:
  - github.com/your-org/k8s-bases//webapp?ref=v1.2.0

通过 ?ref= 锁定版本,既享受复用红利,又不被上游随意改动击穿。组件化让”公司级基线”(如统一的安全上下文、资源配额、探针模板)沉淀为一处,新服务接入只需写极薄的 overlay。

十、常见坑与排障

实践中最容易踩的坑,以及对应处理方式整理如下:

现象根因处理
apply 后配置没变ConfigMap 未用 Generator,Pod 未滚动改用 configMapGenerator 注入哈希名
Service 找不到后端加了 namePrefix 后标签/选择子不一致overlay 统一加 namePrefix,引用自洽
patch 构建失败JSON Patch 路径写错先 kustomize 本地渲染再 apply
远程 base 拉取慢/失败网络或 ref 不存在锁定 ref、检查仓库权限

此外,老版本 kubectl 内置的 Kustomize 能力较弱,建议 1.21+,或直接用独立 kustomize CLI 保证行为一致。和 Docker Compose 编排 配合时,本地用 Compose 起依赖服务做联调、集群用 Kustomize 管理多环境,是中小团队性价比很高的组合。

十一、小结

Kustomize 用”不重复、只描述差异”的极简理念,让 Kubernetes 多环境配置回归清爽。它不取代 Helm,而是与之互补:标准化底座用 Helm,环境收口用 Kustomize。把配置交给 Git、交给声明式,每一次发布都可追溯、可回滚,这才是可持续的云原生运维之道。当你厌倦了在 YAML 之间来回拷贝与手动 diff 时,Kustomize 会是你最顺手的那个工具。

上一篇 Embeddings 向量嵌入实战:从原理到语义检索落地
下一篇 推理模型实战:o1/R1/QwQ 慢思考大模型原理与调用
最新评论
Docker 网络模式详解:bridge/host 生产选型 - FSData
Docker 网络模式详解:bridge/host 生产选型 - FSData
8月20日
[…] 注意最后那条:把端口绑定到 127.0.0.1,再由宿主机上的 Nginx 反代进来,比直接 -p 80:80 暴露安全得多,也方便统一做
Vue3 + TypeScript 工程化:类型安全的前端架构 - FSData
Vue3 + TypeScript 工程化:类型安全的前端架构 - FSData
8月20日
[…] Pinia 的工程化用法,可以参考我们之前的实战文章 《Vue3 组合式 API + Pinia:状态管理从入门到实战》,那里覆盖了 Sto
2026 年最值得装的 10 个 VS Code 插件(AI/前端/后端/效率全覆盖) - FSData
2026 年最值得装的 10 个 VS Code 插件(AI/前端/后端/效率全覆盖) - FSData
8月19日
[…] 状态,点一下就能起停容器,配合我们讲过的 Docker Compose 编排 […]
Redis 缓存设计:穿透、击穿、雪崩与最佳实践 - FSData
Redis 缓存设计:穿透、击穿、雪崩与最佳实践 - FSData
8月19日
[…] 缓存三大坑的本质都是”缓存失效导致请求穿透到数据库”。记住口诀:穿透用布隆、击穿用锁、雪崩用错峰。配合合理的过期策略
GitHub Actions 实战:从零搭建 CI/CD 流水线 - FSData
GitHub Actions 实战:从零搭建 CI/CD 流水线 - FSData
8月19日
[…] Docker 镜像部署。结合我们之前写的 Docker Compose 一键编排实战,可以在 CI […]