helm在希腊语中的意思是:舵;驾驶盘
Helm is the best way to find, share, and use software built for Kubernetes
Chart快速开始
三大概念:
1. Chart: 代表一个helm包, 里面会包含k8s上的资源定义。
2. repo: 远程仓库, 远端存储chart。 同时helm是支持本地存储chart的。
3. Release: release代表一个正在运行的k8s上的chart实例, 一个chart可以在集群上安装多次, 每次都会产生一个release
Helm运行流程
1. 从chart仓库中获取chart;
2. 使用者配置自己的values文件,根据自己的运行环境对values进行修改;
3. 默认values文件和使用者values文件会进行一个merge,形成最终的values文件;
4. 使用最终的values文件,渲染chart的template,形成可以被kubernetes执行的yaml;
5. 调用kube apply提交yaml到kubernetes
Chart相关知识点梳理
1. chart开发
2. chart hooks: 在部署流程中hook一部分操作, 改变install、rollback、upgrade、uninstall等的执行动作
3. chart test
4. library chart
5. chart校验
6. OCI
7. 保存chart: helm chart save
8. 登录repo: helm registry login repo_name
9. 高级特性:
a. post rendering:提供在helm install之前对manifest进行操作、配置的一种机制, kustomize使用
chart结构
1. Chart.yaml: chart的信息,包括chart的版本信息、描述信息、依赖关系,等
2. LICENSE: (可选)chart的LICENSE信息
3. README.md: (可选)chart的说明文件
4. values.yaml: chart的默认配置信息
5. values.schema.json: (可选) values配置信息的元信息(字段类型、字段描述、字段之间的依赖等),格式json
6. charts: 依赖的其他chart
7. crds: Custom Resource Definitions
8. templates: 部署模板,结合values.yaml会渲染出kubernetes yaml文件
9. templates/NOTES.txt: (可选)安装说明
Search
> search for charts
- helm search hub: 去hub上搜其他大佬贡献的chart
- helm search repo : 从已经添加的repo中, 搜本地chart
Install
> upload the chart to Kubernetes
1. helm install [NAME] [CHART] [flags] 可以使用 `—generate-name` 替换NAME
2. `helm status` 查看release状态, 页可以看到配置信息
其他命令
install/upgrade/rollback/uninstall/template 等
安装前的自定义操作
helm show values [chart name] 可以看chart都支持哪些配置项
—values或者-f制定的yaml文件可以传递多个, 位置越靠后, 优先级越大
—setset复写的配置会被持久化到config map中,同时可以使用helm get values <release-name>获取那些通过set设置进来的值,想清除通过set进来的值可以在运行helm upgrade 时带上--reset-values
Helm Chart Template
Charts结构
mychart/
Chart.yaml # 包含了chart的描述, 可以从模板中访问, charts木偶路可以包含其他的chart, 称之为子chart
values.yaml # 文件也会导入模板, 包含了chart的默认值
charts/ # 子chart存放目录
templates/ # 包含了模板文件, 当helm评估chart时, 会通过模板渲染引擎将所有文件存放templates目录中。然后收集结果发送给kubernetes
创建chart
helm create mychart
快速查看mychart/templates
NOTES.txt: chart的"帮助文本"。这会在你的用户执行helm install时展示给他们。
deployment.yaml: 创建Kubernetes工作负载的基本清单
service.yaml: 为你的工作负载创建一个service终端基本清单。
_helpers.tpl: 放置可以通过chart复用的模板辅助对象
第一个模板configMap
配置映射只是用于存储配置数据的对象。其他组件,比如pod,可以访问配置映射中的数据。
- helm install ym-test .
- helm get manifest ym-test # 查看清单
- kubectl get cm ym-test -oyaml # 查看具体configmap
- helm uninstall ym-test
添加一个简单的模板调用
通过插入发布名称来生成名称字段。
结果
configmap名字已经变成 ym-test-configmap
helm install —debug —dry-run test . 测试自己要安装的helm, 但是不会实际安装
小tips
1. 用作分割命名空间, 第一个.代表顶层命名空间。
2. Release为内置对象
3. --dry-run会让你变得更容易测试,但不能保证Kubernetes会接受你生成的模板。 最好不要仅仅因为--dry-run可以正常运行就觉得chart可以安装。
内置对象
对象可以通过模板引擎传递到模板中。 当然你的代码也可以传递对象。
Release:Release对象描述了版本发布本身。包含了以下对象:
Release.Name: release名称
Release.Namespace: 版本中包含的命名空间
Release.IsUpgrade: 如果当前操作是升级或回滚的话, true
Release.IsInstall: 如果当前操作是安装的话, true
Release.Revision: 此次修订的版本号. 安装是1, 升级和回滚都会自增
Release.Service: 该service用来渲染当前模板, helm里始终helm
Values:Values对象是从values.yaml文件和用户提供的文件传进模板的, 默认为空。
Chart:Chart.yaml文件内容, chart.yaml里的所有数据在这里都可访问, 具体属性见Chart指南
Files: 在chart中提供访问的所有非特殊文件的对象
你不能使用它访问Template对象,只能访问其他文件。 请查看这个文件访问部分了解更多信息
Files.Get通过文件名获取文件的方法。 (.Files.Getconfig.ini)
Files.GetBytes用字节数组代替字符串获取文件内容的方法。 对图片之类的文件很有用
Files.Glob用给定的shell glob模式匹配文件名返回文件列表的方法
Files.Lines逐行读取文件内容的方法。迭代文件中每一行时很有用
Files.AsSecrets使用Base 64编码字符串返回文件体的方法
Files.AsConfig使用YAML格式返回文件体的方法
Capabilities: 提供关于Kubernetes集群支持功能的信息
Capabilities.APIVersions是一个版本列表
Capabilities.APIVersions.Has $version说明集群中的版本 (比如,batch/v1) 或是资源 (比如,apps/v1/Deployment) 是否可用
Capabilities.KubeVersion和Capabilities.KubeVersion.Version是Kubernetes的版本号
Capabilities.KubeVersion.MajorKubernetes的主版本
Capabilities.KubeVersion.MinorKubernetes的次版本
Capabilities.HelmVersion包含Helm版本详细信息的对象,和helm version的输出一致
Capabilities.HelmVersion.Version是当前Helm语义格式的版本
Capabilities.HelmVersion.GitCommitHelm的git sha1值
Capabilities.HelmVersion.GitTreeState是Helm git树的状态
Capabilities.HelmVersion.GoVersion是使用的Go编译器版本
Template: 包含当前被执行的当前模板信息
Template.Name: 当前模板的命名空间文件路径 (e.g.mychart/templates/mytemplate.yaml)
Template.BasePath: 当前chart模板目录的路径 (e.g.mychart/templates)
小tips
1. 使用首字母小写将本地名称与内置对象区分开
Values文件
values对象内容来源
1. chart中的values.yaml
2. 如果是子chart, 就是父chart中的values.yaml文件
3. 使用-f参数传递到helm install 或 helm upgrade 的values文件
4. 使用 —set 传递的单个参数
优先级从低到高
实验举例
在configmap.yaml中新增drink: {{ .Values.favoriteDrink }}
1. helm install ym-test . —dry-run —debug
2. helm install solid-vulture ./mychart --dry-run --debug --set favoriteDrink=slurm
删除默认的key
如果需要从默认的value中删除key, 可以将key设置为null
1. helm install stable/drupal --set image=my-registry/drupal:0.1.0 --set livenessProbe.exec.command=[cat,docroot/CHANGELOG.txt] --set livenessProbe.httpGet=null
可以生成如下yaml
模板函数和流水线
我们希望以一种更有用的方式来转换所提供的数据。
quote 是一个函数, .Values.favorite.food 是一个参数
Helm中有超过60个可用的函数。 其中有些通过Go模板语言本身定义。其他大部分都是Sprig 模板库。我们可以在示例看到其中很多函数。
当我们讨论"Helm模板语言"时,感觉它是Helm专属的,实际上他是Go模板语言、一些额外的函数和用于 向模板暴露某些对象的装饰器组合而成的。很多Go模板的资料也有助于你学习模板。
管道符
管道符是按顺序完成一系列任务的方式
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。实际上两种操作都是可以的。
使用default函数
模板中频繁使用的一个函数是default:default DEFAULT_VALUE GIVEN_VALUE。 这个函数允许你在模板中指定一个默认值,以防这个值被忽略。
示例如下
drink: {{ .Values.favorite.drink | default "tea" | quote }}
静态默认值应该设置在values.yaml文件中,default命令很适合计算值, 例如
drink: {{ .Values.favorite.drink | default (printf "%s-tea" (include "fullname" .)) }}
这里**fullname**如何添加引用?
使用lookup函数、
lookup函数可以用于在运行的集群中查找资源。lookup函数简述为查找apiVersion, kind, namespace,name -> 资源或者资源列表。
parametertype
apiVersionstring
kindstring
namespacestring
namestring
lookup返回值接收
当lookup返回一个对象,它会返回一个字典。这个字典可以进一步被引导以获取特定值。
(lookup "v1" "Namespace" "" "mynamespace").metadata.annotations
当lookup返回一个对象列表时,可以通过items字段访问对象列表:
{{ range $index, $service := (lookup "v1" "Service" "mynamespace" "").items }}
{{/* do something with each service */}}
{{ end }}
当对象未找到时,会返回空值。可以用来检测对象是否存在。
Helm在helm template或者helm install|upgrade|delete|rollback --dry-run时 会返回空字典
运算符页是函数
对于模板来说,运算符(eq,ne,lt,gt,and,or等等) 都是作为函数来实现的。 在管道符中,操作可以按照圆括号分组。
模板函数列表
Helm 包含了很多可以在模板中利用的模板函数。以下列出了具体分类:
Logic and Flow Control重点, 里面包含 and/or/eq等逻辑判断
流控制
控制结构(在模板语言中称为"actions")提供给你和模板作者控制模板迭代流的能力。 Helm的模板语言提供了以下控制结构:
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 }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
drink: {{ .Values.favorite.drink | default "tea" | quote }}
food: {{ .Values.favorite.food | upper | quote }}
{{ if eq .Values.favorite.drink "coffee" }}mug: "true"{{ end }}
对比下面俩命令
helm install solid-vulture . --dry-run --debug
helm install solid-vulture . --dry-run --debug —set 'favorite.drink='
控制空格
要确保-和其他命令之间有一个空格。{{- 3 }}表示“删除左边空格并打印3”,而{{-3 }}表示“打印-3”。
最终,有时这更容易告诉模板系统如何缩进,而不是试图控制模板指令间的间距。因此,您有时会发现使用indent方法({{ indent 2 "mug:true" }})会很有用。
修改使用with的范围
.作用域会从全局变为with的作用域, 为了获取全局对象, 可以使用$从父作用域中访问Release.Name对象。当模板开始执行后$会被映射到根作用域,且执行过程中不会更改。 下面这种方式也可以正常工作
{{- with .Values.favorite }}
drink: {{ .drink | default "tea" | quote }}
food: {{ .food | upper | quote }}
release: {{ $.Release.Name }}
{{- end }}
使用range操作循环
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
{{- with .Values.favorite }}
drink: {{ .drink | default "tea" | quote }}
food: {{ .food | upper | quote }}
toppings: |-
{{- range $.Values.pizzaToppings }}
- {{ . | title | quote }}
{{- end }}
{{- end }}
正如例子中所示,|-标识在YAML中是指多行字符串。这在清单列表中嵌入大块数据是很有用的技术。 具体见Kubernetes ConfigMap 文档
有时能在模板中快速创建列表然后迭代
Helm模板的tuple可以很容易实现该功能
sizes: |-
{{- range tuple "small" "medium" "large" }}
- {{ . }}
{{- end }}
变量
解决作用域问题的一种方法是将对象分配给可以不考虑当前作用域而访问的变量。
变量是对另一个对象的命名引用。遵循$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 }}
变量在range循环中特别有用。可以用于类似列表的对象,以捕获索引和值:
toppings: |-
{{- range $index, $topping := .Values.pizzaToppings }}
{{ $index }}: {{ $topping }}
{{- end }}
对于数据结构有key和value,可以使用range获取key和value。比如,可以通过.Values.favorite进行循环:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
{{- range $key, $val := .Values.favorite }}
{{ $key }}: {{ $val | quote }}
{{- end }}
但有个变量一直是全局的$这个变量一直是指向根的上下文。当在一个范围内循环时会很有用,同时你要知道chart的版本名称。
命名模板
模板名称是全局的。如果您想声明两个相同名称的模板,哪个最后加载就使用哪个。 因为在子chart中的模板和顶层模板一起编译,命名时要注意chart特定名称。
创建方式:
在流控制部分, 我们介绍了三种声明和管理模板的方法:define,template,和block
特殊用途的include方法,类似于template操作
局部的和_文件
Helm的模板语言允许你创建命名的嵌入式模板, 这样就可以在其他位置按名称访问。
_helpers.tpl文件是模板局部的默认位置。
在编写模板细节之前,文件的命名惯例需要注意:
templates/中的大多数文件被视为包含Kubernetes清单
NOTES.txt是个例外
命名以下划线(_)开始的文件则假定没有包含清单内容。这些文件不会渲染为Kubernetes对象定义,但在其他chart模板中都可用。
用define和template声明和使用模板
{{- define "MY.NAME" }}
# body of template here
{{- end }}
{{- define "mychart.labels" }}
labels:
generator: helm
date: {{ now | htmlDate }}
{{- end }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
{{- template "mychart.labels" }}
data:
myvalue: "Hello World"
{{- range $key, $val := .Values.favorite }}
{{ $key }}: {{ $val | quote }}
{{- end }}
tips:
define 中的 mychart.labels 全局的, 因此可以在任意地方调用
define 不会有输出, 除非使用 template 调用它
一般helm chart讲这些模板防止在局部文件中, 一般是_helpers.tpl
按照惯例define方法会有个简单的文档块({{/* ... */}})来描述要做的事。
define最好使用{chart_name}.{labels}作为模板前缀
设置模板范围
{{/* Generate basic labels */}}
{{- define "mychart.labels" }}
labels:
generator: helm
date: {{ now | htmlDate }}
chart: {{ .Chart.Name }}
version: {{ .Chart.Version }}
{{- end }}
如果渲染这个,会因为.没有内容传入, 导致错误
要查看渲染了什么helm install --dry-run --disable-openapi-validation moldy-jaguar .
{- template "mychart.labels" }}没有内容传入,所以模板中无法用.访问任何内容。{{- template "mychart.labels" . }}即可解决,.可以是其他参数, .Values 等
helm install --dry-run --debug plinking-anaco .
include方法
相较于使用template,在helm中使用include被认为是更好的方式 只是为了更好地处理YAML文档的输出格式
在模板内部访问文件
Helm 提供了通过.Files对象访问文件的方法。不过,在我们使用模板示例之前,有些事情需要注意:
可以添加额外的文件到chart中。虽然这些文件会被绑定。但是要小心,由于Kubernetes对象的限制,Chart必须小于1M。
通常处于安全考虑,一些文件无法通过.Files对象访问:
无法访问templates/中的文件
无法访问使用.helmignore排除的文件
helm应用subchart之外的文件,包括父级中的,不能被访问的
Chart不能保留UNIX模式信息,因此当文件涉及到.Files对象时,文件级权限不会影响文件的可用性。
基础应用
{{$file := .Files }} # 获取文件句柄
{{$file.Get file_name }} 获取文件信息
路径帮助
帮助处理文件路径见模板函数-FilePath
全局模式
当你的chart不断变大时Files.Glob(pattern string)方法来使用全局模式的灵活性读取特定文件。
{{ range $path, $_ := .Files.Glob "**.yaml" }}
{{ $.Files.Get $path }}
{{ end }}
ConfigMap and Secrets utility functions
Files类型提供了很多使用方法
{{ (.Files.Glob "foo/*").AsConfig | indent 2 }}
{{ .Files.Get "config1.toml" | b64enc }}
lines, 直接支持遍历
data:
some-file.txt: {{ range .Files.Lines "foo/bar.txt" }}
{{ . }}{{ end }}
创建一个NOTES.txt文件
templates/NOTES.txt在helm install或helm upgrade命令的最后,高度自定义部分的信息。
参考文档
参考文档
helm Chart+configmap 使用 helm template具体生成需要看下
apiVersion: v1
kind: ConfigMap
metadata:
name: mychart-configmap
data:
myvalue: "Hello World"