kubernetes之helm语法

2024-12-04 15:46   湖南  

案例

https://blog.51cto.com/cuiyingfeng/4371622

https://xie.infoq.cn/article/f25c42010b41fa78e2d929aba

https://docs.koderover.com/zadig/v1.13.0/bestpractice/

安装

#解压后加入环境变量或者执行文件放到/usr/local/bin/下
https://github.com/helm/helm/releases
helm version
#添加repo仓库
helm repo add stable http://mirror.azure.cn/kubernetes/charts/
helm repo list
#查询
helm search repo stable
#仓库中将可用的 charts 信息同步到本地,可以确保我们获取到最新的 charts 列表
helm repo update
helm install stable/mysql --generate-name
helm show chart stable/mysql
helm show all stable/mysql
helm ls
helm uninstall mysql-1575619811
helm uninstall mysql-1575619811 --keep-history

charts

wordpress/
Chart.yaml # 包含当前 chart 信息的 YAML 文件
LICENSE # 可选:包含 chart 的 license 的文本文件
README.md # 可选:一个可读性高的 README 文件
values.yaml # 当前 chart 的默认配置 values
values.schema.json # 可选: 一个作用在 values.yaml 文件上的 JSON 模式
charts/ # 包含该 chart 依赖的所有 chart 的目录
crds/ # Custom Resource Definitions
templates/ # 模板目录,与 values 结合使用时,将渲染生成 Kubernetes 资源清单文件
templates/NOTES.txt # 可选: 包含简短使用使用的文本文件

Chart.yaml 文件

对于一个 chart 包来说 Chart.yaml 文件是必须的,它包含下面的这些字段:

apiVersion: chart API 版本 (必须)
name: chart 名 (必须)
version: SemVer 2版本 (必须)
kubeVersion: 兼容的 Kubernetes 版本 (可选)
description: 一句话描述 (可选)
type: chart 类型 (可选)
keywords:
- 当前项目关键字集合 (可选)
home: 当前项目的 URL (可选)
sources:
- 当前项目源码 URL (可选)
dependencies: # chart 依赖列表 (可选)
- name: chart 名称 (nginx)
version: chart 版本 ("1.2.3")
repository: 仓库地址 ("https://example.com/charts")
maintainers: # (可选)
- name: 维护者名字 (对每个 maintainer 是必须的)
email: 维护者的 email (可选)
url: 维护者 URL (可选)
icon: chart 的 SVG 或者 PNG 图标 URL (可选).
appVersion: 包含的应用程序版本 (可选). 不需要 SemVer 版本
deprecated: chart 是否已被弃用 (可选, boolean)

使用 Helm 管理 Charts

helm create mychart
helm package mychart
helm lint mychart

helm repo add traefik https://helm.traefik.io/traefik
helm repo list
helm fetch traefik/traefik

#修改配置以后渲染到yaml文件中检查
helm template --namespace kube-system traefik ./traefik > traefik.yaml

#开发时模拟安装
helm install --generate-name --dry-run --debug ./mychart/
helm install --generate-name --dry-run --debug --set favoriteDrink=water ./mychart/

函数

Helm 有60多种可用的函数,其中一些是由 Go 模板语言本身定义的,其他大多数都是 Sprig 模板库提供的
https://pkg.go.dev/text/template
https://masterminds.github.io/sprig/

quote 就是个模板函数
模板函数的语法规则是 functionName arg1 arg2 ...

函数
quote:给参数加上""号
|:管道符(过滤)arg1 arg2 | functionName
upper lower:大小写转换
repeat 5:重复5次
default:默认值

{{- 删除左边的空格
-}}删除右边的空格
indent 2 空2格

运算符、流程控制

eq、ne、lt小于、gt 大于、and、or

控制语句

  • if/else 条件语句

  • with 指定一个作用域范围

  • range 提供类似于 for each 这样的循环样式

还提供了一些声明和使用命名模板的操作:

  • define 在模板内部声明一个新的命名模板

  • template 导入一个命名模板

  • block 声明了一种特殊的可填充模板区域

if/else 语句
{{ if PIPELINE }}
# Do something
{{ else if OTHER PIPELINE }}
# Do something else
{{ else }}
# Default case
{{ end }}

布尔 false、数字零、一个空字符串、nil(empty 或者 null)、一个空集合(map、slice、tuple、dict、array),都会将管道判断为 false

with 语句
with后面接范围,后面的可以用.来控制范围
{{ with PIPELINE }}
# 限制范围
{{ end }}

range 循环操作
pizzaToppings:
- mushrooms
- cheese
- peppers
- onions

toppings: |-
{{- range .Values.pizzaToppings }}
- {{ . | title | quote }}
{{- end }}

在模板中快速创建一个列表,然后遍历该列表很有用,Helm 模板具有简化该功能的函数:tuple。元组是固定大小的列表集合,但是具有任意数据类型,下面是元组的大概使用方法:
sizes: |-
{{- range tuple "small" "medium" "large" }}
- {{ . }}
{{- end }}
结果:
sizes: |-
- small
- medium
- large

变量

声明变量$relname , := 赋值
{{- $relname := .Release.Name -}}

使用变量$relname
{{- with .Values.favorite }}
drink: {{ .drink | default "tea" | quote }}
food: {{ .food | upper | quote }}
release: {{ $relname }}
{{- end }}

range 循环中使用
$index获取下标
$topping := 获取值
toppings: |-
{{- range $index, $topping := .Values.pizzaToppings }}
{{ $index }}: {{ $topping }}
{{- end }}

获取key/value
{{- range $key, $val := .Values.favorite }}
{{ $key }}: {{ $val | quote }}
{{- end }}

$.是直接获取全局变量, 直接用.要注意作用域,with和循环中

命名模板

define 关键字可以让我们在模板文件中创建命名模板
{{- define "mychart.labels" }}
labels:
generator: helm
date: {{ now | htmlDate }}
{{- end }}

调用
{{- template "mychart.labels" }}

一般来说,Helm 中约定将这些模板统一放到一个 partials 文件中,通常就是 _helpers.tpl 文件
{{/* 生成基本的 Label 标签 */}}
{{- define "mychart.labels" }}
labels:
generator: helm
date: {{ now | htmlDate }}
chart: {{ .Chart.Name }}
version: {{ .Chart.Version }}
{{- end }}

用template调用的模板含有变量,需要在后面加上 . ,表示作用域是全局
{{- template "mychart.labels" . }}


include 函数
{{- define "mychart.app" -}}
app_name: {{ .Chart.Name }}
app_version: "{{ .Chart.Version }}"
{{- end -}}

因为 template 只是一个动作,而不是一个函数,所以无法将模板调用的输出传递给其他函数,只是内联插入
Helm 提供了代替 template 的函数 include,可以将模板的内容导入到当前的管道中,这样就可以在管道中传递给其他函数进行处理了
{{ include "mychart.app" . | indent 2 }}

在 Helm 模板中最好使用 include 而不是 template,这样可以更好地处理 YAML 文档的输出格式。

访问文件

  • 可以在 Helm chart 中添加额外的文件,这些文件也会被打包,不过需要注意,由于 Kubernetes 对象的存储限制,Charts 必须小于 1M

  • 由于一些安全原因,通过 .Files 对象无法访问某些文件(无法访问 templates/ 下面的文件、无法访问使用 .helmignore 排除的文件)

  • Chart 不会保留 UNIX 模式的信息,所以,当使用 .Files 对象时,文件级别的权限不会对文件的可用性产生影响。

config1.toml:
message = Hello from config 1

config2.toml:
message = This is config 2

config3.toml:
message = Goodbye from config 3

apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
{{- $files := .Files }}
{{- range tuple "config1.toml" "config2.toml" "config3.toml" }}
{{ . }}: |-
{{ $files.Get . }}
{{- end }}


# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mychart-1576046462-configmap
data:
config1.toml: |-
message = Hello from config 1

config2.toml: |-
message = This is config 2

config3.toml: |-
message = Goodbye from config 3

Glob 模式

随着 chart 的增长,你可能需要更多地组织文件,因此 Helm 提供了 Files.Glob 的方法来帮助我们获取具有 glob 模式的文件。

.Glob 返回 Files 类型,所以你可以在返回的对象上调用任何 Files 方法。比如,我们的文件目录结构如下所示:

foo/:
foo.txt foo.yaml

bar/:
bar.go bar.conf baz.yaml

{{ range $path := .Files.Glob "**.yaml" }}
{{ $path }}: |
{{ .Files.Get $path }}
{{ end }}

ConfigMap 和 Secrets

想要将文件内容同时放入 ConfigMap 和 Secrets 中,以便在运行时安装到 Pod 中,这种需求很常见,为了解决这个问题,Helm 在 Files 类型上添加了一个实用的方法。

apiVersion: v1
kind: ConfigMap
metadata:
name: conf
data:
{{ (.Files.Glob "foo/*").AsConfig | indent 2 }}
---
apiVersion: v1
kind: Secret
metadata:
name: very-secret
type: Opaque
data:
{{ (.Files.Glob "bar/*").AsSecrets | indent 2 }}

编码

apiVersion: v1
kind: Secret
metadata:
name: {{ .Release.Name }}-secret
type: Opaque
data:
token: |-
{{ .Files.Get "config1.toml" | b64enc }}

上面将采用我们上面的 config1.toml 文件并对其内容进行 base64 编码,渲染会得到如下所示的结果:
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: Secret
metadata:
name: mychart-1576048287-secret
type: Opaque
data:
token: |-
bWVzc2FnZSA9IEhlbGxvIGZyb20gY29uZmlnIDEK

Lines

有时,需要访问模板中文件的每一行内容,Helm 也提供了方法的 Lines 方法,我们可以使用 range 函数遍历每行内容:

data:
some-file.txt: {{ range .Files.Lines "foo/bar.txt" }}
{{ . }}{{ end }}

创建子chart

$ cd mychart/charts
$ helm create mysubchart
Creating mysubchart
$ rm -rf mysubchart/templates/*.*

添加 values 和 模板

dessert: cake

apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-cfgmap2
data:
dessert: {{ .Values.dessert }}

从父 chart 覆盖 values

favorite:
drink: coffee
food: pizza
pizzaToppings:
- mushrooms
- cheese
- peppers
- onions

mysubchart:
dessert: ice cream

最后两行,mysubchart 部分中的所有指令都回被发送到 mysubchart 子 chart 中,所以,如果我们现在渲染模板,我们可以看到 mysubchart 的 ConfigMap 会被渲染成如下的内容:

# Source: mychart/charts/mysubchart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mychart-1576051914-cfgmap2
data:
dessert: ice cream

全局值

favorite:
drink: coffee
food: pizza
pizzaToppings:
- mushrooms
- cheese
- peppers
- onions

mysubchart:
dessert: ice cream

global:
salad: caesar

由于全局值的原因,在 mychart/templates/configmap.yaml 和 mysubchart/templates/configmap.yaml 下面都应该可以以 {{ .Values.global.salad }} 的形式来访问这个值。
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
salad: {{ .Values.global.salad }}

共享模板

父级 chart 和子 chart 可以共享模板,任何 chart 中已定义的块都可以用于其他 chart。比如,我们可以定义一个简单的模板,如下所示:

{{- define "labels" }}from: mychart{{ end }}

{{ include $mytemplate }}

Chart Hooks

Helm 也提供了一种 Hook 机制,可以允许 chart 开发人员在 release 生命周期的某些时间点进行干预。比如,可以使用 hook 来进行下面的操作:

  • 在加载任何 charts 之前,在安装的时候加载 ConfigMap 或者 Secret

  • 在安装新的 chart 之前,执行一个 Job 来备份数据库,然后在升级后执行第二个 Job 还原数据

  • 在删除 release 之前运行一个 JOb,以在删除 release 之前适当地取消相关服务

Hooks

  • 预安装pre-install:在模板渲染后,kubernetes 创建任何资源之前执行

  • 安装后post-install:在所有 kubernetes 资源安装到集群后执行

  • 预删除pre-delete:在从 kubernetes 删除任何资源之前执行删除请求

  • 删除后post-delete:删除所有 release 的资源后执行

  • 升级前pre-upgrade:在模板渲染后,但在任何资源升级之前执行

  • 升级后post-upgrade:在所有资源升级后执行

  • 预回滚pre-rollback:在模板渲染后,在任何资源回滚之前执行

  • 回滚后post-rollback:在修改所有资源后执行回滚请求

  • 测试test:在调用 Helm test 子命令的时候执行(可以查看测试文档





博闻简书
以简驭繁,书写博闻
 最新文章