到目前为止,我们已经知道了如何将数据传入到模板中。但是传入的数据并不能被修改。Helm 提供了一种方式“函数”,可以实现传入数据的转换。Helm 有超过60个可用函数,通过使用这些函数,我们可以非常方便的对转入的数据进行转换。
- 当我们讨论"Helm模板语言"时,感觉它是Helm专属的,实际上他是由Go模板语言、一些额外的函数和用于向模板暴露某些对象的装饰器组合而成的。很多Go模板的资料也有助于你学习模板。
- Helm函数大部分都是 Sprig 模板库,也有一些通过 Go模板语言本身定义。
1、认识模板函数和管道
模板函数和管道符是转换信息然后将其插入到YAML中的强有力方式。
1.1 模板函数(Template Functions)
我们从一个最佳实践开始:可以通过调用模板指令中的 quote函数 把 .Values对象中的字符串属性用引号引起来,然后放到模板中。
- 模板函数的语法是
functionName arg1 arg2...
。
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
drink: {{ quote .Values.favorite.drink }}
food: {{ quote .Values.favorite.food }}
在上面的代码片段中,quote .Values.favorite.drink
调用了quote函数
并传递了一个参数.Values.favorite.drink
。
1.2 管道(Pipelines)
模板语言中有一个强大的功能: 管道。借鉴UNIX中的概念,管道是将一系列的模板语言紧凑地链接在一起,进行流式处理结果合并的工具。换句话说,管道符是按顺序完成一系列任务的有效方式。现在用管道符重写上述示例:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
drink: {{ .Values.favorite.drink | quote }}
food: {{ .Values.favorite.food | quote }}
在这个示例中,并不是调用 quote 函数
,而是倒置了命令。使用管道符 |
将参数“发送”给函数: .Values.favorite.drink | quote
。使用管道符可以将很多函数链接在一起,按顺序执行:
- 倒置命令是模板中的常见做法。可以经常看到
.val | quote
而不是quote .val
。实际上两种操作都是可以的。
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
drink: {{ .Values.favorite.drink | quote }}
food: {{ .Values.favorite.food | upper | quote }}
上述模板会生成以下内容:
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: trendsetting-p-configmap
data:
myvalue: "Hello World"
drink: "coffee"
food: "PIZZA"
- 注意:原有的pizza现在已经被转换成了"PIZZA"。当使用管道操作的时候,前面的操作结果会作为参数传递给后面的模板函数,如(.Values.favorite.drink | upper 的结果) 作为了quote的最后一个参数。
我们希望将上面模板中的 drink
的值渲染为重复出现3次的字符串,则我们就可以使用到 Sprig 模板库提供的 repeat函数
,不过该函数需要传入一个参数repeat COUNT STRING
表示重复的次数:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
drink: {{ .Values.favorite.drink | repeat 3 | quote }}
food: {{ .Values.favorite.food | upper | quote }}
该repeat函数会将给定的字符串重复3次返回,所以我们将得到以下输出:
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: melting-porcup-configmap
data:
myvalue: "Hello World"
drink: "coffeecoffeecoffee"
food: "PIZZA"
注意:函数的顺序是很重要的,把上面例子的 drink
部分改一下:
drink: {{ .Values.favorite.drink | quote | repeat 3 }}
则输出结果就变为把drink的字符串值重复输出了3次,输出结果如下:
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: melting-porcup-configmap
data:
myvalue: "Hello World"
drink: "coffee""coffee""coffee"
food: "PIZZA"
2、常用模板函数介绍
2.1 quote 和 squote函数
在编写模板文件的时候,有时候需要将模板中引用内置对象的部分使用引号括起来,这样可以便于模板处理这些数据并正确地传递给 Kubernets。我们可以使用 quote 函数
。如果要使用单引号,则使用 squote 函数
。
- 这2个函数是将字符串用双引号(quote) 或者单引号,则使用(squote)括起来。
# 使用双引号
drink: {{ .Values.favorite.drink | quote }}
# 使用单引号
drink: {{ .Values.favorite.drink | squote }}
2.2 default函数
模板中频繁使用的一个函数是default: default DEFAULT_VALUE GIVEN_VALUE。 这个函数允许你在模板中指定一个默认值,以防这个值被忽略。
修改上面的示例, ConfigMap 的模板中 drink
添加默认值:(templates/configmap.yaml)
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
drink: {{ .Values.favorite.drink | default "tea" | quote }}
food: {{ .Values.favorite.food | upper | quote }}
这时候如果运行,drink
的值为 coffee
。
现在,从 values.yaml 中移除 drink
的设置:
favorite:
#drink: coffee
food: pizza
现在重新运行 helm install --dry-run --debug fair-worm ./mychart
会生成如下内容,可以看到 drink
的值变为了默认值 tea
:
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: fair-worm-configmap
data:
myvalue: "Hello World"
drink: "tea"
food: "PIZZA"
在实际的chart中,所有的静态默认值都应该设置在 values.yaml 文件中,且不应该重复使用 default 命令 (否则会出现冗余)。
default 命令很适合计算值,这些值不能声明在values.yaml文件中,比如:
drink: {{ .Values.favorite.drink | default (printf "%s-tea" (include "fullname" .)) }}
- 有些场景中,if条件比default更加适合。
2.3 lookup函数
lookup 函数可以用于在运行的集群中查找资源。lookup函数简述为查找 apiVersion, kind, namespace,name -> 资源或者资源列表。
- 当对象未找到时,会返回空值。可以用来检测对象是否存在。
- lookup函数使用Helm已有的Kubernetes连接配置查询Kubernetes。当与调用API服务交互时返回了错误 (比如缺少资源访问的权限),helm 的模板操作会失败。
parameter | type | 必填 |
---|---|---|
apiVersion | string | 必填 |
kind | string | 必填 |
namespace | string | 选填 |
name | string | 选填 |
- name 和 namespace 都是选填的,且可以传空字符串(“”)作为空。
以下是可能的参数组合:
命令 | Lookup 函数 |
---|---|
kubectl get pod mypod -n mynamespace | lookup “v1” “Pod” “mynamespace” “mypod” |
kubectl get pods -n mynamespace | lookup “v1” “Pod” “mynamespace” “” |
kubectl get pods --all-namespaces | lookup “v1” “Pod” “” “” |
kubectl get namespace mynamespace | lookup “v1” “Namespace” “” “mynamespace” |
kubectl get namespaces | lookup “v1” “Namespace” “” “” |
当lookup返回一个对象,可以得到一个字典。这个字典可以进一步被引导以获取特定值。
下面的例子将返回mynamespace对象的annotations属性:
(lookup "v1" "Namespace" "" "mynamespace").metadata.annotations
当lookup返回一个对象列表时,可以通过items字段访问对象列表:
{{ range $index, $service := (lookup "v1" "Service" "mynamespace" "").items }}
{{/* do something with each service */}}
{{ end }}
请记住,
Helm在helm template
或者helm install|update|delete|rollback --dry-run
时, 不会请求Kubernetes API服务。因此在这种情况下,lookup函数会返回空列表。
2.4 运算符也是函数
对于模板来说,运算符(eq, ne, lt, gt, and, or等等) 都是作为函数来实现的。 在管道符中,操作可以按照圆括号分组。
1)and
返回两个参数的and布尔值。
and .Arg1 .Arg2
2)or
返回两个参数的or布尔值。会返回第一个非空参数或最后一个参数。
or .Arg1 .Arg2
3)not
返回参数的布尔求反。
not .Arg
4)eq
返回参数的布尔等式(比如, Arg1 == Arg2)。
eq .Arg1 .Arg2
5)ne
返回参数的布尔非等式(比如 Arg1 != Arg2)。
ne .Arg1 .Arg2
6)lt
如果第一参数小于第二参数,返回布尔真。否则返回假(比如, Arg1 < Arg2)。
lt .Arg1 .Arg2
7)le
如果第一参数小于等于第二参数,返回布尔真,否则返回假(比如, Arg1 <= Arg2)。
le .Arg1 .Arg2
8)gt
如果第一参数大于第二参数,返回布尔真,否则返回假(比如, Arg1 > Arg2)。
gt .Arg1 .Arg2
9)ge
如果第一参数大于等于第二参数,返回布尔真,否则返回假。(比如, Arg1 >= Arg2)。
ge .Arg1 .Arg2
评论区