云原生应用管理:原理与实践
上QQ阅读APP看书,第一时间看更新

2.10.5 变量

了解了函数、管道、对象、逻辑控制语句后,我们就可以转向学习一个编码中最常用的概念:变量。我们可以使用变量极大地简化编写模板流程,下面先展示一个错误的变量模板。


{{- with .Values.favorite }}
  drink: {{ .drink | default "tea" | quote }}
  food: {{ .food | upper | quote }}
  release: {{ .Release.Name }}
  {{- end }}

Release.Name在with语句的受限区域内,这个模板运行时就会报错。但是我们可以尝试在外部将Release.Name赋值给某个变量然后再引用。

在Helm中,变量也是一个对于对象的引用,它的格式为$name,赋值给某个变量的操作符是:=,下面我们重写这个模板。


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

请注意在with之前的$relname:=.Release.Name,我们将Release名称指定给一个变量,然后在下面使用这个变量,这样就能实现对于名称的引用,最终打印出来的结果如下所示。


apiVersion: v1
kind: ConfigMap
metadata:
  name: viable-badger-configmap
data:
  myvalue: "Hello World"
  drink: "coffee"
  food: "PIZZA"
  release: viable-badger

变量在循环时也是非常有用的,它能在循环的时候分别展示序号和具体的信息。


 toppings: |-
    {{- range $index, $topping := .Values.pizzaToppings }}
      {{ $index }}: {{ $topping }}
    {{- end }}

请注意循环的第一个参数赋值给了序号,第二个参数才是真正的值,这个模板最终输出的内容如下。


toppings: |-
      0: mushrooms
      1: cheese
      2: peppers
      3: onions

对于那些类似map的数据类型,我们就可以使用如下方式将它们打印出来。


apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  myvalue: "Hello World"
  {{- range $key, $val := .Values.favorite }}
  {{ $key }}: {{ $val | quote }}
  {{- end}}

这个favorite就是一个标准的键值对,它可以将对应的key-value打印出来。


apiVersion: v1
kind: ConfigMap
metadata:
  name: eager-rabbit-configmap
data:
  myvalue: "Hello World"
  drink: "coffee"
  food: "pizza"

变量只适用在它声明的地方,在其他一些地方我们还是需要使用全局变量,这里就有一个全局变量标识符$,这个标识符能在某些区域引用全局变量,下面以一个例子来看一下引用全局变量的效果。


{{- range .Values.tlsSecrets }}
apiVersion: v1
kind: Secret
metadata:
  name: {{ .name }}
  labels:
    # Many helm templates would use `.` below, but that will not work,
    # however `$` will work here
    app.Kubernetes.io/name: {{ template "fullname" $ }}
    # I cannot reference .Chart.Name, but I can do $.Chart.Name
    helm.sh/Chart: "{{ $.Chart.Name }}-{{ $.Chart.Version }}"
    app.Kubernetes.io/instance: "{{ $.Release.Name }}"
    # Value from appVersion in Chart.yaml
    app.Kubernetes.io/version: "{{ $.Chart.AppVersion }}"
    app.Kubernetes.io/managed-by: "{{ $.Release.Service }}"
type: Kubernetes.io/tls
data:
  tls.crt: {{ .certificate }}
  tls.key: {{ .key }}
---
{{- end }}

由于在range范围内,“.”被替代为当前的变量,如果想要使用全局的变量,可以这样书写$.Chart.Name。