上两节我们了解了模板函数
和管道
,但是有的场景需要添加一些判断逻辑,这些逻辑比仅仅插入字符串要复杂得多。
下面我们将来了解模板语言中提供的控制流程。
Helm 的模板语言提供了以下一些流程控制,为模板作者提供了多样的功能:
if/else
:条件语句with
:指定一个作用域范围range
:提供类似于 for each
这样的循环样式if/else
条件判断的基本结构如下所示:
{{ if PIPELINE }}
# Do something
{{ else if OTHER PIPELINE }}
# Do something else
{{ else }}
# Default case
{{ end }}
可以看到我们这里判断的是管道而不是一个 values 值。如果值为以下的一些内容,则将管道判断为 false:
在其他条件下,条件都为真。
创建新的chart conditional-learn
:
kongpingfan:~/environment/helm $ helm create conditional-learn
Creating conditional-learn
kongpingfan:~/environment/helm $ cd conditional-learn/
将template目录下除service.yaml
外所有文件都删除,删除后的目录结构如下:
kongpingfan:~/environment/helm/conditional-learn $ tree
.
├── charts
├── Chart.yaml
├── templates
│ └── service.yaml
└── values.yaml
修改values.yaml
的内容:
replicaCount: 2
image: nginx
orgLabel: payroll
templates/service.yaml
内容:
apiVersion: v1
kind: Service
metadata:
name: nginx
{{ if .Values.orgLabel }}
labels:
org: {{ .Values.orgLabel }}
{{ end }}
spec:
ports:
- port: 80
name: http
selector:
app: hello-world
如果在values.yaml
中设置了orgLabel
字段,则生成的service yaml中包括这个字段:
如果在values.yaml
中没有设置orgLabel
字段,则生成的service yaml中不包含这个字段:
我们注意到,上面渲染生成的yaml中含有两个空行:
这是因为if
逻辑本身需要占用一行内容:
如果不想生成空行,则可以使用-
标记实现:
此时生成的yaml不会再有空行:
当我们在查看很多平台的helm代码时,经常会看到这种用法,例如 https://github.com/prometheus-community/helm-charts/blob/main/charts/prometheus/templates/server/cm.yaml :
if/else
条件判断的基本结构如下所示:
{{ if PIPELINE }}
# Do something
{{ else if OTHER PIPELINE }}
# Do something else
{{ else }}
# Default case
{{ end }}
else if
部分可以使用多种判断逻辑,例如eq, ne, gt, ge...
:
更新service.yaml
内容如下:
apiVersion: v1
kind: Service
metadata:
name: nginx
{{- if .Values.orgLabel }}
labels:
org: {{ .Values.orgLabel }}
{{- else if eq .Values.orgLabel "hr" }}
labels:
org: human resources
{{- else }}
labels:
org: no-org
{{- end }}
spec:
ports:
- port: 80
name: http
selector:
app: hello-world
现在的判断逻辑为:
org: human resources
org: orgLabel
org: no-org
执行测试:
if逻辑一个常用的功能是控制一个K8s对象是否生成。
把变量抽离到values.yaml中,create参数来进行整体的控制:
serviceAccount:
create: false
对变量进行判断,当为true时,则渲染出相应的yaml;当为false时,则不进行渲染。
service.yaml
:
{{- if .Values.serviceAccount.create }}
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
ports:
- port: 80
name: http
selector:
app: hello-world
{{- end }}
执行测试: