Named Templates(命名模板)
概述
参考:
Named Templates(命名模板,有时称为 partial(部分) 或 subtemplate(子模板)) 是限定在一个文件内部的模板,并起一个名称。Named Templates 可以在一个文件中定义,并在其他地方使用它们。
我们有两种创建方法,以及几种不同的使用方法。
在 控制结构与变量 章节中,我们介绍了声明和管理模板三个动作:define,template,和 block。在本节中,我们将介绍这三个动作,并介绍一个 include 函数,与 template 类似功能。
在命名模板时要注意一个重要的细节:模板名称是全局的。如果声明两个具有相同名称的模板,则最后加载一个模板是起作用的模板。由于子 chart 中的模板与顶级模板一起编译,因此注意小心地使用特定 chart 的名称来命名模板。
通用的命名约定是为每个定义的模板添加 chart 名称:{{define “mychart.labels”}}。通过使用特定 chart 名称作为前缀,我们可以避免由于同名模板的两个不同 chart 而可能出现的任何冲突。
partials 和 _ 文件
到目前为止,我们已经使用了一个文件,一个文件包含一个模板。但 Helm 的模板语言允许创建指定的嵌入模板,可以通过名称访问。
在我们开始编写这些模板之前,有一些文件命名约定值得一提:
- 大多数文件 templates/ 被视为包含 Kubernetes manifests
- NOTES.txt 是一个例外
- 名称以下划线(_)开头的文件被假定为没有内部 manifest。这些文件不会渲染 Kubernetes 对象定义,而是在其他 chart 模板中随处可用以供调用。
这些文件用于存储 partials 和辅助程序。事实上,当我们第一次创建时 mychart,我们看到一个叫做文件 _helpers.tpl。该文件是模板 partials 的默认位置。
define 定义模板 && template 引用模板
define 定义模板,语法如下:
{{ define "MY.NAME" }}
# body of template here
{{ end }}
例如,我们可以定义一个模板来封装一个 Kubernetes 标签块:
{{- define "mychart.labels" }}
labels:
generator: helm
date: {{ now | htmlDate }}
{{- end }}
template 引用模板,语法如下:
template "模板名" [范围]
现在我们可以将此模板嵌入到现有的 ConfigMap 中,然后将其包含在 template 操作中:
{{- define "mychart.labels" }}
labels:
generator: helm
date: {{ now | htmlDate }}
{{- end }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
{{- template "mychart.labels" }}
data:
myvalue: "Hello World"
{{- range $key, $val := .Values.favorite }}
{{ $key }}: {{ $val | quote }}
{{- end }}
当模板引擎读取该文件时,它将存储引用 mychart.labels 直到 template “mychart.labels” 被调用。然后它将在文件内渲染该模板。所以结果如下所示:
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: running-panda-configmap
labels:
generator: helm
date: 2016-11-02
data:
myvalue: "Hello World"
drink: "coffee"
food: "pizza"
Helm chart 通常将这些模板放入 partials 文件中,默认是 _helpers.tpl 文件
{{/* Generate basic labels */}}
{{- define "mychart.labels" }}
labels:
generator: helm
date: {{ now | htmlDate }}
{{- end }}
按照惯例,define 函数应该有一个简单的文档块({{/_ … _/}})来描述他们所做的事情。
即使这个定义在 _helpers.tpl,它仍然可以在 configmap.yaml 以下位置访问:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
{{- template "mychart.labels" }}
data:
myvalue: "Hello World"
{{- range $key, $val := .Values.favorite }}
{{ $key }}: {{ $val | quote }}
{{- end }}
如上所述, 模板名称是全局的 。因此,如果两个模板被命名为相同的名称,则最后一次使用的模板将被使用。由于子 chart 中的模板与顶级模板一起编译,因此最好使用 chart 专用名称命名模板。一个流行的命名约定是为每个定义的模板添加 chart 名称:{{define “mychart.labels”}}。
设置模板的范围
在我们上面定义的模板中,我们没有使用任何对象。我们只是使用函数。当时,如果要在命名模板中,引用对象,则会产生如下问题:
{{/* Generate basic labels */}}
{{- define "mychart.labels" }}
labels:
generator: helm
date: {{ now | htmlDate }}
chart: {{ .Chart.Name }}
version: {{ .Chart.Version }}
{{- end }}
如果我们这样做,将不会得到我们所期望的结果:
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: moldy-jaguar-configmap
labels:
generator: helm
date: 2016-11-02
chart:
version:
名称和版本发生了什么变化?他们不在我们定义的模板的范围内。当一个已命名的模板(用于创建 define)被渲染时,它将接收由该 template 调用传入的作用域。在我们的例子中,我们包含了这样的模板:
{{- template "mychart.labels" }}
没有范围被传入,因此在模板中我们无法访问任何内容.。虽然这很容易解决。我们只需将范围传递给模板:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
{{- template "mychart.labels" . }}
请注意,我们在调用 template 时末尾传递了 .。我们可以很容易地通过 .Values 或者 .Values.favorite 或者我们想要的任何范围。但是我们想要的是顶级范围。
现在,当我们用 helm install –dry-run –debug ./mychart 执行这个模板,我们得到这个:
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: plinking-anaco-configmap
labels:
generator: helm
date: 2016-11-02
chart: mychart
version: 0.1.0
现在 {{.Chart.Name}} 解析为 mychart,{{ .Chart.Version }} 解析为 0.1.0。
include 函数,引用模板的另一种方式
假设我们已经定义了一个如下所示的简单模板:
{{- define "mychart.app" -}}
app_name: {{ .Chart.Name }}
app_version: "{{ .Chart.Version }}+{{ .Release.Time.Seconds }}"
{{- end -}}
现在我想插入到我的模板的 labels: 部分和 data: 部分:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
labels:
{{ template "mychart.app" .}}
data:
myvalue: "Hello World"
{{- range $key, $val := .Values.favorite }}
{{ $key }}: {{ $val | quote }}
{{- end }}
{{ template "mychart.app" . }}
输出不是我们所期望的:
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: measly-whippet-configmap
labels:
app_name: mychart
app_version: "0.1.0+1478129847"
data:
myvalue: "Hello World"
drink: "coffee"
food: "pizza"
app_name: mychart
app_version: "0.1.0+1478129847"
注意,app_version 缩进在两个地方都是错误的。为什么?因为被替换的模板具有与右侧对齐的文本。因为 template 是一个动作,而不是一个函数,所以没有办法将 template 调用的输出传递给其他函数; 数据只是内嵌插入。
为了解决这个问题,Helm 提供了一个替代 template 方案,将模板的内容导入到当前管道中,并将其传递到管道中的其函数。
这里是上面的例子,用 indent 纠正正确缩进 mychart_app 模板:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
labels:
{{ include "mychart.app" . | indent 4 }}
data:
myvalue: "Hello World"
{{- range $key, $val := .Values.favorite }}
{{ $key }}: {{ $val | quote }}
{{- end }}
{{ include "mychart.app" . | indent 2 }}
现在生成的 YAML 每个部分都正确缩进:
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: edgy-mole-configmap
labels:
app_name: mychart
app_version: "0.1.0+1478129987"
data:
myvalue: "Hello World"
drink: "coffee"
food: "pizza"
app_name: mychart
app_version: "0.1.0+1478129987"
注意:在 Helm 模板中使用 include 比 template 会更好,可以更好地为 YAML 处理输出格式。
有时我们想要导入内容,但不是作为模板。也就是说,我们要逐字输入文件。我们下一节中描述可以通过使用 .Files
的对象来读取文件。
在 Templates(模板中) 访问文件
官方文档:https://helm.sh/docs/chart_template_guide/accessing_files/
反馈
此页是否对你有帮助?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.