传递值给`range`内的`include`函数,使用合并时的默认值

huangapple go评论56阅读模式
英文:

Passing values to include function inside range, using defaults with merge

问题

根据您提供的YAML文件,问题在于您的Helm模板逻辑和值的处理方式。特别是在extraContainers的循环中,当您定义了某些值后,这些值会在后续迭代中保留,除非您明确覆盖它们。这是因为Helm模板默认采用逐层覆盖的方式,而不是合并。

要实现您所期望的行为,您可以采取以下步骤:

  1. 修改您的values.yaml文件,将extraContainers的资源值设置为nil,以便在后续迭代中不继承之前的值。如下所示:
extraContainers:
  extra-container2:
    image:
      name: xxx.dkr.ecr.eu-west-1.amazonaws.com/foobar-two
      tag: test
    # 将资源设置为nil
    resources: nil
    command:
      - sleep
      - 10
    envVars:
      - name: FOO
        value: BAR
    probes:
      readinessProbe:
        path: /ContainerTwoReadinessPath
      livenessProbe:
        path: /ContainerTwoLivenessPath

  extra-container3:
    image:
      name: xx.dkr.ecr.eu-west-1.amazonaws.com/foobar-three
      tag: latest
    # 将资源设置为nil
    resources: nil
    command:
      - sleep
      - 10
    envVars:
      - name: FOO
        value: BAZ
    probes:
      readinessProbe:
        enabled: false
      livenessProbe:
        enabled: false
  1. 在您的deployment.yaml模板中,确保在循环中检查资源是否为nil,如果为nil,则使用默认值。如下所示:
{{- range $k, $v := .Values.extraContainers }}
{{- $nameDict := dict "name" $k -}}
{{- include "app.container" (mustMergeOverwrite $.Values.app $nameDict $v) | nindent 8 }}
{{- include "ports" (merge $nameDict $v ) | nindent 8 }}
{{- with $v.resources }}
  resources:
    limits:
      cpu: {{ .limits.cpu | default .cpu | quote }}
      memory: {{ .limits.memory | default .memory | quote }}
    requests:
      cpu: {{ .requests.cpu | default .cpu | quote }}
      memory: {{ .requests.memory | default .memory | quote }}
{{- end }}
{{- end }}

通过将资源设置为nil,您可以确保extra-container3不会继承来自extra-container2的资源值,并且会使用默认的.values.app中的资源值。

英文:

Given this deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment
spec:
  revisionHistoryLimit: 5
  template:
    spec:
      containers:
      {{- include "app.container" (merge .Values.app $) | nindent 8 }}
      {{- include "ports" (merge .Values.app ) | nindent 8 }}
      {{- range $k, $v := .Values.extraContainers }}
      {{- $nameDict := dict "name" $k -}}
        {{- include "app.container" (mustMergeOverwrite $.Values.app $nameDict $v)  | nindent 8 }}
        {{- include "ports" (merge $nameDict $v ) | nindent 8 }}
      {{- end }}

This helpers file...

{{/* vim: set filetype=helm: */}}

{{/*
app container base
*/}}
{{- define "app.containerBase" -}}
- name: {{ .name | default "app" }}
  image: {{ .image.name }}:{{ .image.tag }}
  {{- if .command }}
  command:
    {{- range .command }}
    - {{ . | quote }}
    {{- end }}
  {{- end }}
  {{- if .args }}
  args:
    {{- range .args }}
    - {{ . | quote }}
      {{- end }}
  {{- end }}
    {{- range .envVars }}
    - name: {{ .name }}
      {{- with .value }}
      value: {{ . | quote }}
      {{- end }}
      {{- with .valueFrom }}
      valueFrom:
        {{- toYaml . | nindent 8 }}
      {{- end }}
    {{- end }}
  {{- if or .Values.configMaps .Values.secrets .Values.configMapRef }}
  envFrom:
    {{- if .Values.configMaps }}
    - configMapRef:
        name: "{{- include "app.fullname" $ }}"
    {{- end }}
    {{- range .Values.configMapRef }}
    - configMapRef:
        name: {{ . }}
    {{- end }}
    {{- range $name, $idk := $.Values.secrets }}
    - secretRef:
        name: "{{- include "app.fullname" $ }}-{{ $name }}"
    {{- end }}
  {{- end }}
{{- end -}}

{{/*
app container
*/}}
{{- define "app.container" -}}
{{- include "app.containerBase" . }}
  resources:
    limits:
      cpu: {{ .resources.limits.cpu | default "100m" | quote }}
      memory: {{ .resources.limits.memory | default "128Mi" | quote }}
      {{- if .resources.limits.ephemeralStorage }}
      ephemeral-storage: {{ .resources.limits.ephemeralStorage }}
      {{- end }}
    requests:
      cpu: {{ .resources.requests.cpu | default "100m" | quote }}
      memory: {{ .resources.requests.memory | default "128Mi" | quote }}
      {{- if .resources.requests.ephemeralStorage }}
      ephemeral-storage: {{ .resources.requests.ephemeralStorage }}
      {{- end }}
  securityContext:
    runAsNonRoot: true
    runAsUser: {{ .securityContext.runAsUser }}
    runAsGroup: {{ .securityContext.runAsGroup }}
    allowPrivilegeEscalation: false
{{- end -}}

{{/*
ports
*/}}
{{- define "ports" -}}
{{- if .port }}
  ports:
  - containerPort: {{ .port }}
  protocol: {{ .protocol | default "tcp" | upper }}
  {{- range .extraPorts}}
    - containerPort: {{ required ".port is required." .port }}
    {{- if .name }}
      name: {{ .name }}
    {{- end }}
    {{- if .protocol }}
      protocol: {{ .protocol | upper }}
    {{- end }}
  {{- end }}
{{- end }}
{{- end -}}



This values.yaml

extraContainers:
  extra-container2:
    image:
      name: xxx.dkr.ecr.eu-west-1.amazonaws.com/foobar-two
      tag: test
    command:
      - sleep
      - 10
    envVars:
      - name: FOO
        value: BAR
    probes:
      readinessProbe:
        path: /ContainerTwoReadinessPath
      livenessProbe:
        path: /ContainerTwoLivenessPath
    resources:
      limits:
        cpu: 200Mi
        memory: 2Gi
      requests:
        cpu: 200Mi
        memory: 2Gi
  extra-container3:
    image:
      name: xx.dkr.ecr.eu-west-1.amazonaws.com/foobar-three
      tag: latest
    command:
      - sleep
      - 10
    envVars:
      - name: FOO
        value: BAZ
    probes:
      readinessProbe:
        enabled: false
      livenessProbe:
        enabled: false

app:
  image:
    name: xx.dkr.ecr.eu-west-1.amazonaws.com/foobar
    tag: latest
  probes:
    readinessProbe:
      path: /_readiness
      enabled: true
    livenessProbe:
      path: /_liveness
      enabled: true
  port: 100
  resources:
    limits:
      cpu: 100Mi
      memory: 1Gi
    requests:
      cpu: 100Mi
      memory: 1Gi

Why does helm template result in the below:

---
# Source: corp-service/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment
spec:
  revisionHistoryLimit: 5
  template:
    spec:
      containers:
        - name: app
          image: xx.dkr.ecr.eu-west-1.amazonaws.com/foobar:latest
          resources:
            limits:
              cpu: "100Mi"
              memory: "1Gi"
            requests:
              cpu: "100Mi"
              memory: "1Gi"
          securityContext:
            runAsNonRoot: true
            runAsUser: 2000
            runAsGroup: 2000
            allowPrivilegeEscalation: false
        
          ports:
          - containerPort: 100
          protocol: TCP
        - name: extra-container2
          image: xx.dkr.ecr.eu-west-1.amazonaws.com/foobar-two:test
          command:
            - "sleep"
            - "10"
            - name: FOO
              value: "BAR"
          resources:
            limits:
              cpu: "200Mi"
              memory: "2Gi"
            requests:
              cpu: "200Mi"
              memory: "2Gi"
          securityContext:
            runAsNonRoot: true
            runAsUser: 2000
            runAsGroup: 2000
            allowPrivilegeEscalation: false
        
        - name: extra-container3
          image: xx.dkr.ecr.eu-west-1.amazonaws.com/foobar-three:latest
          command:
            - "sleep"
            - "10"
            - name: FOO
              value: "BAZ"
          resources:
            limits:
              cpu: "200Mi"
              memory: "2Gi"
            requests:
              cpu: "200Mi"
              memory: "2Gi"
          securityContext:
            runAsNonRoot: true
            runAsUser: 2000
            runAsGroup: 2000
            allowPrivilegeEscalation: false

i.e why does extra-container3 have resources: set with values from extra-container2 instead of taking them from the default set of resources found under .values.app.

essentially, i want extracontainers to use default values from .values.app unless i explicitly set them inside the extracontainers section. however it seems that if a previous iteration of the loop over extracontainers defines some values, they are used in the next iteration if they are not overriden.

the resources for extra-container3 i am expecting are:

resources:
    limits:
      cpu: 100Mi
      memory: 1Gi
    requests:
      cpu: 100Mi
      memory: 1Gi

what am i doing wrong?

答案1

得分: 3

所以这里涉及到了一些事情,但大多数情况下答案是 `(mergeMustOverwrite)` **改变** 了 `$dest` 映射,这会导致你的范围“记住”了它所看到的最后一个值,根据你的问题,这并不是你想要的行为。最简单的答案是将 `(deepCopy $.Values.app)` 用作 `$dest`,但由于我们稍后将要讨论的另一个错误,这里有一个星号。

你看,`(deepCopy $.Values.app)` 会因为你莫名其妙地使用了 `(merge .Values.app $)` 而在 `helm` 中导致堆栈溢出,它会引入 `Chart`、`Files`、`Capabilities` 和整个世界。我猜想你的 `_helpers.tpl` 必须是从别处复制粘贴过来的,这解释了在 `define` 中错误的相对 `.Values` 引用。修复的一种方式是移除 `.Values.configMaps`,这样它将跟踪 `.app` 上下文,就像我猜测你想要的那样,或者你可以将第一个 `(merge)` 更改为人为地创建一个 `"Values": {}` 项,只是为了在尝试引用 `.app.Values.configMaps` 时防止模板崩溃。正确的方法将取决于你的意图,但 `(merge .Values.app $)` 几乎肯定不是它。

所以,要么:

```diff
--- a/templates/_helpers.tpl
+++ b/templates/_helpers.tpl
@@ -28,13 +28,13 @@ app container base
         {{- toYaml . | nindent 8 }}
       {{- end }}
     {{- end }}
-  {{- if or .Values.configMaps .Values.secrets .Values.configMapRef }}
+  {{- if or .configMaps .secrets .configMapRef }}
   envFrom:
-    {{- if .Values.configMaps }}
+    {{- if .configMaps }}
     - configMapRef:
         name: "{{- include "app.fullname" $ }}"
     {{- end }}
-    {{- range .Values.configMapRef }}
+    {{- range .configMapRef }}
     - configMapRef:
         name: {{ . }}
     {{- end }}

或者:

       containers:
-      {{- include "app.container" (merge .Values.app $) | nindent 8 }}
+      {{- include "app.container" (merge .Values.app (dict "Values" (dict))) | nindent 8 }}
       {{- include "ports" (merge .Values.app ) | nindent 8 }}

<details>
<summary>英文:</summary>

So there are a couple of things going on here, but mostly the answer is that `(mergeMustOverwrite)` **mutates** the `$dest` map, which causes your range to &quot;remember&quot; the last value it saw, which according to your question isn&#39;t the behavior you want. The simplest answer is to use `(deepCopy $.Values.app)` as the `$dest`, but there&#39;s an asterisk to that due to another bug we&#39;ll cover in a second

```diff
       {{- $nameDict := dict &quot;name&quot; $k -}}
-        {{- include &quot;app.container&quot; (mustMergeOverwrite $.Values.app $nameDict $v)  | nindent 8 }}
+        {{- include &quot;app.container&quot; (mustMergeOverwrite (deepCopy $.Values.app) $nameDict $v)  | nindent 8 }}
         {{- include &quot;ports&quot; (merge $nameDict $v ) | nindent 8 }}
       {{- end }}

You see, (deepCopy $.Values.app) stack-overflows helm because of your inexplicable use of (merge .Values.app $) drags in Chart, Files, Capabilities and the whole world. I'm guessing your _helpers.tpl must have been copy-pasted from somewhere else, which explains the erroneous relative .Values reference inside that define. One way to fix that is to remove the .Values.configMaps, so it will track the .app context like I expect you meant, or you can change the first (merge) to artificially create a &quot;Values&quot;: {} item just to keep the template from blowing up when in tries to reference .app.Values.configMaps. The correct one will depend on what you were intending, but (merge .Values.app $) is almost certainly not it

so, either:

--- a/templates/_helpers.tpl
+++ b/templates/_helpers.tpl
@@ -28,13 +28,13 @@ app container base
         {{- toYaml . | nindent 8 }}
       {{- end }}
     {{- end }}
-  {{- if or .Values.configMaps .Values.secrets .Values.configMapRef }}
+  {{- if or .configMaps .secrets .configMapRef }}
   envFrom:
-    {{- if .Values.configMaps }}
+    {{- if .configMaps }}
     - configMapRef:
         name: &quot;{{- include &quot;app.fullname&quot; $ }}&quot;
     {{- end }}
-    {{- range .Values.configMapRef }}
+    {{- range .configMapRef }}
     - configMapRef:
         name: {{ . }}
     {{- end }}

or

       containers:
-      {{- include &quot;app.container&quot; (merge .Values.app $) | nindent 8 }}
+      {{- include &quot;app.container&quot; (merge .Values.app (dict &quot;Values&quot; (dict))) | nindent 8 }}
       {{- include &quot;ports&quot; (merge .Values.app ) | nindent 8 }}

huangapple
  • 本文由 发表于 2023年2月18日 03:25:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/75488507.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定