继承头盔模板

时间:2019-12-01 16:49:36

标签: kubernetes-helm

我有将近25个部署和服务。每个Helm模板都有以下内容:

apiVersion: v1
kind: Deployment
metadata:
  name: aa1
spec:
  replicas: 1
  strategy: {}
  template:
    metadata:
      labels:
        app: aa1
    spec:
      containers:
      - env:
        - name: {{ .Values.env1 }}
          value: "yes"
        volumeMounts:
        - name: {{ .Values.v1 }}
          mountPath: {{ .Values.v1monthPath}}
          subPath: {{ .Values.v1subpath }}

类似地,我为所有25个模板定义了相同的envvolumeMount

有什么办法可以在Helm中使用模板继承?

1 个答案:

答案 0 :(得分:0)

单个Helm .tpl文件可以包含多个YAML文档,并用---文档开始分隔符分隔。另外,您可以使用所有标准的Go text/template功能,包括其循环结构。

这意味着您可以编写如下模板:

{{- $top := . -}}
{{- range .Values.names -}}
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ . }}
spec:
  ...
  template:
    spec:
      containers:
      - env:
        - name: {{ $top.Values.env1 }}
          value: "yes"
---
apiVersion: v1
kind: Service
metadata:
  name: {{ . }}
spec: { ... }
{{ end -}}

这首先是保存当前上下文;由于range将当前模板默认上下文.重置为迭代器值,因此我们需要记住其当前值。然后,我们遍历值文件中列表中的每个值。 (Sprig list函数可以在模板中创建列表。)对于每个项目,我们创建一个Deployment和Service,每个部署和服务都以---开头。当我们需要当前名称时,它是.;当我们需要从Helm值中获取某些东西时,我们需要在$top.Values中明确地查找它。

另一种可能的方法是为部署和服务编写单独的模板,然后使文件分别调用它们。从技术上讲,模板仅需要一个参数,但是您可以使用listindex来使一个参数成为列表。

{{/* _deployment.tpl */}}
{{- define "deployment" -}}
{{- $name := index 0 . -}}
{{- $top := index 1 . -}}
---
apiVersion: apps/v1
kind: Deployment
...
name: {{ $name }}
...
name: {{ $top.Values.env1 }}
...
{{ end -}}
{{/* aa1.yaml */}}
{{- template "deployment" (list "aa1" .) -}}
{{- template "service" (list "aa1" .) -}}

这几乎会变得非常复杂(您可以基于当前对象名称使用条件;可以使用模板index函数在values对象中查找值;依此类推)。 helm template会进行一些验证,并将渲染的模板写到stdout而不调用Kubernetes,这有助于将其视而不见,并且可以作为自动化测试的基础。

文本/模板的“继承”功能(使用例如 block)在这里并不是很好的匹配。 (*text/template.Template).Parse的文档指出,如果多次调用Parse,则最后找到的define将获胜,这为您提供了一个空间Parse和占位符{ {1}},然后block是重新定义的精致模板。 Helm并没有真正使用此功能。在将所有YAML和支持模板文件加载到同一模板实例中的同时,它分别渲染所有顶级文件,而不是渲染一些允许覆盖的根模板。