【问题标题】:Helm template is not compatible to values.yaml structureHelm 模板与 values.yaml 结构不兼容
【发布时间】:2020-12-05 14:22:40
【问题描述】:

我有以下 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”时,它失败了:

错误:升级失败:模板:templates/ingress.yaml:31:15: 在 <.host> 处执行“templates/ingress.yaml”:无法评估字段 类型接口 {}

中的主机

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

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

但在这种情况下,我得到:

警告:主机的目的地是一个表。忽略非表值 [map[host:app.example.com 路径:[/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 模板 ... --set ingress.hosts.host=c1.app.example.com ...

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

更新 3

我从值中删除了数据:

ingress:
  enabled: false

  rules:
    - host:

  tls:
    - secretName:
      hosts: []

【问题讨论】:

  • 问题解决了吗?
  • @HelloWorld 我刚刚放置了 UPDATE 3。这是一个解决方案。
  • 请将答案作为实际答案提供,而不是更新问题。让问题成为问题并使用答案发布答案​​,不要将它们混合在一起。很难看出这是解决方案。添加答案后,请将其标记为已接受。谢谢
  • @HelloWorld 完成。

标签: kubernetes-helm kubernetes-ingress


【解决方案1】:

回答我自己的问题。

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

这是命令行参数的恰当搭配:

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 }}

【讨论】:

    【解决方案2】:

    模板正在寻找.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
    
    

    【讨论】:

    • 谢谢。我有入口(只是把它剪掉了,因为它是多余的)。在 UPDATE 1 中,我根据您所说的进行了改进。仍然没有运气。顺便说一句,我注意到命名很重要。当我将“主机”重命名为“规则”时,它跳到了“路径”部分。请查看更新 1。
    • 好吧,UPDATE 1 不相关。现在更新 2 :)
    • 好吧--set 是另一种向模板提供值的方式。您也可以使用-f values.yaml 传递它。两者应该是一样的。
    猜你喜欢
    • 2019-09-21
    • 2022-08-16
    • 2022-08-03
    • 2023-03-19
    • 2020-04-15
    • 2022-12-17
    • 2021-12-18
    • 2021-06-17
    相关资源
    最近更新 更多