You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何深度合并Helm命名模板中的数组?

Helm模板合并:实现数组对象的深度合并

当前尝试的模板与合并逻辑

我尝试合并两个Helm命名模板,简化示例如下:

{{- define "common.t1" -}}
a1: "t1-a1"
a2: "t1-a2"
b1:
  c1: t1-b1-c1
  c2: t1-b1-c2
d1:
  - name: container1
    e1: t1-d1-e1
    e2: t1-d1-e2
  - name: container2
    
{{- end -}}

{{- define "this.t2" -}}
a1: "t2-a1"
a3: "t2-a3"
b1:
  c1: t2-b1-c1
  c3: t2-b1-c3 
d1:
  - name: container1
    e1: t2-d1-e1
    e3: t2-d1-e3
  - name: container3
{{- end -}}

{{- $t1 := fromYaml (include "common.t1" .) -}}
{{- $t2 := fromYaml (include "this.t2" .) -}}
{{ toYaml (merge $t2 $t1) }}

当前merge函数的输出结果

使用merge函数合并后,d1数组中的对象被完全覆盖,结果如下:

a1: t2-a1
a2: t1-a2
a3: t2-a3
b1:
  c1: t2-b1-c1
  c2: t1-b1-c2
  c3: t2-b1-c3
d1:
- e1: t2-d1-e1
  e3: t2-d1-e3
  name: container1
- name: container3

预期的合并结果

我需要针对数组中的对象按name字段做合并:同名对象合并属性,保留未被覆盖的原有项,新增对象直接添加,预期结果如下:

a1: t2-a1
a2: t1-a2
a3: t2-a3
b1:
  c1: t2-b1-c1
  c2: t1-b1-c2
  c3: t2-b1-c3
d1:
- e1: t2-d1-e1
  e2: t1-d1-e2
  e3: t2-d1-e3
  name: container1
- name: container2
- name: container3

实际应用场景

这个合并需求是为了将通用Kubernetes Deployment模板放在公共库Chart中,让业务Chart基于通用模板做扩展,以此简化数十个Helm Chart的开发与维护。实际场景示例如下:

{{ magicMerge "common.deployment" "mychart548.deployment" . }}
{{- define "mychart548.deployment" -}}
spec:
  template:
    spec:
      containers:
        - name: {{ include "common.names.name" . }}
          envFrom:
            - configMapRef:
                name: {{ include "common.names.envConfigmapName" . }}
          env:
            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: {{ include "common.names.fullname" . }}-postgress
                  key: postgres-password
{{- end -}}

解决方案:自定义深度合并函数

Helm内置的merge/mergeOverwrite函数无法处理数组对象的合并,需要自定义模板函数实现按指定键(如name)合并数组的逻辑。

实现步骤

  1. 在公共Chart的_helpers.tpl中添加自定义合并函数:
{{- define "common.mergeArraysByName" -}}
{{- $arr1 := index . 0 -}}
{{- $arr2 := index . 1 -}}
{{- $merged := dict -}}
{{- /* 将第一个数组的对象存入字典,以name为键 */ -}}
{{- range $item := $arr1 -}}
{{- $_ := set $merged $item.name $item -}}
{{- end -}}
{{- /* 遍历第二个数组,合并到字典中 */ -}}
{{- range $item := $arr2 -}}
{{- if hasKey $merged $item.name -}}
{{- $_ := set $merged $item.name (merge $item (index $merged $item.name)) -}}
{{- else -}}
{{- $_ := set $merged $item.name $item -}}
{{- end -}}
{{- end -}}
{{- /* 将字典转回数组 */ -}}
{{- $result := list -}}
{{- range $key, $val := $merged -}}
{{- $_ := append $result $val -}}
{{- end -}}
{{- toYaml $result -}}
{{- end -}}
  1. 修改主合并逻辑,针对数组字段单独处理:
{{- $t1 := fromYaml (include "common.t1" .) -}}
{{- $t2 := fromYaml (include "this.t2" .) -}}
{{- /* 先合并非数组字段 */ -}}
{{- $base := merge $t2 $t1 -}}
{{- /* 处理d1数组的合并 */ -}}
{{- $mergedD1 := fromYaml (include "common.mergeArraysByName" (list $t1.d1 $t2.d1)) -}}
{{- $_ := set $base "d1" $mergedD1 -}}
{{- toYaml $base -}}

说明

  • 该函数通过将数组转为字典实现对象匹配,递归合并同名对象的属性,最后转回数组。
  • 可根据需求扩展函数,支持自定义匹配键或处理多层嵌套数组的场景。

内容的提问来源于stack exchange,提问作者Stan B

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 10:06:20