如何在 helm 模板中包含嵌套值
How to include nested value in helm template
我在 helm 中有这种模板文件:
api版本:networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: {{.Values.app.name}}-global-route
namespace: {{.Release.Namespace}}
spec:
hosts:
- "{{.Values.app.name}}-global.{{.Release.Namespace}}.svc.cluster.local"
gateways:
- {{.Values.app.name}}-gateway
- mesh
http:
# 1st priority, to route specific end-user to canary service
- route:
- destination:
host: "{{.Values.app.name}}-global.{{.Release.Namespace}}.svc.cluster.local"
subset: canary
match: {{.Values.infra.trafficRoute.canaryCondition}}
我想公开 values.yaml 如下所示:
# default values supplied for templates/* files
app:
name: java-maven-app
infra:
trafficRoute:
canaryCondition:
- headers:
end-user:
exact: apratama
key:
exact: agung
所以,基本上我想要实现的是让最终用户(使用我的 helm chart 的人)自定义 canary 条件。条件本身取决于 istio 的 match
数据结构(可以是嵌套和复杂的值)。
我在上面尝试使用 helm upgrade --install
命令,但不知何故我得到了这个错误:
Error: UPGRADE FAILED: YAML parse error on java-maven-app-infra/templates/global-service.yaml: error converting YAML to JSON: yaml: line 17: found unexpected ':'
make: *** [deploy-infra] Error 1
然而,当我注释掉这一行时:
match: {{.Values.infra.trafficRoute.canaryCondition}}
它可以正常工作。
有什么建议吗?
已解决。我在#helm-users slack 频道 (kubernetes.slack.com) 中与一些人聊天,因此提供给模板的值是一个字符串值。因此需要将其转换为 yaml 对象并适当缩进。我通过稍微改变它来解决这个
# 1st priority, to route specific end-user to canary service
- route:
- destination:
host: "{{.Values.app.name}}-global.{{.Release.Namespace}}.svc.cluster.local"
subset: canary
match:
{{ toYaml .Values.infra.trafficRoute.canaryCondition | indent 4 }}
我们之前在 k8s Slack 中讨论过这个解决方案。我注意到你发布了你自己的答案,但我想我不妨稍微扩展一下,以防其他人遇到同样的问题。
问题是 Helm 图表模板执行文本模板而不是 YAML 模板。因此,插入的 YAML 子树 (canaryCondition
) 不会自动转换为 YAML 并优雅地放置在 match
键下,而是转换为字符串并直接插入模板指令所在的位置。对于字符串和整数等简单值,这适用于大多数情况,但更复杂的值(如数组和映射)需要以不同方式处理。
为了在模板中插入 YAML 子树,您需要先使用 toYaml
函数将子树转换为 YAML,然后确保使用正确的缩进级别 indent
函数。
{{ toYaml .Values.infra.trafficRoute.canaryCondition | indent 4 }}
有关如何在模板中插入 YAML 子树的另一个示例,请参阅 NGINX template example。
要开始调试 Helm 图表模板,您可以使用 helm template
命令查看 Helm 图表生成的 YAML。
如果对缩进有共同的混淆:
您也可以使用 left trim {{- toYaml ... }}
and nindent
(newline + indent) 来获得正确的缩进:
# 1st priority, to route specific end-user to canary service
- route:
- destination:
host: "{{.Values.app.name}}-global{{.Release.Namespace}}.svc.cluster.local"
subset: canary
match:
{{- toYaml .Values.infra.trafficRoute.canaryCondition | nindent 4 }}
我在 helm 中有这种模板文件:
api版本:networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: {{.Values.app.name}}-global-route
namespace: {{.Release.Namespace}}
spec:
hosts:
- "{{.Values.app.name}}-global.{{.Release.Namespace}}.svc.cluster.local"
gateways:
- {{.Values.app.name}}-gateway
- mesh
http:
# 1st priority, to route specific end-user to canary service
- route:
- destination:
host: "{{.Values.app.name}}-global.{{.Release.Namespace}}.svc.cluster.local"
subset: canary
match: {{.Values.infra.trafficRoute.canaryCondition}}
我想公开 values.yaml 如下所示:
# default values supplied for templates/* files
app:
name: java-maven-app
infra:
trafficRoute:
canaryCondition:
- headers:
end-user:
exact: apratama
key:
exact: agung
所以,基本上我想要实现的是让最终用户(使用我的 helm chart 的人)自定义 canary 条件。条件本身取决于 istio 的 match
数据结构(可以是嵌套和复杂的值)。
我在上面尝试使用 helm upgrade --install
命令,但不知何故我得到了这个错误:
Error: UPGRADE FAILED: YAML parse error on java-maven-app-infra/templates/global-service.yaml: error converting YAML to JSON: yaml: line 17: found unexpected ':'
make: *** [deploy-infra] Error 1
然而,当我注释掉这一行时:
match: {{.Values.infra.trafficRoute.canaryCondition}}
它可以正常工作。
有什么建议吗?
已解决。我在#helm-users slack 频道 (kubernetes.slack.com) 中与一些人聊天,因此提供给模板的值是一个字符串值。因此需要将其转换为 yaml 对象并适当缩进。我通过稍微改变它来解决这个
# 1st priority, to route specific end-user to canary service
- route:
- destination:
host: "{{.Values.app.name}}-global.{{.Release.Namespace}}.svc.cluster.local"
subset: canary
match:
{{ toYaml .Values.infra.trafficRoute.canaryCondition | indent 4 }}
我们之前在 k8s Slack 中讨论过这个解决方案。我注意到你发布了你自己的答案,但我想我不妨稍微扩展一下,以防其他人遇到同样的问题。
问题是 Helm 图表模板执行文本模板而不是 YAML 模板。因此,插入的 YAML 子树 (canaryCondition
) 不会自动转换为 YAML 并优雅地放置在 match
键下,而是转换为字符串并直接插入模板指令所在的位置。对于字符串和整数等简单值,这适用于大多数情况,但更复杂的值(如数组和映射)需要以不同方式处理。
为了在模板中插入 YAML 子树,您需要先使用 toYaml
函数将子树转换为 YAML,然后确保使用正确的缩进级别 indent
函数。
{{ toYaml .Values.infra.trafficRoute.canaryCondition | indent 4 }}
有关如何在模板中插入 YAML 子树的另一个示例,请参阅 NGINX template example。
要开始调试 Helm 图表模板,您可以使用 helm template
命令查看 Helm 图表生成的 YAML。
如果对缩进有共同的混淆:
您也可以使用 left trim {{- toYaml ... }}
and nindent
(newline + indent) 来获得正确的缩进:
# 1st priority, to route specific end-user to canary service
- route:
- destination:
host: "{{.Values.app.name}}-global{{.Release.Namespace}}.svc.cluster.local"
subset: canary
match:
{{- toYaml .Values.infra.trafficRoute.canaryCondition | nindent 4 }}