如何在掌舵模板中包含嵌套值

时间:2018-08-13 05:17:24

标签: kubernetes-helm

我掌控着这种模板文件:

apiVersion: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

因此,基本上我想要实现的是让最终用户(使用我的头盔图的用户)自定义加纳利条件。条件本身取决于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}}

它正常工作。

有什么建议吗?

3 个答案:

答案 0 :(得分:3)

我们之前在k8s Slack中讨论了此解决方案。我注意到您发布了自己的答案,但我想我也可以对此加以扩展,以防其他人遇到相同的问题。

问题在于,Helm图表模板执行文本模板而不是YAML模板。因此,插入的YAML子树(canaryCondition)不会自动转换为YAML并优雅地放置在match键下,而是将其转换为字符串并直接插入template指令所在的位置。使用简单的值(例如字符串和整数),在大多数情况下都可以正常工作,但是更复杂的值(例如数组和映射)则需要以不同的方式处理。

为了在模板中插入YAML子树,您需要先使用toYaml函数将子树转换为YAML,然后确保indent使用正确的缩进级别功能。

{{ toYaml .Values.infra.trafficRoute.canaryCondition | indent 4 }}

有关如何在模板中插入YAML子树的另一个示例,请参见NGINX template example

要开始调试Helm图表模板,可以使用helm template命令查看Helm图表生成的YAML。

答案 1 :(得分:3)

如果缩进出现共同的困惑:

您还可以使用left trim {{- toYaml ... }}nindentnewline + 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 }}

答案 2 :(得分:0)

已解决。我在#helm-users松弛频道(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 }}