Helm模板拼接字符串动态取值无法正确渲染问题咨询
问题根因
printf 仅做字符串拼接,不会将拼接生成的字符串作为模板变量路径解析,因此最终会把$.Values.app1.image_repository这类字符串直接原样输出,不会读取Values中对应路径的实际值。
基于现有配置结构的修复方案
使用Go模板内置的index函数实现动态路径取值,注意在with语句块内要通过$引用根作用域,避免上下文被覆盖:
{{- range $containerApp := .Values.containerApps }} {{- with $containerApp }} ... containers: - name: {{ .name }} image: "{{ index $.Values .name "image_repository" }}:{{ index $.Values .name "image_tag" }}" replicas: {{ .replicaCount }} ... ... {{- end }} {{- end }}
index函数支持按传入的层级key依次读取嵌套map值,上述写法的逻辑是:从根作用域的Values对象中,先查找key为当前应用名(即.name对应的值)的子配置项,再分别读取子项中的image_repository和image_tag字段,无论配置是写在values.yaml中还是通过--set-string命令行传入,都可以正常渲染。
更易维护的配置优化方案
现有配置将应用基础信息放在containerApps列表、镜像配置单独放在顶层同名字段的结构维护成本较高,推荐将所有应用配置收敛,从根源上避免动态路径取值的问题,有两种常用的收敛方式:
方案1:保留列表结构
将每个应用的镜像配置直接放入containerApps的对应列表项中:# values.yaml containerApps: - name: app1 replicaCount: 1 image_repository: "" image_tag: "" ... - name: app2 replicaCount: 1 image_repository: "" image_tag: "" ... - name: app3 replicaCount: 1 image_repository: "" image_tag: "" ...模板不需要动态取值,直接读取当前循环项的字段即可:
{{- range $containerApp := .Values.containerApps }} {{- with $containerApp }} ... containers: - name: {{ .name }} image: "{{ .image_repository }}:{{ .image_tag }}" replicas: {{ .replicaCount }} ... ... {{- end }} {{- end }}命令行传参按列表索引指定路径即可:
helm template . --name-template my-app --namespace dev \ --set-string containerApps[0].image_repository=my-registry/image-app-1 \ --set-string containerApps[0].image_tag=073f799 \ --set-string containerApps[1].image_repository=my-registry/image-app-2 \ --set-string containerApps[1].image_tag=934df33 \ --set-string containerApps[2].image_repository=my-registry/image-app-3 \ --set-string containerApps[2].image_tag=k393caf \ --values values.yaml方案2:改用map结构(推荐)
将containerApps从列表改为以应用名为key的map结构,不需要关心列表顺序,传参和维护都更方便:# values.yaml containerApps: app1: replicaCount: 1 image_repository: "" image_tag: "" ... app2: replicaCount: 1 image_repository: "" image_tag: "" ... app3: replicaCount: 1 image_repository: "" image_tag: "" ...模板循环时同时读取应用名和对应配置:
{{- range $appName, $appConfig := .Values.containerApps }} ... containers: - name: {{ $appName }} image: "{{ $appConfig.image_repository }}:{{ $appConfig.image_tag }}" replicas: {{ $appConfig.replicaCount }} ... ... {{- end }}命令行传参直接按应用名指定路径,不受列表顺序变动影响:
helm template . --name-template my-app --namespace dev \ --set-string containerApps.app1.image_repository=my-registry/image-app-1 \ --set-string containerApps.app1.image_tag=073f799 \ --set-string containerApps.app2.image_repository=my-registry/image-app-2 \ --set-string containerApps.app2.image_tag=934df33 \ --set-string containerApps.app3.image_repository=my-registry/image-app-3 \ --set-string containerApps.app3.image_tag=k393caf \ --values values.yaml
内容的提问来源于stack exchange,提问作者Hutger Hauer
相关产品推荐
相关产品推荐

