如何实现Helm模板依次使用不合并覆盖的多value文件(ArgoCD场景)
解决方案:Helm模板依次加载多Value文件生成独立Deployment
要实现不合并、不覆盖,依次加载多个Value文件生成Deployment,核心思路是绕过Helm默认的Value合并逻辑,直接用Helm模板函数遍历指定的文件列表,逐个读取文件内容并渲染对应的资源。具体步骤和示例如下:
实现原理
- 在Chart的主Value文件中定义需要加载的文件列表
- 用Helm的
range遍历该列表,通过readFile读取单个文件内容,再用fromYaml解析为可操作的YAML对象 - 对每个解析后的对象独立渲染Deployment,确保每个Value文件对应一个独立的资源实例
示例实现
1. Chart目录结构
charts/my-app/ ├── templates/ │ └── deployment.yaml # 核心模板文件 ├── values.yaml # 主配置文件,定义要加载的文件列表 ├── values-app1.yaml # 第一个应用的配置文件 └── values-app2.yaml # 第二个应用的配置文件
2. 配置文件内容
values.yaml(主配置)
# 定义需要依次加载的Value文件列表 targetFiles: - values-app1.yaml - values-app2.yaml
values-app1.yaml(第一个应用配置)
app: name: nginx-demo image: nginx:1.25-alpine replicas: 1 port: 80
values-app2.yaml(第二个应用配置)
app: name: busybox-demo image: busybox:1.36.1 replicas: 2 port: 8080
3. Deployment模板(templates/deployment.yaml)
{{- range $filePath := .Values.targetFiles }} {{- $appConfig := readFile $filePath | fromYaml }} --- apiVersion: apps/v1 kind: Deployment metadata: name: {{ $appConfig.app.name }} labels: app.kubernetes.io/name: {{ $appConfig.app.name }} spec: replicas: {{ $appConfig.app.replicas }} selector: matchLabels: app.kubernetes.io/name: {{ $appConfig.app.name }} template: metadata: labels: app.kubernetes.io/name: {{ $appConfig.app.name }} spec: containers: - name: {{ $appConfig.app.name }} image: {{ $appConfig.app.image }} ports: - containerPort: {{ $appConfig.app.port }} {{- end }}
4. ArgoCD应用配置
在ArgoCD的Application中,只需指定主配置文件即可(因为我们通过模板直接读取其他Value文件,无需Helm自动合并):
apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: multi-app-deployment spec: project: default source: repoURL: https://your-git-repo-url.git targetRevision: main path: charts/my-app helm: valueFiles: - values.yaml # 仅加载主配置,其他文件由模板读取 destination: server: https://kubernetes.default.svc namespace: default
效果验证
当ArgoCD同步该应用时,Helm会渲染出两个独立的Deployment:
nginx-demo:使用nginx镜像,1个副本busybox-demo:使用busybox镜像,2个副本
完全不会出现配置合并或覆盖的情况,每个Value文件的配置都独立生效。
内容的提问来源于stack exchange,提问作者Sri
相关产品推荐
相关产品推荐

