Helm模板循环中引用values.yaml值及include报错问题排查
问题原因与解决方法
一、include "hosts"报错的原因
这个错误是因为你没有定义名为hosts的模板片段。Helm的include函数只能引用已经在_helpers.tpl或其他模板文件中定义好的模板,你可能误以为hosts是内置模板,但实际上需要自己手动定义,或者直接引用字段值而非用include。
二、循环内引用顶层Values的正确方式
在range/with循环中,当前上下文.会指向循环的对象(比如每个serviceEntries.policies项),要访问values.yaml的顶层值,必须用全局变量$,它始终指向模板的顶层上下文。例如:
- 引用顶层的
namespacePolicy:{{ $.Values.namespacePolicy }} - 在
range循环中的实际用法:{{- range $policy := .Values.serviceEntries.policies }} apiVersion: networking.istio.io/v1alpha3 kind: ServiceEntry metadata: name: {{ $policy.name }} namespace: {{ $.Values.namespacePolicy.targetNs }} # 用$访问顶层Values spec: # 直接引用当前policy的hosts字段,无需include hosts: {{ toYaml $policy.hosts | nindent 6 }} {{- end }}
三、直接插入YAML块的最优方案
如果你想直接把values.yaml中定义的YAML块原样插入模板,用toYaml函数配合nindent控制缩进即可,避免手动拼接:
示例:values.yaml结构
namespacePolicy: targetNs: "default" serviceEntries: policies: - name: "external-service-1" hosts: - "foo.example.com" - "bar.example.com" ports: - number: 80 name: http protocol: HTTP - name: "external-service-2" hosts: ["baz.example.com"] ports: - number: 443 name: https protocol: HTTPS
示例:ServiceEntry.yaml模板
{{- range $policy := .Values.serviceEntries.policies }} apiVersion: networking.istio.io/v1alpha3 kind: ServiceEntry metadata: name: {{ $policy.name }} namespace: {{ $.Values.namespacePolicy.targetNs }} spec: hosts: {{ toYaml $policy.hosts | nindent 4 }} # 直接插入hosts的YAML块,缩进4空格 ports: {{ toYaml $policy.ports | nindent 4 }} resolution: DNS {{- end }}
可选:复用hosts处理逻辑(定义hosts模板)
如果需要对hosts做统一处理(比如添加后缀、过滤),可以在templates/_helpers.tpl中定义模板:
{{/* 定义hosts模板,接收当前policy对象作为参数 */}} {{- define "hosts" -}} {{- range .hosts }} - {{ . }}.{{ $.Values.namespacePolicy.domainSuffix }} {{- end }} {{- end -}}
然后在模板中引用时,要传递当前上下文(或policy对象):
spec: hosts: {{ include "hosts" $policy | nindent 4 }}
内容的提问来源于stack exchange,提问作者user3372090
相关产品推荐
相关产品推荐

