以下操作,均原取自官网,由个人进行实操。
官网地址:
Helm | 命名模板如何定义命名模板https://helm.sh/zh/docs/chart_template_guide/named_templates/
操作前准备:
1. 有一台云服务器(已配置成为master结点),确保集群所有pod正常运行。
2. 已安装下载HELM。
3. 已创建了一个chart, 并且删除templates文件夹下的所有。
4. 已在values.yaml文件中插入:
favorite:
drink: coffee
food: pizza
pizzaToppings:
- mushrooms
- cheese
- peppers
- onions
5. 在templates下新建configmap.yaml文件,下面的操作均只针对该文件。
命名模板 - define&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 }}
引擎会识别到define标签,读取到模板,在template调用它时引入。
但实际上,命名模板我们一般不会写在configmap.yaml上,而是写在_helper.tql文件中,就是templates目录下最开始生成的那个文件。这里就可以创建。然后把上面的configmap.yaml拆一下即可:
({{/* */}}在define模板这里是注释作用)
_helper.tql:
{{/* Generate basic labels */}}
{{- define "mychart.labels" }}
labels:
generator: helm
date: {{ now | htmlDate }}
{{- end }}
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 }}
这里就有疑问了,如果要在模板中调用对象, 那么对象的范围是全局下来都可以访问吗?答案不是的,而且通过template调用时在末尾传入传输模板范围。
可以修改一下_helper.tql,让它调用一下外部对象的属性,改为:
{{/* Generate basic labels */}}
{{- define "mychart.labels" }}
labels:
generator: helm
date: {{ now | htmlDate }}
chart: {{ .Chart.Name }}
version: {{ .Chart.Version }}
{{- end }}
如果直接运行chart,会报错:
Error: INSTALLATION FAILED: unable to build kubernetes objects from release manifest: error validating "": error validating data: [unknown object type "nil" in ConfigMap.metadata.labels.chart, unknown object type "nil" in ConfigMap.metadata.labels.version]
把configmap.yaml的↓部分,从左框改为右框(指定作用域“.”):
{{- template "mychart.labels" }} | {{- template "mychart.labels" . }} |
运行结果:
命名模板 - define&include
把_helper.tql修改为(会发现缩进都没有,就是普通的模板,这才是正常的情况):
{{- define "mychart.app" -}}
app_name: {{ .Chart.Name }}
app_version: "{{ .Chart.Version }}"
{{- end -}}
然后此时的configmap.yaml为
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 }}
报错:Error: INSTALLATION FAILED: unable to build kubernetes objects from release manifest....
原因是缩进不对,yaml格式错误,在运行命令加参数(--disable-openapi-validation就可以看到)
[root@k8s-master testchart]# helm install --dry-run --disable-openapi-validation chart17 ./mychart
这时候就需要include方法来代替template方法,配合indent方法,加缩进,如果留着原先template的空格,用indent 2,看着好像格式是没问题的,但是这会报错,indent函数使用必须前面不保留缩进。
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
labels:
{{- include "mychart.labels" . | indent 4 }}
data:
myvalue: "Hello World"
{{- range $key, $val := .Values.favorite }}
{{ $key }}: {{ $val | quote }}
{{- end }}
结果: