文章目录

  • 模板
  • 1. 概述
  • 2. 结构
  • 3. 定义模板的名称
  • 4. 格式化模板
  • 5. 注释
  • values 管道与函数
  • 1. values
  • 2. 管道符
  • 3. 函数
  • 4. 函数列表
  • default
  • empty
  • fail
  • coalesce
  • ternary


模板

1. 概述

Helm 最核心的就是模板,即模板化的 K8S manifests 文件。
他本质上就是一个 Go 的 template 模板HelmGo template 模板的基础上,还会增加很多东西。如一些自定义的元数据信息,扩展的库以及一些类似于变成形式的工作流,例如**条件语句管道**等等。这些东西都会使得我们的模板变得更加丰富。

2. 结构

templates/目录结构应该如下:

  • 如果生成 YAML 输出,模板文件应该有扩展名 .yaml。 扩展名是 .tpl 可用于生成非格式化内容的模板文件。
  • 模板文件名称应该使用横杠符号( my-example-configmap.yaml ),不用驼峰记法。
  • 每个资源的定义应该在它自己的模板文件中。
  • 模板文件的名称应该反映名称中的资源类型。比如:foo-pod.yaml, bar-svc.yaml

3. 定义模板的名称

定义的模板(在{{ define }}命令中定义的模板)是可全局访问的。这就意味着 chart 和所有的子 chart 都可以访问用{{ define }}创建的所有模板。

因此, 所有定义的模板名称应该被命名空间化。

  • 正确的:
{{- define "nginx.fullname" }}
{{/* ... */}}
{{ end -}}
  • 不正确的:
{{- define "fullname" -}}
{{/* ... */}}
{{ end -}}

说明: 强烈建议通过 helm create 命令创建新 chart,因为模板名称是根据此最佳实践自动定义的。

4. 格式化模板

模板应该使用两个 空格 缩进(永远不要用tab)。

模板命令的大括号前后应该使用空格:

  • 正确的:
{{ .foo }}
{{ print "foo" }}
{{- print "bar" -}}
  • 不正确的:
{{.foo}}
{{print "foo"}}
{{-print "bar"-}}

5. 注释

  • YAML 注释
# This is a comment
type: sprocket
  • 模板注释
{{- /*
This is a comment.
*/}}
type: frobnitz

values 管道与函数

1. values

  • 命名规范
    变量名称以小写字母开头,单词按驼峰区分。
# example.yaml

chicken: true
chickenNoodleSoup: true

说明: 所有的 Helm 内置变量以大写字母开头,以便与用户定义的 value 进行区分:.Release.Name.Capabilities.KubeVersion

  • 扁平或嵌套的 Value
    YAML是一种灵活格式,值可以嵌套得很深,也可以是扁平的。

      嵌套的:

server:
  name: nginx
  port: 80

      扁平的:

serverName: nginx
serverPort: 80



  • 类型
    YAML的类型强制规则有时候是很反常的。比如,foo: falsefoo: “false” 是不一样的。大整型数如:foo: 12345678 有时会被转换成科学计数法。
    避免类型强制规则错误最简单的方式是字符串明确定义,其他都是不明确的。或者,简单来讲, 给所有字符串打引号。
    通常,为了避免整数转换问题,将整型存储为字符串更好,并用 {{ int $value }} 在模板中将字符串转回整型。
    在大多数场景中,显示的类型标记更好,所以 foo: !!string 1234 会将 1234 作为字符串对待。 但是,YAML 解析器会消耗标记,因此类型数据在一次解析后会丢失。
  • 潜在的value来源:
  1. chart 的 values.yaml 文件
  2. helm install -fhelm upgrade -f 提供的 values 文件
  3. 在执行 helm installhelm upgrade 时传递给 --set--set-string 参数的 values

说明: 当设计 values 的结构时,记得你的 chart 用户可能会通过 -f 参数或 --set

2. 管道符

模板语言其中一个强大功能是 管道 概念。借鉴UNIX的概念,管道符是将一系列的 模板语言紧凑地表示为一系列转换的工具。换句话说,管道符是按顺序完成一系列任务的有效方式。

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

使用管道符 ( | ) 将参数 “发送” 给函数: .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。两种操作都是可以的。

3. 函数

  • 使用 default 函数
    模板中频繁是有的一个函数是 default: default DEFAULT_VALUE GIVEN_VALUE。 这个函数允许你在模板中指定一个默认值,以防这个值被忽略。现在使用它修改上述示例:
drink: {{ .Values.favorite.drink | default "tea" | quote }}

说明: 在实际的 chart 中,所有的静态默认值应该设置在 values.yaml 文件中,且不应该重复使用 default 命令 (否则会出现冗余)。有些场景,if 条件保护比 default 更加适合

  • 使用 lookup 函数
    lookup 函数可以用于在运行的集群中 查找 资源。lookup 函数简述为 查找 apiVersion, kind, namespace, name -> 资源或者资源列表
# 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 对象的注释:
(lookup "v1" "Namespace" "" "mynamespace").metadata.annotations

4. 函数列表

Helm 包括了需要逻辑和流控制函数,包括 and, coalesce, default, empty, eq, fail, ge, gt, le, lt, ne, not, or

模板函数列表

function

command

instructions

and

and .Arg1 .Arg2

返回两个参数的and布尔值

or

or .Arg1 .Arg2

返回两个参数的or布尔值。会返回第一个非空参数或最后一个参数

not

not .Arg

返回参数的布尔求反

eq

eq .Arg1 .Arg2

返回参数的布尔等式(比如, Arg1 == Arg2)

ne

ne .Arg1 .Arg2

返回参数的布尔非等式(比如 Arg1 != Arg2)

lt

lt .Arg1 .Arg2

如果第一参数小于第二参数,返回布尔真。否则返回假(比如, Arg1 < Arg2)

le

le .Arg1 .Arg2

如果第一参数小于等于第二参数,返回布尔真,否则返回假(比如, Arg1 <= Arg2)

gt

gt.Arg1 .Arg2

如果第一参数大于第二参数,返回布尔真,否则返回假(比如, Arg1 > Arg2)

ge

ge .Arg1 .Arg2

如果第一参数大于等于第二参数,返回布尔真,否则返回假。(比如, Arg1 >= Arg2)

default

使用 default 设置一个简单的默认值

default "foo" .Bar

说明: 如果.Bar是非空值,则使用它,否则会返回foo, “空” 定义取决于以下类型

  • 整型: 0
  • 字符串: ""
  • 列表: []
  • 字典: {}
  • 布尔: false
  • 以及所有的nil (或 null)

empty

如果给定的值被认为是空的,则empty函数返回true,否则返回false。空值列举在default部分

empty .Foo

说明: 在Go模板条件中,空值是为你计算出来的。这样你很少需要 if empty .Foo ,仅使用 if .Foo 即可

fail

无条件地返回带有指定文本的空 string 或者 error。这在其他条件已经确定而模板渲染应该失败的情况下很有用

fail "Please accept the end user license agreement"

coalesce

coalesce 函数获取一个列表并返回第一个非空值; 此函数用于扫描多个变量或值:

coalesce .name .parent.name "Matt"

说明: 上述示例会优先检查 .name 是否为空。如果不是,就返回值。如果 是 空, 继续检查.parent.name。 最终,如果 .name.parent.name 都是空,就会返回 Matt

ternary

ternary 函数获取两个值和一个test值。如果test值是true,则返回第一个值。如果test值是空,则返回第二个值。 这和cternary运算符类似

  • true test value

ternary "foo" "bar" true        或者
true | ternary "foo" "bar"

      上述返回 "foo"

  • false test value

ternary "foo" "bar" false        或者
false | ternary "foo" "bar"

      上述返回 "bar"