Helm模板渲染报错:无法在interface{}类型中解析Values字段求助
这个报错的核心原因是嵌套range循环里的作用域(scope)变化,你在内层循环里误用了.引用根上下文的Values,但此时.已经指向循环的当前项了。
具体分析
当你进入{{- range .Values.ingress.hosts }}循环后,模板里的.就不再是根上下文(包含Release、Values等顶级对象的那个上下文),而是变成了当前遍历的host对象;再进入内层的{{- range .paths }}循环时,.又进一步变成了当前的path对象。这时候你写.Values.network.appPort,Helm会尝试在当前的path对象里找Values字段,自然找不到,就抛出了can't evaluate field Values in type interface {}的错误。
而你在其他地方能用相同结构的Values,是因为那些代码不在嵌套的range循环里,.仍然指向根上下文。
修复方案(两种任选其一)
方案1:使用$直接引用根上下文
Helm模板里的$符号是全局的,始终指向根上下文,你只需要把{{ .Values.network.appPort }}改成{{ $.Values.network.appPort }}即可:
修改后的ingress.yaml关键部分:
rules: {{- range .Values.ingress.hosts }} - host: {{ .host | quote }} http: paths: {{- range .paths }} - path: {{ . }} backend: serviceName: {{ $fullName }} servicePort: {{ $.Values.network.appPort }} # 这里改成$.Values {{- end }} {{- end }}
方案2:提前保存根上下文引用
在模板开头(你已经定义$fullName的地方),额外保存根上下文到一个变量,比如$root,然后在内层循环里用这个变量访问Values:
{{- $fullName := include "mychart.fullname" . -}} {{- $root := . -}} # 新增这行,保存根上下文 apiVersion: extensions/v1beta1 kind: Ingress # ... 其余代码不变 rules: {{- range .Values.ingress.hosts }} - host: {{ .host | quote }} http: paths: {{- range .paths }} - path: {{ . }} backend: serviceName: {{ $fullName }} servicePort: {{ $root.Values.network.appPort }} # 用$root访问 {{- end }} {{- end }}
验证你的配置
你的values.yaml配置network: appPort: 4141是完全正确的,只要修复了作用域问题,servicePort就能正常读取到4141这个值。
内容的提问来源于stack exchange,提问作者red888

