Helm 介绍
工作需要批量部署同一套ToB(to business)服务到多个k8s cluster/namespace 上,经过几百根头发的研究,本文介绍Helm相关概念。
简介
Helm 是 Kubernetes 包管理器,类似 Mac 下的 brew,Linux 下的 apt、yum 等包管理工具。
Helm 是 CNCF 的毕业项目,是查找、分享和使用软件构建 Kubernetes 的最优方式(Helm官方说的)。
Helm is the best way to find, share, and use software built for Kubernetes.
基本概念
-
Chart 代表着 Helm 包。它包含在 Kubernetes 集群内部运行应用程序,工具或服务所需的所有资源定义。你可以把它看作是 Homebrew formula,Apt dpkg,或 Yum RPM 在Kubernetes 中的等价物。
-
Repository(仓库) 是用来存放和共享 charts 的地方。(非必须,本文以本地 charts 文件为例,不使用Repository)
-
Release 是运行在 Kubernetes 集群中的 chart 的实例。一个 chart 通常可以在同一个集群中安装多次。每一次安装都会创建一个新的 release。以 MySQL chart为例,如果你想在你的集群中运行两个数据库,你可以安装该chart两次。每一个数据库都会拥有它自己的 release 和 release name。
Helm 安装 charts 到 Kubernetes 集群中,每次安装都会创建一个新的 release。你可以在 Helm 的 chart repositories 中寻找新的 chart。
安装
前置条件
-
一个 Kubernetes 集群
-
确定你安装版本
查看Helm和对应支持的Kubernetes版本,您可以参考 Helm 版本支持策略。
-
安装和配置Helm。
1 |
|
Chart 模板指南
创建chart
1 |
|
目录结构
1 |
|
-
values.yaml
文件也导入到了模板。这个文件包含了chart的 默认值 。这些值会在用户执行helm install
或helm upgrade
时被覆盖。 -
Chart.yaml
文件包含了该chart的描述。你可以从模板中访问它。charts/
目录 可以 包含其他的chart(称之为 子chart)。 -
templates/
目录包括了模板文件。当Helm评估chart时,会通过模板渲染引擎将所有文件发送到templates/
目录中。 然后收集模板的结果并发送给Kubernetes。
Chart.yaml
1 |
|
dependencies
当前chart依赖的其他chart会在dependencies
字段定义为一个列表。
1 |
|
一旦你定义好了依赖,运行 helm dependency update
就会使用你的依赖文件下载所有你指定的chart到你的charts/
目录
当 helm dependency update
拉取chart时,会在charts/
目录中形成一个chart包。因此对于上面的示例,会在chart目录中期望看到以下文件:
1 |
|
依赖顺序
上面的部分说明如何指定chart的依赖,但是对使用 helm install
和 helm upgrade
安装chart有什么影响?
假设有个chart “A” 创建了下面的Kubernetes对象:
- namespace “A-Namespace”
- statefulset “A-StatefulSet”
- service “A-Service”
另外,A是依赖于chart B创建的对象:
- namespace “B-Namespace”
- replicaset “B-ReplicaSet”
- service “B-Service”
安装/升级chart A后,会创建/修改一个单独的Helm版本。这个版本会按顺序创建/升级以下所有的Kubernetes对象:
- A-Namespace
- B-Namespace
- A-Service
- B-Service
- B-ReplicaSet
- A-StatefulSet
这是因为当Helm安装/升级chart时,chart中所有的Kubernetes对象以及依赖会
- 聚合成一个单一的集合;然后
- 按照类型和名称排序;然后
- 按这个顺序创建/升级。
至此会为chart及其依赖创建一个包含所有对象的release版本。
Kubernetes类型的安装顺序会按照kind_sorter.go(查看 Helm源文件)中给出的枚举顺序进行。
内置对象
-
Release
:Release
对象描述了版本发布本身,如Release.Name
: release名称 -
Values
:Values
对象是从values.yaml
文件和用户提供的文件传进模板的。默认为空 -
Chart
:Chart.yaml
文件内容,比如{{ .Chart.Name }}-{{ .Chart.Version }}
会打印出mychart-0.1.0
-
Files
: 在chart中提供访问所有的非特殊文件的对象。 请查看这个 文件访问部分了解更多信息 -
Capabilities
: 提供关于Kubernetes集群支持功能的信息 -
Template
: 包含当前被执行的当前模板信息请在内置对象中查看更多
Values 文件
Values内容来自于多个位置:
- chart中的
values.yaml
文件 - 如果是子chart,就是父chart中的
values.yaml
文件 - 使用
-f
参数(helm install -f myvals.yaml ./mychart
)传递到helm install
或helm upgrade
的values文件 - 使用
--set
(比如helm install --set foo=bar ./mychart
)传递的单个参数
以上列表有明确顺序:默认使用values.yaml
,可以被父chart的values.yaml
覆盖,继而被用户提供values文件覆盖, 最后会被--set
参数覆盖,优先级为values.yaml
最低,--set
参数最高。
Templates and Values
所有模板文件存储在chart的 templates/
文件夹。 当Helm渲染chart时,它会通过模板引擎遍历目录中的每个文件。
模板的Value通过两种方式提供:
- Chart开发者可以在chart中提供一个命名为
values.yaml
的文件。这个文件包含了默认值。 - Chart用户可以提供一个包含了value的YAML文件。可以在命令行使用
helm install -f demo.yaml
命令时提供。
当用户提供自定义value时,这些value会覆盖chart的values.yaml
文件中value。
模板函数
开始之前,我们先在values.yaml
文件添加一个披萨的配料列表:
1 |
|
语法
模板函数的语法是 functionName arg1 arg2...
1 |
|
管道符
1 |
|
流控制
If/Else
1 |
|
PIPELINE 如果是以下值时,管道会被设置为 false:
- 布尔false
- 数字0
- 空字符串
nil
(空或null)- 空集合(
map
,slice
,tuple
,dict
,array
)
在所有其他条件下,条件都为true。
with
with 用来控制变量范围
1 |
|
-
.
是对 当前作用域 的引用。因此.Values
就是告诉模板在当前作用域查找Values
对象。with
允许你为特定对象设定当前作用域(.
)。 -
with
后面的块只有在PIPELINE
的值不为空时才会执行。 -
在
with
的作用域内,无法使用.
访问父作用域的对象,可以使用$
从根作用域中访问对象或使用变量
1 |
|
range 循环
- 在
range
的作用域内,无法使用.
访问父作用域的对象,可以使用$
从根作用域中访问对象或使用变量 range
可被用于迭代列表和元组以及有键值对的集合(像map
或dict
)
1 |
|
变量
变量是对另一个对象的命名引用。遵循$name
变量的格式且指定了一个特殊的赋值运算符::=
。
-
用于解决with、range作用域问题
1
2
3
4
5
6
7# 把.Release.Name 赋值给 $relname
{{- $relname := .Release.Name -}}
{{- with .Values.favorite }}
drink: {{ .drink | default "tea" | quote }}
food: {{ .food | upper | quote }}
release: {{ $relname }}
{{- end }} -
变量还可以用于类似列表的对象,以捕获索引和值
1
2
3{{- range $index, $topping := .Values.pizzaToppings }}
{{ $index }}: {{ $topping }}
{{- end }} -
变量还可以用于对于数据结构有key和value,可以使用
range
获取key和value。1
2
3{{- range $key, $val := .Values.favorite }}
{{ $key }}: {{ $val | quote }}
{{- end }}
空格
你可能注意到在上面的流控制中存在 {{-` `-}}
是为了消除流控制空格即换行,YAML认为空格是有意义的。
一定注意空格就是换行
{{- `(包括添加的横杠和空格)表示向左删除空白, 而 - ` -}}
表示右边的空格应该被去掉。
1 |
|
在上面示例中 1未加- food,mug后各有一行空格,因此一般流控制中都会加{{- if xxx -}}
来确保没有空格/换行。
命名模板
- 以下划线(
_
)开始的文件不会渲染为Kubernetes对象定义,但会被helm命令加载。 _helpers.tpl
这个文件是默认的模板文件。
define
使用模板
define
操作允许我们在模板文件中创建一个命名模板
我们可以定义一个模板:
1 |
|
template
和include
使用模板
在configMap使用模板标签
1 |
|
注意两处的app_version
缩进都不对,为啥?因为被替换的模板中文本是左对齐的。由于template
是一个行为,不是方法,无法将 template
调用的输出传给其他方法,数据只是简单地按行插入。而indent 可以使用管道进行缩进。
相较于使用
template
,在helm中使用include
被认为是更好的方式 为了更好地处理YAML文档的输出格式
Chart Hook
Helm 提供了一个 hook 机制允许chart开发者在发布生命周期的某些点进行干预。
注释值 | 描述 |
---|---|
pre-install |
在模板渲染之后,Kubernetes资源创建之前执行 |
post-install |
在所有资源加载到Kubernetes之后执行 |
pre-delete |
在Kubernetes删除之前,执行删除请求 |
post-delete |
在所有的版本资源删除之后执行删除请求 |
pre-upgrade |
在模板渲染之后,资源更新之前执行一个升级请求 |
post-upgrade |
所有资源升级之后执行一个升级请求 |
pre-rollback |
在模板渲染之后,资源回滚之前,执行一个回滚请求 |
post-rollback |
在所有资源被修改之后执行一个回滚请求 |
test |
调用Helm test子命令时执行 ( test文档) |
常用命令
-
helm version
打印客户端版本信息 -
helm upgrade --install
升级/安装chart -
helm rollback
- 回滚发布到上一个版本 -
helm lint
是验证chart是否遵循最佳实践的首选工具。 -
helm template --debug
在本地测试渲染chart模板。 -
helm install --dry-run --debug
:让服务器渲染模板,然后返回生成的清单文件。这样不会安装应用(chart)到你的kubenetes集群中,只会渲染模板内容到控制台(用于测试) -
helm get manifest
: 这是查看安装在服务器上的模板。
总结
-
即使是最复杂的应用,Helm Chart 依然可以描述, 提供使用单点授权的可重复安装应用程序。
-
随时随地升级和自定义的钩子消除您升级的痛苦。
-
Helm Chart 很容易在公共或私有化服务器上发版,分发和部署站点。
-
使用
helm rollback
可以轻松回滚到之前的发布版本。