上两节我们了解了模板函数和管道,但是有的场景需要添加一些判断逻辑,这些逻辑比仅仅插入字符串要复杂得多。
下面我们将来了解模板语言中提供的控制流程。
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 resourcesorg: orgLabelorg: 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 }}
执行测试:
