helm模板文件chart编写语法

发布时间 2023-04-12 16:44:13作者: 凡人半睁眼

一、简单介绍

1、快速创建一个chart模板

helm create mychart

mychart
├── charts
├── Chart.yaml
├── templates
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── NOTES.txt
│   ├── serviceaccount.yaml
│   ├── service.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml

3 directories, 10 files
  • Chart.yaml: 该chart的描述文件,包括ico地址,版本信息等
  • values.yaml: 给模板文件使用的变量
  • charts: 依赖其他包的charts文件
  • requirements.yaml: 依赖的charts
  • README.md: 开发人员自己阅读的文件
  • templates: 存放k8s模板文件目录
    • NOTES.txt 说明文件,helm install之后展示给用户看的内容
    • deployment.yaml 创建k8s资源的yaml文件
    • _helpers.tpl: 下划线开头的文件,可以被其他模板引用的变量(_开头的文件不会被渲染成k8s资源)

一个最小的chart目录,只需要包含一个Chart.yaml,和templates目录下一个k8s资源文件.如:

2、helm的模板语法实现原理

- go-template
- sprig

二、helm模板语法

1、模板引用方式,{{ .Release.Name }}, 通过双括号注入,小数点开头表示从最顶层命名空间引用

2、helm内置对象和注释

# Release, release相关属性
# Chart, Chart.yaml文件中定义的内容
# Values, values.yaml文件中定义的内容
{{/* a comment */}}
    注释,执行时会忽略。可以多行。注释不能嵌套,并且必须紧贴分界符始止。

3、管道 pipeline

pipeline是指产生数据的操作。比如{{.}}、{{.Name}}等。Go的模板语法中支持使用管道符号|链接多个命令,用法和unix下的管道类似:|前面的命令会将运算结果(或返回值)传递给后一个命令的最后一个位置。

注意 : 并不是只有使用了|才是pipeline。Go的模板语法中,pipeline的概念是传递数据,只要能产生数据的,都是pipeline

apiVersion: v1
kind: ConfigMap
metadata:
   name: {{ .Release.Name }}-configmap
data:
  myvalue: "Hello World"
  drink: {{ .Values.favorite.drink | repeat 5 | quote }}
  food: {{ .Values.favorite.food | upper | quote }}

Action里可以初始化一个变量来捕获管道的执行结果。初始化语法如下:

$variable := pipeline
{{ $obj := "jack" }}
{{ $obj }} // 输出:jack

4、if语句

{{ if PIPELINE }}
# Do something
{{ else if OTHER PIPELINE }}
# Do something else
{{ else }}
# Default case
{{ end }}

{{if pipeline}} T1 {{end}} 
{{if pipeline}} T1 {{else}} T0 {{end}} 
{{if pipeline}} T1 {{else if pipeline}} T0 {{ else }} T2 {{end}}

5、操作符, and/eq/or/not

{{/* include the body of this if statement when the variable .Values.fooString exists and is set to "foo" */}}
{{ if and .Values.fooString (eq .Values.fooString "foo") }}
    {{ ... }}
{{ end }}


{{/* do not include the body of this if statement because unset variables evaluate to false and .Values.setVariable was negated with the not function. */}}
{{ if or .Values.anUnsetVariable (not .Values.aSetVariable) }}
   {{ ... }}
{{ end }}

6、控制语句块在渲染后生成模板会多出空行,需要使用{{- if ...}}的方式消除此空行

有时候我们在使用模板语法的时候会不可避免的引入一下空格或者换行符,这样模板最终渲染出来的内容可能就和我们想的不一样,

这个时候可以使用 {{-语法去除模板内容左侧的所有空白符号, 使用-}}去除模板内容右侧的所有空白符号。

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  myvalue: "Hello World"
  {{- if eq .Values.favorite.drink "coffee"}}
  mug: true
  {{- end}}

注意:-要紧挨{{和}},同时与模板值之间需要使用空格分隔。

7、引入相对命名空间,with(有待理解)

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  myvalue: "Hello World"
  {{- with .Values.favorite }}
  drink: {{ .drink | default "tea" | quote }}
  food: {{ .food | upper | quote }}
  {{- end }}

#####
{{with pipeline}} T1 {{end}}
如果pipeline为empty不产生输出,否则将dot设为pipeline的值并执行T1。不修改外面的dot。

{{with pipeline}} T1 {{else}} T0 {{end}}
如果pipeline为empty,不改变dot并执行T0,否则dot设为pipeline的值并执行T1。

8、range命令实现循环,如:

Go的模板语法中使用range关键字进行遍历,有以下两种写法,其中pipeline的值必须是数组、切片、字典或者通道。

# values.yaml
favorite:
  drink: coffee
  food: pizza
pizzaToppings:
  - mushrooms
  - cheese
  - peppers
  - onions

#configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  myvalue: "Hello World"
  toppings: |-
    {{- range .Values.pizzaToppings }}
    - {{ . }}
    # .表示range的命令空间下的取值
    {{- end }}
    {{- range $key, $val := .Values.favorite }}
    {{ $key }}: {{ $val | quote }}
    {{- end}} 

9、变量赋值

ApiVersion: v1
Kind: ConfigMap
Metadata:
  name: {{ .Release.Name }}-configmap
Data:
  myvalue: "Hello World"
  # 由于下方的with语句引入相对命令空间,无法通过.Release引入,提前定义relname变量
  {{- $relname := .Release.Name -}}
  {{- with .Values.favorite }}
  food: {{ .food }}
  release: {{ $relname }}
  # 或者可以使用$符号,引入全局命名空间
  release: {{ $.Release.Name }}
  {{- end }}

10、公共模板,define定义,template引入,在templates目录中默认下划线_开头的文件为公共模板(_helpers.tpl)

# _helpers.tpl文件
{{- 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"

11、template语句的升级版本include,template是语句无法在后面接管道符来对引入变量做定义,
include实现了此功能.

# _helpers.tpl文件
{{- define "mychart.app" -}}
app_name: {{ .Chart.Name }}
app_version: "{{ .Chart.Version }}+{{ .Release.Time.Seconds }}"
{{- end -}}

# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
  labels:
    {{- include "mychart.app" . | nindent 4 }}
data:
  myvalue: "Hello World"
  {{- range $key, $val := .Values.favorite }}
  {{ $key }}: {{ $val | quote }}
  {{- end }}
  {{- include "mychart.app" . | nindent 2 }}

# 如果使用template只能手动空格,不能使用管道后的nindent函数来做缩进

12、预定义函数

执行模板时,函数从两个函数字典中查找:首先是模板函数字典,然后是全局函数字典。一般不在模板内定义函数,而是使用Funcs方法添加函数到模板里。
预定义的全局函数如下:

and
    函数返回它的第一个empty参数或者最后一个参数;
    就是说"and x y"等价于"if x then y else x";所有参数都会执行;
or
    返回第一个非empty参数或者最后一个参数;
    亦即"or x y"等价于"if x then x else y";所有参数都会执行;
not
    返回它的单个参数的布尔值的否定
len
    返回它的参数的整数类型长度
index
    执行结果为第一个参数以剩下的参数为索引/键指向的值;
    如"index x 1 2 3"返回x[1][2][3]的值;每个被索引的主体必须是数组、切片或者字典。
print
    即fmt.Sprint
printf
    即fmt.Sprintf
println
    即fmt.Sprintln
html
    返回与其参数的文本表示形式等效的转义HTML。
    这个函数在html/template中不可用。
urlquery
    以适合嵌入到网址查询中的形式返回其参数的文本表示的转义值。
    这个函数在html/template中不可用。
js
    返回与其参数的文本表示形式等效的转义JavaScript。
call
    执行结果是调用第一个参数的返回值,该参数必须是函数类型,其余参数作为调用该函数的参数;
    如"call .X.Y 1 2"等价于go语言里的dot.X.Y(1, 2);
    其中Y是函数类型的字段或者字典的值,或者其他类似情况;
    call的第一个参数的执行结果必须是函数类型的值(和预定义函数如print明显不同);
    该函数类型值必须有1到2个返回值,如果有2个则后一个必须是error接口类型;
    如果有2个返回值的方法返回的error非nil,模板执行会中断并返回给调用模板执行者该错误;

13、比较

eq      如果arg1 == arg2则返回真
ne      如果arg1 != arg2则返回真
lt      如果arg1 < arg2则返回真
le      如果arg1 <= arg2则返回真
gt      如果arg1 > arg2则返回真
ge      如果arg1 >= arg2则返回真

  

 

 

 

 

 

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Go标准库:Go template 用法解读_试剑江湖。的博客-CSDN博客

helm模板文件chart编写语法详解_51CTO博客_vue模板语法