Helm模板函数遍历字典取值报错,求问题排查与解决
问题分析与解决
问题场景
现有values.yaml配置:
# Default region and repository aws_region: us-east-1 repository: 01234567890.dkr.ecr.us-east-1.amazonaws.com repositories: us-east-1: 01234567890.dkr.ecr.us-east-1.amazonaws.com eu-north-1: 98765432109.dkr.ecr.eu-north-1.amazonaws.com image: name: "ms-0" ...
编写Helm模板函数用于根据AWS区域获取对应镜像仓库地址:
{{/* Get the repository from the AWS region */}} {{- define "microservice-base-chart.reponame" -}} {{- $repo := default .Values.repository }} {{- range $key, $value := .Values.repositories }} {{- if .eq $key .Values.aws_region }} {{- $repo = $value }} {{- end }} {{- end }} {{- printf "%s" $repo }} {{- end }}
在deployment.yaml中调用该函数:
apiVersion: apps/v1 kind: Deployment ... spec: ... template: ... spec: ... containers: - name: {{ .Values.image.name }} image: {{ include "microservice-base-chart.reponame" . }}/{{ .Values.image.name }}:{{ .Values.image.version }}
执行命令:
$ helm install ms-0 ./microservice-chart/ --dry-run --debug
出现错误:
install.go:178: [debug] Original chart version: "" install.go:195: [debug] CHART PATH: /path/helm/microservice-chart Error: INSTALLATION FAILED: template: microservice-chart/charts/microservice-0/templates/deployment.yaml:36:20: executing "microservice-chart/charts/microservice-0/templates/deployment.yaml" at <include "microservice-base-chart.reponame" .>: error calling include: template: microservice-chart/charts/microservice-0/templates/_helpers.tpl:70:7: executing "microservice-base-chart.reponame" at <.eq>: can't evaluate field eq in type interface {} helm.go:84: [debug] template: microservice-chart/charts/microservice-0/templates/deployment.yaml:36:20: executing "microservice-chart/charts/microservice-0/templates/deployment.yaml" at <include "microservice-base-chart.reponame" .>: error calling include: template: microservice-chart/charts/microservice-0/templates/_helpers.tpl:70:7: executing "microservice-base-chart.reponame" at <.eq>: can't evaluate field eq in type interface {} INSTALLATION FAILED
错误原因
模板函数中的.eq写法完全错误:
- 在Helm的Go模板语法中,
eq是内置比较函数,不属于当前上下文(.)的字段 - 循环内部的
.指向的是当前循环的$value(即仓库地址字符串),所以.eq相当于试图访问字符串类型的eq字段,这显然不存在,因此抛出类型错误
修正方案
方案1:修复原函数的比较逻辑
把.eq改为eq,同时提前保留顶层上下文的aws_region变量(因为循环内部.已被覆盖,无法直接访问.Values.aws_region):
{{/* Get the repository from the AWS region */}} {{- define "microservice-base-chart.reponame" -}} {{- $region := .Values.aws_region }} {{- $repo := default .Values.repository }} {{- range $key, $value := .Values.repositories }} {{- if eq $key $region }} {{- $repo = $value }} {{- end }} {{- end }} {{- printf "%s" $repo }} {{- end }}
方案2:更简洁高效的写法
无需循环遍历字典,直接用index函数通过键值访问字典,结合default设置默认值:
{{/* Get the repository from the AWS region */}} {{- define "microservice-base-chart.reponame" -}} {{- index .Values.repositories .Values.aws_region | default .Values.repository }} {{- end }}
该写法逻辑:
- 用
index直接从repositories字典中取出对应区域的仓库地址 - 如果目标区域不在字典中,则返回
.Values.repository作为默认值
内容的提问来源于stack exchange,提问作者Chris F
相关产品推荐
相关产品推荐

