如何在Helm模板中替换、增减部分值(含KEDA示例)
处理Helm模板中动态修改values字段的问题
问题描述
基础场景
values.yaml中定义了someField字段:
someField: field1: 1 field2: someValue field3: someObject ...
需要在Helm模板中生成修改后的结构:
someField: field1: 2 field3: someObject ... field100: someNewValue
不想逐个手动列出所有字段,使用toYaml函数只能输出原始值,无法实现动态修改、增删字段的需求。
扩展示例(KEDA ScaledObject)
已安装KEDA的Helm Chart,其ScaledObject CRD定义如下:
apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: {scaled-object-name} spec: scaleTargetRef: apiVersion: {api-version-of-target-resource} # Optional. Default: apps/v1 kind: {kind-of-target-resource} # Optional. Default: Deployment name: {name-of-target-resource} # Mandatory. Must be in the same namespace as the ScaledObject envSourceContainerName: {container-name} # Optional. Default: .spec.template.spec.containers[0] pollingInterval: 30 # Optional. Default: 30 seconds cooldownPeriod: 300 # Optional. Default: 300 seconds idleReplicaCount: 0 # Optional. Default: ignored, must be less than minReplicaCount minReplicaCount: 1 # Optional. Default: 0 maxReplicaCount: 100 # Optional. Default: 100 fallback: # Optional. Section to specify fallback options failureThreshold: 3 # Mandatory if fallback section is included replicas: 6 # Mandatory if fallback section is included advanced: # Optional. Section to specify advanced options restoreToOriginalReplicaCount: true/false # Optional. Default: false horizontalPodAutoscalerConfig: # Optional. Section to specify HPA related options name: {name-of-hpa-resource} # Optional. Default: keda-hpa-{scaled-object-name} behavior: # Optional. Use to modify HPA's scaling behavior scaleDown: stabilizationWindowSeconds: 300 policies: - type: Percent value: 100 periodSeconds: 15 triggers: - type: service-bus authenticationRef: name-of-auth
需要在自定义Helm Chart中基于该CRD生成资源,用户提供spec内容后,自动给triggers数组的每个元素添加authenticationRef字段。
解决方案
基础场景:动态修改、增删字段
Helm 3+提供了字典操作函数,无需逐个列出所有字段即可实现需求:
- 合并字段(修改/新增)
使用merge函数将自定义修改内容合并到原始字段上,新值会覆盖旧值,新增字段会被添加:
someField: {{- merge (dict "field1" 2 "field100" "someNewValue") .Values.someField | toYaml | nindent 2 }}
如果需要优先保留用户提供的字段(即用户配置覆盖默认修改),调换merge参数顺序即可:
someField: {{- merge .Values.someField (dict "field1" 2 "field100" "someNewValue") | toYaml | nindent 2 }}
- 删除指定字段
使用omit函数移除不需要的字段,搭配merge完成修改:
someField: {{- omit .Values.someField "field2" | merge (dict "field1" 2 "field100" "someNewValue") | toYaml | nindent 2 }}
该示例先移除field2,再合并修改后的字段,得到目标结构。
KEDA ScaledObject场景:批量处理数组元素
对于triggers数组需要批量添加字段的情况,可通过range遍历或map函数结合merge实现:
假设用户在values.yaml中提供的配置如下:
scaledObject: spec: scaleTargetRef: name: my-deployment minReplicaCount: 2 triggers: - type: service-bus queueName: my-queue - type: redis address: redis:6379
方式1:使用range遍历修改
apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: my-scaled-object spec: {{- $spec := .Values.scaledObject.spec }} triggers: {{- range $trigger := $spec.triggers }} {{- merge $trigger (dict "authenticationRef" "name-of-auth") | toYaml | nindent 4 }} {{- end }} {{- omit $spec "triggers" | toYaml | nindent 2 }}
方式2:使用map函数批量修改
apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: my-scaled-object spec: {{- $spec := .Values.scaledObject.spec }} {{- $modifiedSpec := merge $spec (dict "triggers" (map (merge (dict "authenticationRef" "name-of-auth")) $spec.triggers)) }} {{- $modifiedSpec | toYaml | nindent 2 }}
两种方式都能保留用户提供的所有spec配置,同时自动给每个trigger添加authenticationRef字段。
内容的提问来源于stack exchange,提问作者Ilya Chernomordik
相关产品推荐
相关产品推荐

