模板函数和管道

到目前为止,我们已经了解了如何将信息放置到模板中。但是这些信息在放置到模板中时未经修改。有时我们希望以更便于我们使用的方式转换提供的数据。

让我们从最佳实践开始:当从 .Values 对象中注入字符串到模板时,我们应该对这些字符串进行引用。我们可以通过在模板指令中调用 quote 函数来做到这一点

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

模板函数遵循语法 functionName arg1 arg2...。在上面的代码段中,quote .Values.favorite.drink 调用了 quote 函数并将一个参数传递给它。

Helm 提供了超过 60 个可用的函数。其中一些是由 Go 模板语言 本身定义的。大多数其他函数都是 Sprig 模板库 的一部分。我们将在后面的示例中看到其中的许多函数。

虽然我们谈论的是“Helm 模板语言”,就好像它是 Helm 特定的,但实际上它结合了 Go 模板语言、一些额外的函数以及各种包装器来将某些对象暴露给模板。在学习模板时,Go 模板的许多资源可能会有所帮助。

管道

模板语言的一项强大功能是它的管道概念。借鉴了 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 ARGUMENT,而是反转了顺序。我们使用管道 (|) 将参数“发送”到函数:.Values.favorite.drink | quote。使用管道,我们可以将多个函数链接在一起

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

反转顺序是模板中的一种常见做法。您将更多地看到 .val | quote 而不是 quote .val。这两种做法都没有问题。

评估时,该模板将生成以下内容

# 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) 将作为最后一个参数传递给函数。我们可以修改上面的饮料示例,以使用一个接受两个参数的函数来进行说明:repeat COUNT STRING

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 }}

repeat 函数将根据给定的次数回显给定的字符串,因此我们将获得以下输出

# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: melting-porcup-configmap
data:
  myvalue: "Hello World"
  drink: "coffeecoffeecoffeecoffeecoffee"
  food: "PIZZA"

使用 default 函数

模板中经常使用的函数之一是 default 函数:default DEFAULT_VALUE GIVEN_VALUE。此函数允许您在模板中指定一个默认值,以防值被省略。让我们使用它来修改上面的饮料示例

drink: {{ .Values.favorite.drink | default "tea" | quote }}

如果我们像往常一样运行它,我们将获得我们的 coffee

# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: virtuous-mink-configmap
data:
  myvalue: "Hello World"
  drink: "coffee"
  food: "PIZZA"

现在,我们将从 values.yaml 中删除最喜欢的饮料设置

favorite:
  #drink: coffee
  food: pizza

现在重新运行 helm install --dry-run --debug fair-worm ./mychart 将生成以下 YAML

# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: fair-worm-configmap
data:
  myvalue: "Hello World"
  drink: "tea"
  food: "PIZZA"

在一个实际的图表中,所有静态默认值都应该放在 values.yaml 中,并且不应使用 default 命令重复(否则它们将是冗余的)。但是,default 命令非常适合计算值,这些值无法在 values.yaml 中声明。例如

drink: {{ .Values.favorite.drink | default (printf "%s-tea" (include "fullname" .)) }}

在某些地方,if 条件保护可能比 default 更合适。我们将在下一节中看到这些内容。

模板函数和管道是转换信息并将其插入 YAML 的强大方法。但有时有必要添加一些比仅仅插入字符串更复杂的模板逻辑。在下一节中,我们将了解模板语言提供的控制结构。

使用 lookup 函数

lookup 函数可用于查找正在运行的集群中的资源。lookup 函数的概要是 lookup apiVersion, kind, namespace, name -> resource or resource list

参数类型
apiVersion字符串
kind字符串
命名空间字符串
名称字符串

namenamespace 都是可选的,可以作为空字符串 ("") 传递。

以下是可能的参数组合

行为查找函数
kubectl get pod mypod -n mynamespacelookup "v1" "Pod" "mynamespace" "mypod"
kubectl get pods -n mynamespacelookup "v1" "Pod" "mynamespace" ""
kubectl get pods --all-namespaceslookup "v1" "Pod" "" ""
kubectl get namespace mynamespacelookup "v1" "Namespace" "" "mynamespace"
kubectl get namespaceslookup "v1" "Namespace" "" ""

lookup 返回一个对象时,它将返回一个字典。可以进一步导航此字典以提取特定值。

以下示例将返回 mynamespace 对象的注释

(lookup "v1" "Namespace" "" "mynamespace").metadata.annotations

lookup 返回一个对象列表时,可以通过 items 字段访问对象列表

{{ range $index, $service := (lookup "v1" "Service" "mynamespace" "").items }}
    {{/* do something with each service */}}
{{ end }}

如果没有找到对象,则返回空值。这可以用于检查对象是否存在。

lookup 函数使用 Helm 的现有 Kubernetes 连接配置来查询 Kubernetes。如果在与调用 API 服务器交互时返回任何错误(例如由于缺乏访问资源的权限),Helm 的模板处理将失败。

请记住,Helm 不应该在 helm template|install|upgrade|delete|rollback --dry-run 操作期间联系 Kubernetes API 服务器。要测试针对正在运行的集群的 lookup,应改为使用 helm template|install|upgrade|delete|rollback --dry-run=server 以允许集群连接。

运算符是函数

对于模板,运算符 (eqneltgtandor 等) 都是作为函数实现的。在管道中,可以使用括号 (()) 对操作进行分组。

现在,我们可以从函数和管道转向使用条件、循环和作用域修饰符进行流程控制。