Helm 模板与 values.yaml 结构不兼容

Helm template is not compatible to values.yaml structure

我有以下 ingress.yaml:

spec:
{{- if .Values.ingress.tls }}
  tls:
  {{- range .Values.ingress.tls }}
    - hosts:
      {{- range .hosts }}
        - {{ . | quote }}
      {{- end }}
      secretName: {{ .secretName }}
  {{- end }}
{{- end }}
  rules:
  {{- range .Values.ingress.hosts }}
    - host: {{ .host }}                 // row 31
      http:
        paths:
        {{- range .paths }}
          - path: {{ . | quote }}
            backend:
              serviceName: {{ $fullName }}
              servicePort: {{ $svcPort }}
        {{- end }}
  {{- end }}
{{- end }}

并为该模板提供以下值:

  hosts:
    host: "app.example.com"
    paths:
      - "/api"
      - "/oauth"

  tls:
    - secretName: "example-tls"
      hosts:
        - "*.app.example.com"
        - "dev.example.com"

当我运行“helm install”失败时:

Error: UPGRADE FAILED: template: templates/ingress.yaml:31:15: executing "templates/ingress.yaml" at <.host>: can't evaluate field host in type interface {}

所以对我来说,hosts 看起来必须是一个列表,而不是字典(因为 range 指令)。所以我转换它:

  hosts:
    - host: "app.example.com"
      paths:
        - "/api"
        - "/oauth"

但在这种情况下我得到:

warning: destination for hosts is a table. Ignoring non-table value [map[host:app.example.com paths:[/api /oauth]]]

除此之外还有和上面一样的错误。

如何让它发挥作用?

更新 1

值:

ingress:
  enabled: true

  rules:
    - host: c1.app.example.com
      paths:
        - /api
        - /oauth
    - host: c2.app.example.com
      paths:
        - /api
        - /oauth
  tls:
    - secretName: "example-tls"
      hosts:
        - "*.app.example.com"
        - "dev.example.com"

模板:

{{- if .Values.ingress.tls }}
  tls:
  {{- range .Values.ingress.tls }}
    - hosts:
      {{- range .hosts }}
        - {{ . | quote }}
      {{- end }}
      secretName: {{ .secretName }}
  {{- end }}
{{- end }}
  rules:
  {{- range .Values.ingress.rules }}
    - host: {{ .host | quote }}
      http:
        paths:
        {{- range .paths }}
          - path: {{ . | quote }}
            backend:
              serviceName: {{ $fullName }}
              servicePort: {{ $svcPort }}
        {{- end }}
  {{- end }}
{{- end }}

更新 2

我知道问题不在代码中,而是在命令行中。我喂的是字符串而不是数组。

helm template ... --set ingress.hosts.host=c1.app.example.com ...

我将尝试弄清楚如何提供多个值并在此处更新它。

更新 3

我从值中删除了数据:

ingress:
  enabled: false

  rules:
    - host:

  tls:
    - secretName:
      hosts: []

模板正在寻找 .Values.ingress.hosts,而在您显示的值中没有 ingress 前缀。当使用 range 运算符时,我们应该有一个 字典列表 .

此外,在执行 helm install 之前,最好先 运行 helm template 以确保正确呈现 YAML 定义。

考虑到 values.yaml 中的以下内容:

--- 
ingress: 
  hosts: 
    - 
      host: app1.example.com
      paths: 
        - /api
        - /oauth
    - 
      host: app2.example.com
      paths: 
        - /api1
        - /authz
  tls:
    - hosts:
      - "*.app.example.com"
      - "dev.example.com"
      secretName: "example-tls"

运行 helm template 命令结果(为了说明,我将 serviceName 定义为 haproxy,将 servicePort 定义为 8080):

spec:
  tls:
    - hosts:
        - "*.app.example.com"
        - "dev.example.com"
      secretName: example-tls
  rules:
    - host: app1.example.com                 // row 31
      http:
        paths:
          - path: "/api"
            backend:
              serviceName: haproxy
              servicePort: 8080
          - path: "/oauth"
            backend:
              serviceName: haproxy
              servicePort: 8080
    - host: app2.example.com                 // row 31
      # similar output for app2.example.com

回答我自己的问题。

问题是入口模板结构与我为参数覆盖提供的命令行参数不匹配。

这是命令行参数的正确匹配:

helm upgrade <some other options here>
--values ./values.yaml
--set ingress.enabled=True
--set ingress.tls[0].hosts[0]=app.example.com
--set ingress.tls[0].secretName=example-tls
--set ingress.rules[0].host=app.example.com

填充 values.yaml:

ingress:
  enabled: false

  rules:
    - host:

  tls:
    - secretName:
      hosts: []

对于入口 模板:

spec:
{{- if .Values.ingress.tls }}
  tls:
  {{- range .Values.ingress.tls }}
    - secretName: {{ .secretName }}
      hosts:
      {{- range .hosts }}
        - {{ . | quote }}
      {{- end }}
  {{- end }}
{{- end }}
  rules:
  {{- range .Values.ingress.rules }}
    - host: {{ .host | quote }}
      http:
        paths:
        - path: /api
          backend:
            serviceName: {{ $fullName }}
            servicePort: {{ $svcPort }}
  {{- end }}
{{- end }}