在 Helm 模板中,如何使用一个列表中的项目来迭代另一个列表

在 Helm 模板中,如何使用一个列表中的项目来迭代另一个列表

我想预先填充一个 Kubernetes 集群,其中包含我们应用和服务的命名空间及其各自的机密。为此,我希望能够指定 2 个列表,1 个包含机密的列表和 1 个包含命名空间的列表。列表中的每个命名空间都有一个机密列表。就像这个 values.yaml:

secrets:
  - name: secret1
    data: key1
  - name: secret2
    data: key2
  - name: secret3
    data: key3

namespaces:
  - name: app1
    secrets:
      - secret1
      - secret2
  - name: app2
    secrets:
      - secret1
      - secret3

然后我想循环命名空间来创建命名空间,例如:

{{- range $namespaces := .Values.namespaces }}
apiVersion: v1
kind: Namespace
metadata:
  name: {{ $namespaces.name }}
---
{{- end }}

在该循环中,我希望在此循环内再添加一个循环,使用来自机密列表的数据为每个命名空间创建机密。有点像这样:

{{- range $secrets := .secrets }}
apiVersion: v1
kind: Secret
metadata:
  name: {{ .name }}
  namespace: {{ $namespaces.name }}
type: kubernetes.io/tls
data: $secrets.data
---
{{- end }}

但是如果我将该循环放在命名空间循环中,它只会在所有命名空间中的机密列表中创建所有机密。我怎样才能让循环只创建命名空间列表中指定的机密?
我认为可以使用 go 模板索引函数来完成,但我不知道怎么做。

答案1

我已经重现了您的问题并找到了答案。

你的例子

我使用你的 yamls 创建命名空间并更改了第二个,因此它现在实际上可以工作了。

值.yaml

secrets:
  - name: secret1
    data: key1
  - name: secret2
    data: key2
  - name: secret3
    data: key3

namespaces:
  - name: app1
    secrets:
      - secret1
      - secret2
  - name: app2
    secrets:
      - secret1
      - secret3

模板/命名空间.yaml

{{- range $namespaces := .Values.namespaces }}
apiVersion: v1
kind: Namespace
metadata:
  name: {{ $namespaces.name }}
---
{{- end }}

{{- range $namespace := .Values.namespaces }}                                                                               
{{- range $secret := $namespace.secrets }}                                                                                  
---                                                                                                                         
apiVersion: v1                                                                                                              
kind: Secret                                                                                                                
metadata:                                                                                                                   
  name: {{ $secret }}                                                                                                       
  namespace: {{ $namespace.name }}                                                                                          
type: kubernetes.io/tls                                                                                                     
data: $secrets.data                                                                                                         
---                                                                                                                         
{{- end }}                                                                                                                  
{{- end }}

结果:

COMPUTED VALUES:
namespaces:
- name: app1
  secrets:
  - secret1
  - secret2
- name: app2
  secrets:
  - secret1
  - secret3
secrets:
- data: key1
  name: secret1
- data: key2
  name: secret2
- data: key3
  name: secret3

HOOKS:
MANIFEST:

---
# Source: mychart/templates/namespaces.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: app1
---
# Source: mychart/templates/namespaces.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: app2
---
# Source: mychart/templates/namespaces.yaml
apiVersion: v1
kind: Secret
metadata:
  name: secret1
  namespace: app1                  
type: kubernetes.io/tls
data: $secrets.data
---
# Source: mychart/templates/namespaces.yaml
apiVersion: v1
kind: Secret
metadata:
  name: secret2
  namespace: app1                  
type: kubernetes.io/tls
data: $secrets.data
---
# Source: mychart/templates/namespaces.yaml
apiVersion: v1
kind: Secret
metadata:
  name: secret1
  namespace: app2                  
type: kubernetes.io/tls
data: $secrets.data
---
# Source: mychart/templates/namespaces.yaml
apiVersion: v1
kind: Secret
metadata:
  name: secret3
  namespace: app2                  
type: kubernetes.io/tls
data: $secrets.data

我的想法是

不要为命名空间创建秘密,而是反过来做,创建秘密并向其添加命名空间。

值.yaml

Secret1:
- namespace1
- namespace2

Secret2:
- namespace2

模板/命名空间.yaml

{{- range $namespaces := .Values.namespaces }}
apiVersion: v1
kind: Namespace
metadata:
  name: {{ $namespaces.name }}
---
{{- end }}

模板/secrets.yaml

{{- range .Values.Secret1 }}
---
apiVersion: v1
data:
  password: MWYyZDFlMmU2N2Rm
  username: YWRtaW4=
kind: Secret
metadata:
  creationTimestamp: null
  name: secret1
  namespace: {{ . }}
{{- end}}
{{- range .Values.Secret2 }}
---
apiVersion: v1
data:
  password: MWYyZDFlMmU2N2Rm
  username: YWRtaW4=
kind: Secret
metadata:
  creationTimestamp: null
  name: secret2
  namespace: {{ . }}
{{- end}}

结果:

COMPUTED VALUES:
Secret1:
- namespace1
- namespace2
Secret2:
- namespace2
namespaces:
- name: namespace1
- name: namespace2

HOOKS:
MANIFEST:

---
# Source: mychart/templates/namespaces2.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: namespace1
---
# Source: mychart/templates/namespaces2.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: namespace2
---
# Source: mychart/templates/namespaces.yaml
apiVersion: v1                                                                                                              
data:                                                                                                                       
  password: UyFCXCpkJHpEc2I=                                                                                                   
  username: ZGV2dXNlcg==                                                                                                      
kind: Secret                                                                                                                
metadata:                                                                                                                   
  creationTimestamp: null                                                                                                   
  name: secret1                                                                                                             
  namespace: namespace2
---
# Source: mychart/templates/namespaces.yaml
apiVersion: v1                                                                                                              
data:                                                                                                                       
  password: ZGV2dXNlcg==                                                                                              
  username: UyFCXCpkJHpEc2I=                                                                                                    
kind: Secret                                                                                                                
metadata:                                                                                                                   
  creationTimestamp: null                                                                                                   
  name: secret2                                                                                                             
  namespace: namespace2
---
# Source: mychart/templates/namespaces.yaml
apiVersion: v1                                                                                                              
data:                                                                                                                       
  password: UyFCXCpkJHpEc2I=                                                                                                   
  username: ZGV2dXNlcg==                                                                                                      
kind: Secret                                                                                                                
metadata:                                                                                                                   
  creationTimestamp: null                                                                                                   
  name: secret1                                                                                                             
  namespace: namespace1

有关流量控制(if、else if、range)的更多信息,请参见这里

答案2

我发现这篇文章非常有用。我需要一个稍微不同的用例,但目前还无法实现。

值.yaml

    customCerts:
  - name: test
    secrets:
      tls.crt: |
        -----BEGIN CERTIFICATE-----
        xxxx
        -----END CERTIFICATE-----
      tls.key: |
        -----BEGIN RSA PRIVATE KEY-----
        xxxx
        -----END RSA PRIVATE KEY-----
  - name: test2
    secrets:
      tls.crt: |
        -----BEGIN CERTIFICATE-----
        xxxx
        -----END CERTIFICATE-----
      tls.key: |
        -----BEGIN RSA PRIVATE KEY-----
        xxxx
        -----END RSA PRIVATE KEY-----

秘密.yaml

{{- range $customCerts := .Values.customCerts }}
---
apiVersion: v1
kind: Secret
metadata:
  name: {{ .name }}
  namespace: {{ .Release.Namespace }}
stringData:
  {{ .secrets  | indent 2 }}
---
{{- end }}

我有两个问题:

  • .Release.Namespace 在 {{ range }} 内不起作用
  • 我无法通过 {{ .secrets }} 获取秘密

编辑

.Release.Namespace我通过在开头添加以下内容解决了该问题:{{- $root := . -}}然后使用{{ $root.Release.Namespace }}

  • 但我仍然无法填补这个秘密tls.keytls.crt条目

编辑2:

我现在可以列出秘密,但我无法删除“|”字符:

值.yaml:

customCerts:
  - name: test
    secrets: |
      tls.crt: |
        -----BEGIN CERTIFICATE-----
        xxxx
        -----END CERTIFICATE-----
      tls.key: |
        -----BEGIN RSA PRIVATE KEY-----
        xxxx
        -----END RSA PRIVATE KEY-----
  - name: test2
    secrets: |
      tls.crt: |
        -----BEGIN CERTIFICATE-----
        xxxx
        -----END CERTIFICATE-----
      tls.key: |
        -----BEGIN RSA PRIVATE KEY-----
        xxxx
        -----END RSA PRIVATE KEY-----

secrets.yaml:

{{- $root := . -}}
{{- range $customCerts := .Values.customCerts }}
---
apiVersion: v1
kind: Secret
metadata:
  name: {{ .name }}
  namespace: {{ $root.Release.Namespace }}
stringData:
  {{ toYaml .secrets }}
---
{{- end }}

输出:

# Source: ciam-app/templates/secretsCustomCerts.yaml
apiVersion: v1
kind: Secret
metadata:
  name: test
  namespace: qbel1-ciam
stringData:
  |
  tls.crt: |
    -----BEGIN CERTIFICATE-----
    xxxx
    -----END CERTIFICATE-----
  tls.key: |
    -----BEGIN RSA PRIVATE KEY-----
    xxxx
    -----END RSA PRIVATE KEY-----
---
# Source: ciam-app/templates/secretsCustomCerts.yaml
---
apiVersion: v1
kind: Secret
metadata:
  name: test2
  namespace: qbel1-ciam
stringData:
  |
  tls.crt: |
    -----BEGIN CERTIFICATE-----
    xxxx
    -----END CERTIFICATE-----
  tls.key: |
    -----BEGIN RSA PRIVATE KEY-----
    xxxx
    -----END RSA PRIVATE KEY-----

|我无法摆脱stringData

编辑3:

我终于找到了一种方法:

  {{ toYaml .secrets | trimPrefix "|" | trim }}

也许这会对其他人有所帮助。

相关内容