Kustomize复用YAML模板创建多K8s Deployment仅最后补丁生效问题
问题根因
- 逻辑认知错误:Kustomize的
patches字段仅用于修改resources列表中已声明的现有资源,不会自动复制资源生成多份实例。你在resources中只引入了1份nginx模板,无论配置多少个补丁,最终都只会输出1个Deployment,所有补丁按声明顺序依次作用在这同一个资源上,后执行的nginx2补丁直接覆盖了nginx1补丁对容器名的修改,最终只保留容器名为nginx-2的配置。 - 资源重名冲突:即使补丁逻辑正确,两个Deployment如果都沿用模板默认的
metadata.name: nginx,Kubernetes同命名空间下同类型资源名称唯一,也无法同时存在。 - 补丁格式不规范:当前的JSON补丁文件直接编写op操作列表,没有声明补丁类型和API版本,不符合Kustomize的补丁加载规范。
解决方案
提供两种方案,第一种是最小改动快速验证补丁功能,第二种是符合Kustomize最佳实践、适合后续扩展配置增删改需求的标准方案。
方案一:最小改动快速验证
适合当前阶段验证补丁能力,不需要调整目录结构:
- 修改
base/kustomization.yml,通过两次资源引用+名称补丁的方式生成两个独立Deployment:
resources: - nginx_template.yml - nginx_template.yml # 第二次引用模板,作为第二个Deployment的基础 patches: - path: ./apps/nginx1/nginx1.yml target: kind: Deployment name: nginx - path: ./apps/nginx2/nginx2.yml target: kind: Deployment name: nginx
两次引用同一个模板后Kustomize会识别到两个同名基础资源,需要在补丁中修改资源名称做区分
- 修正
base/apps/nginx1/nginx1.yml,补全必要的字段修改,保证资源唯一可关联:
- op: replace path: /metadata/name value: nginx-1 - op: replace path: /spec/selector/matchLabels/app value: nginx-1 - op: replace path: /spec/template/metadata/labels/app value: nginx-1 - op: replace path: /spec/template/spec/containers/0/name value: nginx-1
- 修正
base/apps/nginx2/nginx2.yml:
- op: replace path: /metadata/name value: nginx-2 - op: replace path: /spec/selector/matchLabels/app value: nginx-2 - op: replace path: /spec/template/metadata/labels/app value: nginx-2 - op: replace path: /spec/template/spec/containers/0/name value: nginx-2
执行kubectl kustomize base即可看到输出两个独立的Deployment资源。
方案二:标准分层方案(推荐后续长期使用)
该结构完全适配你后续对不同实例做配置新增、替换、删除的需求,符合Kustomize的设计理念:
- 调整目录结构,拆分公共基础模板和实例专属配置:
base/ ├── kustomization.yml └── nginx_template.yml # 仅存所有nginx实例共有的通用配置 nginx1/ ├── kustomization.yml └── patch.yml # nginx1专属配置修改 nginx2/ ├── kustomization.yml └── patch.yml # nginx2专属配置修改
- 编写
base/kustomization.yml,仅保留通用资源引用,不绑定任何实例配置:
resources: - nginx_template.yml
- 编写
nginx1/kustomization.yml,引用公共base并叠加实例专属配置:
resources: - ../base namePrefix: nginx1- # 自动给Deployment、Service加名称前缀,避免重名 commonLabels: app: nginx1 # 自动同步修改所有标签、Service selector,保证服务关联正确 patches: - path: patch.yml target: kind: Deployment
- 编写
nginx1/patch.yml,后续所有nginx1的自定义配置(容器名、resources资源限制等)都写在这里:
apiVersion: apps/v1 kind: Deployment metadata: name: nginx spec: template: spec: containers: - name: nginx-1 # 后续新增配置直接追加即可,例如resources配置: # resources: # requests: # cpu: 100m # memory: 128Mi
- 参考nginx1的配置,编写
nginx2/kustomization.yml和nginx2/patch.yml,把对应名称、标签、容器名改为nginx2即可。 - 部署时可以分别在nginx1、nginx2目录执行
kubectl apply -k .,也可以编写一个上层kustomization同时引用两个实例目录批量部署。
内容的提问来源于stack exchange,提问作者unstuckerino
相关产品推荐
相关产品推荐

