【问题标题】:Helm: Passing array values through --setHelm:通过 --set 传递数组值
【发布时间】:2021-08-03 22:12:18
【问题描述】:

我有一个 cronjob helm chat,我可以在 values.yaml 中定义许多工作,而 cronjob.yaml 将提供我的工作。我在命令行中设置图像标签 ID 时遇到了一个问题,以下命令不会引发错误,但不会将作业图像标签更新为新标签。

helm upgrade cronjobs cronjobs/ --wait --set job.myservice.image.tag=b70d744

cronjobs 将使用旧图像标签运行我该如何解决这个问题?

这是我的 cronjobs.yaml

{{- $chart_name := .Chart.Name }}
{{- $chart_version := .Chart.Version | replace "+" "_" }}
{{- $release_name := .Release.Name }}

{{- range $job := .Values.jobs }}
---
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  namespace: "{{ $job.namespace }}"
  name: "{{ $release_name }}-{{ $job.name }}"
  labels:
    chart: "{{ $chart_name }}-{{ $chart_version }}"
spec:
  concurrencyPolicy: {{ $job.concurrencyPolicy }}
  failedJobsHistoryLimit: {{ $job.failedJobsHistoryLimit }}
  suspend: {{ $job.suspend }}
  jobTemplate:
    spec:
      template:
        metadata:
          labels:
            app: {{ $release_name }}
            cron: {{ $job.name }}
        spec:
          containers:
          - image: "{{ $job.image.repository }}:{{ $job.image.tag }}"
            imagePullPolicy: {{ $job.image.imagePullPolicy }}
            ports:
              - name: http
                containerPort: 80
                protocol: TCP
            name: {{ $job.name }}
            args:
{{ toYaml $job.args | indent 12 }}
            env:
{{ toYaml $job.image.env | indent 12 }}
            volumeMounts:
            - name: nfs
              mountPath: "{{ $job.image.nfslogpath }}"
          restartPolicy: OnFailure
          imagePullSecrets:
            - name: {{ $job.image.secret }}
          volumes:
            - name: nfs
              nfs:
                server: "{{ $job.image.server }}"
                path: "{{ $job.image.nfspath }}"
                readOnly: false
  schedule: {{ $job.schedule | quote }}
  successfulJobsHistoryLimit: {{ $job.successfulJobsHistoryLimit }}
  {{- end }}

这是我的 values.yaml

jobs:
  - name: myservice
    namespace: default
    image:
      repository: xxx.com/myservice
      tag: fe4544
      pullPolicy: Always
      secret: xxx
      nfslogpath: "/var/logs/"
      nfsserver: "xxx"
      nfspath: "/nfs/xxx/cronjobs/"
      nfsreadonly: false
      env:
    schedule: "*/5 * * * *"
    args:
    failedJobsHistoryLimit: 1
    successfulJobsHistoryLimit: 3
    concurrencyPolicy: Forbid
    suspend: false

  - name: myservice2
    namespace: default
    image:
      repository: xxxx/myservice2
      tag: 1dff39a
      pullPolicy: IfNotPresent
      secret: xxxx
      nfslogpath: "/var/logs/"
      nfsserver: "xxxx"
      nfspath: "/nfs/xxx/cronjobs/"
      nfsreadonly: false
      env:
    schedule: "*/30 * * * *"
    args:
    failedJobsHistoryLimit: 1
    successfulJobsHistoryLimit: 2
    concurrencyPolicy: Forbid
    suspend: false

【问题讨论】:

    标签: kubernetes-helm


    【解决方案1】:

    如果您需要传递数组值,您可以使用花括号(unix shell 需要引号):

    --set test={x,y,z}
    --set "test={x,y,z}"
    

    结果 YAML:

    test:
      - x
      - y
      - z
    

    来源:https://helm.sh/docs/intro/using_helm/#the-format-and-limitations-of---set

    已编辑:为 bash 等 unix shell 添加了双引号

    【讨论】:

    • 这似乎不起作用,至少在 2.16 版本的 helm 中是这样。当运行helm upgrade opining-frog deploy/traefik/chart --set externalIps={a,b,c} --debug 之类的东西时,它会给出Error: This command needs 2 arguments: release name, chart path。您使用的是哪个版本的 helm?
    • 您是否先使用 --set 进行测试?示例:helm upgrade --set pwd=3jk$o2,z=f\30.e redis ./redis 来源:v2.helm.sh/docs/helm/#helm-upgrade
    • 非常感谢,这没有用,但我通过转义逗号让它工作(以防其他人面临同样的问题):helm upgrade opining-frog deploy/traefik/chart --set externalIps={a\,b\,c}。几个小时与此作斗争。
    • 谢谢大卫!似乎以下内容也将解决所述错误:--set "service.ListValue={a,b,c}"
    【解决方案2】:

    Update for Helm 2.5.0

    从 Helm 2.5.0 开始,可以使用数组索引语法访问列表项。

    例如,--set servers[0].port=80 变为:

    servers:
      - port: 80
    

    【讨论】:

    • @justin.m.chase - 不同意。这是将数组项设置为地图。虽然这很有用,但不是问题所在。
    【解决方案3】:

    由于您在 values.yaml 文件中使用数组,请参阅related issue

    替代解决方案

    • 您的 values.yaml 缺少 argsenv 的值。我在示例中设置了它们,并将缩进更改为 14

    • 您的 cronjob.yaml server: "{{ $job.image.server }}" 值为 null,我已将其更改为 .image.nfsserver

    不要使用数组,只需像下面的示例那样分隔您的服务:

    values.yaml

    jobs:
      myservice:
        namespace: default
        image:
          repository: xxx.com/myservice
          tag: fe4544
          pullPolicy: Always
          secret: xxx
          nfslogpath: "/var/logs/"
          nfsserver: "xxx"
          nfspath: "/nfs/xxx/cronjobs/"
          nfsreadonly: false
          env:
            key: val
        schedule: "*/5 * * * *"
        args:
          key: val
        failedJobsHistoryLimit: 1
        successfulJobsHistoryLimit: 3
        concurrencyPolicy: Forbid
        suspend: false
    
      myservice2:
        namespace: default
        image:
          repository: xxxx/myservice2
          tag: 1dff39a
          pullPolicy: IfNotPresent
          secret: xxxx
          nfslogpath: "/var/logs/"
          nfsserver: "xxxx"
          nfspath: "/nfs/xxx/cronjobs/"
          nfsreadonly: false
          env:
            key: val
        schedule: "*/30 * * * *"
        args:
          key: val
        failedJobsHistoryLimit: 1
        successfulJobsHistoryLimit: 2
        concurrencyPolicy: Forbid
        suspend: false
    

    在您的 cronjob.yaml 中使用 {{- range $job, $val := .Values.jobs }} 来迭代值。

    在您使用 {{ $job.name }} 的地方使用 $job

    使用 {{ .suspend }} 而不是 {{ $job.suspend }}

    访问像 suspend 这样的值

    cronjob.yaml

    {{- $chart_name := .Chart.Name }}
    {{- $chart_version := .Chart.Version | replace "+" "_" }}
    {{- $release_name := .Release.Name }}
    
    {{- range $job, $val := .Values.jobs }}
    ---
    apiVersion: batch/v1beta1
    kind: CronJob
    metadata:
      namespace: {{ .namespace }} 
      name: "{{ $release_name }}-{{ $job }}"
      labels:
        chart: "{{ $chart_name }}-{{ $chart_version }}"
    spec:
      concurrencyPolicy: {{ .concurrencyPolicy }}
      failedJobsHistoryLimit: {{ .failedJobsHistoryLimit }}
      suspend: {{ .suspend }}
      jobTemplate:
        spec:
          template:
            metadata:
              labels:
                app: {{ $release_name }}
                cron: {{ $job }}
            spec:
              containers:
              - image: "{{ .image.repository }}:{{ .image.tag }}"
                imagePullPolicy: {{ .image.imagePullPolicy }}
                ports:
                  - name: http
                    containerPort: 80
                    protocol: TCP
                name: {{ $job }}
                args:
    {{ toYaml .args | indent 14 }}
                env:
    {{ toYaml .image.env | indent 14 }}
                volumeMounts:
                - name: nfs
                  mountPath: "{{ .image.nfslogpath }}"
              restartPolicy: OnFailure
              imagePullSecrets:
                - name: {{ .image.secret }}
              volumes:
                - name: nfs
                  nfs:
                    server: "{{ .image.nfsserver }}"
                    path: "{{ .image.nfspath }}"
                    readOnly: false
      schedule: {{ .schedule | quote }}
      successfulJobsHistoryLimit: {{ .successfulJobsHistoryLimit }}
    {{- end }}
    

    使用 --set 传递值:

    helm upgrade cronjobs cronjobs/ --wait --set jobs.myservice.image.tag=b70d744

    示例:

    helm install --debug --dry-run --set jobs.myservice.image.tag=my123tag .

    ...
    HOOKS:
    MANIFEST:
    
    ---
    # Source: foo/templates/cronjob.yaml
    apiVersion: batch/v1beta1
    kind: CronJob
    metadata:
      namespace: default
      name: "illmannered-iguana-myservice"
      labels:
        chart: "foo-0.1.0"
    spec:
      concurrencyPolicy: Forbid
      failedJobsHistoryLimit: 1
      suspend: false
      jobTemplate:
        spec:
          template:
            metadata:
              labels:
                app: illmannered-iguana
                cron: myservice
            spec:
              containers:
              - image: "xxx.com/myservice:my123tag"
                imagePullPolicy:
                ports:
                  - name: http
                    containerPort: 80
                    protocol: TCP
                name: myservice
                args:
                  key: val
    
                env:
                  key: val
    
                volumeMounts:
                - name: nfs
                  mountPath: "/var/logs/"
              restartPolicy: OnFailure
              imagePullSecrets:
                - name: xxx
              volumes:
                - name: nfs
                  nfs:
                    server: "xxx"
                    path: "/nfs/xxx/cronjobs/"
                    readOnly: false
      schedule: "*/5 * * * *"
      successfulJobsHistoryLimit: 3
    ---
    # Source: foo/templates/cronjob.yaml
    apiVersion: batch/v1beta1
    kind: CronJob
    metadata:
      namespace: default
      name: "illmannered-iguana-myservice2"
      labels:
        chart: "foo-0.1.0"
    spec:
      concurrencyPolicy: Forbid
      failedJobsHistoryLimit: 1
      suspend: false
      jobTemplate:
        spec:
          template:
            metadata:
              labels:
                app: illmannered-iguana
                cron: myservice2
            spec:
              containers:
              - image: "xxxx/myservice2:1dff39a"
                imagePullPolicy:
                ports:
                  - name: http
                    containerPort: 80
                    protocol: TCP
                name: myservice2
                args:
                  key: val
    
                env:
                  key: val
    
                volumeMounts:
                - name: nfs
                  mountPath: "/var/logs/"
              restartPolicy: OnFailure
              imagePullSecrets:
                - name: xxxx
              volumes:
                - name: nfs
                  nfs:
                    server: "xxxx"
                    path: "/nfs/xxx/cronjobs/"
                    readOnly: false
      schedule: "*/30 * * * *"
      successfulJobsHistoryLimit: 2
    

    希望有帮助!

    【讨论】:

    • 现在支持使用 --set "test={x,y,z}"--set servers[0].port=80 传递数组,如其他答案中所述。
    • i 你的 cronjob.yaml 你定义了 $val 但从未使用过它,如果我尝试访问 .env 它会在范围循环内返回错误,nill 指针评估接口,你确定这是正确的如何访问循环内的变量?
    • @edbighead 你能在这里回答我的问题吗--> stackoverflow.com/questions/69173783/…我的问题比较简单。
    【解决方案4】:

    掌舵 3。这对我有用。 --set "servers[0].port=80" --set "servers[1].port=8080"

    【讨论】:

    • 这也适用于嵌套元素。一个例子:"elements[0].arguments[0].value=firstValue""elements[0].arguments[1].value=secondValue"
    猜你喜欢
    • 2020-01-21
    • 2022-11-07
    • 2022-08-11
    • 1970-01-01
    • 2012-10-20
    • 1970-01-01
    • 1970-01-01
    • 2011-02-03
    • 1970-01-01
    相关资源
    最近更新 更多