Helm是一个Kubernetes的包管理工具,就像Linux下的包管理器,如yum/apt等,可以很方便的将之前打包好的yaml文件部署到kubernetes上。k8s 之前部署要写很多的yaml文件,大型应用部署起来比较麻烦,于是helm 就出现了。
Helm有两个重要概念:
helm:一个命令行客户端工具,主要用于Kubernetes应用chart的创建、打包、发布和管理。
Chart:应用描述,一系列用于描述 k8s 资源相关文件的集合。
Release:基于Chart的部署实体,一个 chart 被 Helm 运行后将会生成对应的一个 release;将在k8s中创建出真实运行的资源对象。
部署Helm客户端
压移动到/usr/bin/目录
wget https://get.helm.sh/helm-v3.0.0-linux-amd64.tar.gz
tar zxvf helm-v3.0.0-linux-amd64.tar.gz
mv linux-amd64/helm /usr/bin/
Helm常用命令
命令描述
create
创建一个chart并指定名字
dependency
管理chart依赖
get
下载一个release。可用子命令:all、hooks、manifest、notes、values
history
获取release历史
install
安装一个chart
list
列出release
package
将chart目录打包到chart存档文件中
pull
从远程仓库中下载chart并解压到本地 # helm pull stable/mysql --untar
repo
添加,列出,移除,更新和索引chart仓库。可用子命令:add、index、list、remove、update
rollback
从之前版本回滚
search
根据关键字搜索chart。可用子命令:hub、repo
show
查看chart详细信息。可用子命令:all、chart、readme、values
status
显示已命名版本的状态
template
本地呈现模板
uninstall
卸载一个release
upgrade
更新一个release
version
查看helm客户端版本
配置国内Chart仓库
添加存储库:
helm repo add stable http://mirror.azure.cn/kubernetes/charts //红色表示这里名字可以自定义,类似仓库名字
helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts //红色表示这里名字可以自定义,类似仓库名字
helm repo update
查看配置的存储库:
helm repo list
helm search repo stable
删除存储库:
helm repo remove aliyun //仓库名字
Helm基本使用
查找chart:
# helm search repo
# helm search repo mysql
查看chart信息:
# helm show chart stable/mysql
安装:
# helm install db stable/mysql // db 是表示你给安装mysql起的名字,可自定义
查看发布状态:
# helm status db // db 表示自己建的应用 名字
安装前自定义chart配置选项
部署的mysql并没有成功,这是因为并不是所有的chart都能按照默认配置运行成功,可能会需要一些环境依赖,例如PV
所以我们需要自定义chart配置选项,安装过程中有两种方法可以传递配置数据:
--values(或-f):指定带有覆盖的YAML文件。这可以多次指定,最右边的文件优先
--set:在命令行上指定替代。如果两者都用,--set优先级高
--values使用,先将修改的变量写到一个文件中
# helm show values stable/mysql
# cat config.yaml
persistence:
enabled: true
storageClass: "managed-nfs-storage" // 填写自己的持久化的pv
accessMode: ReadWriteOnce
size: 8Gi //持久卷的大小
mysqlUser: "k8s" 数据库用户名
mysqlPassword: "123456" 数据库密码
mysqlDatabase: "k8s" 数据库
执行:
helm install db -f config.yaml stable/mysql //db 表示 应用名字 config.yaml 表示 刚刚自己定义的变量。
也可以把chart包下载下来查看详情
# helm pull stable/mysql --untar
values yaml与set使用:
helm install命令可以从多个来源安装:
chart存储库
本地chart存档(helm install foo-0.1.1.tgz)
chart目录(helm install path/to/foo)
自己构建一个Helm Chart
执行
helm create mychart
其目录结构和我们中chart库拉出文件目录一致
Chart.yaml:用于描述这个 Chart的基本信息,包括名字、描述信息以及版本等。
values.yaml :用于存储 templates 目录中模板文件中用到变量的值。
Templates: 目录里面存放所有yaml模板文件。
charts:目录里存放这个chart依赖的所有子chart。
NOTES.txt :用于介绍Chart帮助信息, helm install 部署后展示给用户。例如:如何使用这个 Chart、列出缺省的设置等。
_helpers.tpl:放置模板助手的地方,可以在整个 chart 中重复使用
升级、回滚和删除
布新版本的chart时,或者当要更改发布的配置时,可以使用该helm upgrade命令
# helm upgrade --set imageTag=1.17 web mychart //这里变量 是你在模板定义好的变量
# helm upgrade -f values.yaml web mychart
如果在发布后没有达到预期的效果,则可以使用helm rollback回滚到之前的版本。
查库应用发布的历史版本
helm history db //应用名字
之后执行,helm reooback
# helm rollback web 1 // web表示 应用名字 1 表示 回滚的版本号
卸载发行版,请使用以下helm uninstall命令:
# helm uninstall web
查看历史版本配置信息
# helm get --revision 1 web
我们刚刚创建好的chart 是可以直接运行的
执行下面命令:
# helm install web mychart
这样部署,其实与直接apply没什么两样。
然后使用如下命令可以看到实际的模板被渲染过后的资源文件:
# helm get manifest web
# vi templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-deployment
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:1.16
name: nginx
调试
Helm也提供了--dry-run --debug调试参数,帮助你验证模板正确性。在执行helm install时候带上这两个参数就可以把对应的values值和渲染的资源清单打印出来,而不会真正的去部署一个release。
# helm install web2 --dry-run /root/mychart
内置对象
刚刚我们使用 {{.Release.Name}}将 release 的名称插入到模板中。这里的 Release 就是 Helm 的内置对象,下面是一些常用的内置对象:
| Release.Name | release 名称 |
| ----------------- | --------------------------------------------- |
| Release.Time | release 的时间 |
| Release.Namespace | release 的 namespace(如果清单未覆盖) |
| Release.Service | release 服务的名称 |
| Release.Revision | 此 release 的修订版本号,从1开始累加 |
| Release.IsUpgrade | 如果当前操作是升级或回滚,则将其设置为 true。 |
| Release.IsInstall | 如果当前操作是安装,则设置为 true。 |
Values
Values对象是为Chart模板提供值,这个对象的值有4个来源:
chart 包中的 values.yaml 文件
父 chart 包的 values.yaml 文件
通过 helm install 或者 helm upgrade 的 -f或者 --values参数传入的自定义的 yaml 文件
通过 --set参数传入的值
chart 的 values.yaml 提供的值可以被用户提供的 values 文件覆盖,而该文件同样可以被 --set提供的参数所覆盖。
这里我们来重新编辑 mychart/values.yaml 文件,将默认的值全部清空,然后添加一个副本数:
# cat values.yaml
replicas: 3
image: "nginx"
imageTag: "1.17"
# cat templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-deployment
spec:
replicas: {{ .Values.replicas }}
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: {{ .Values.image }}:{{ .Values.imageTag }}
name: nginx
查看渲染结果:
helm install --dry-run web ../mychart/
在写help 也支持语句判断
{{ if PIPELINE }}
# Do something
{{ else if OTHER PIPELINE }}
# Do something else
{{ else }}
# Default case
{{ end }}
条件判断就是判断条件是否为真,如果值为以下几种情况则为false:
一个布尔类型的 假
一个数字 零
一个 空的字符串
一个 nil(空或 null)
一个空的集合( map、 slice、 tuple、 dict、 array)
除了上面的这些情况外,其他所有条件都为 真。
示例:
# cat values.yaml
replicas: 2
label:
project: tets
app: product
env:
test: "test"
# cat templates/deploymemt.yaml
env:
{{ if eq .Values.env.test "test" }}
- name: hello
value: 123
{{ end }}
其中运算符 eq是判断是否相等的操作,除此之外,还有 ne、 lt、 gt、 and、 or等运算符。
通过模板引擎来渲染一下,会得到如下结果:
# helm install --dry-run web ../mychart/
env:
- name: hello
value: 123
可以看到渲染出来会有多余的空行,这是因为当模板引擎运行时,会将控制指令删除,所有之前占的位置也就空白了,需要使用{{- if ...}} 的方式消除此空行
{{- if xxxxxx }}
- name: hello
value: 123
{{- end }}
果使用-}}需谨慎 因为-}}它删除了双方的换行符。
函数:
缩进:{{ .Values.resources | indent 12 }} {{ .Values.resources | nindent 12 }} // nindent 表示会自动换行 , indent 表示不会自动换行
大写:{{ upper .Values.resources }}
首字母大写:{{ title .Values.resources }}
with 用法
with的用法就是 Vlalues 里面的映射成一个数组,key vlaue
with语句可以允许将当前范围 .设置为特定的对象,比如我们前面一直使用的 .Values.label,我们可以使用 with来将 .范围指向 .Values.label:
示例
Values 中
lables:
app: myngins
test: test_test
在deploymemt
{{- with .Vlaues.labes}}
labes:
app: {{ .app }}
test: {{ .test_test }}
{{- end}}
这样写其实还是有点麻烦,我们可以使用另一个函数
toYaml 的一个函数 ,它可以将这个标签下面的值全部拿过来。
我们可以这样写
{{- with .Values.labes}}
labes:
{{- toYaml . | nindent 3}} //缩进
{{- end}}
在with中如何使用内置变量?
直接使用是会报错的,两种方式,一种需要这样写第一种方式:$
{{- with .Vlaues.labes}}
labes:
name: {{$.Release.Name}} //使用 $
app: {{ .app }}
test: {{ .test_test }}
{{- end}}
第二种方式:定义外置变量,在赋值
{{- $ReleaseName := .Release.Name -}}//这里变量必须要使用 $变量名 赋值 使用 := 内置变量
{{- with .Vlaues.labes}}
labes:
name: {{$ReleaseName}} //使用 外置定义变量的方式
app: {{ .app }}
test: {{ .test_test }}
{{- end}}
如何引入 env 结合range 方式
# cat ../values.yaml
env:
NAME: "java_vml"
JAVA_OPTS: "-Xmx1G"
# cat deployment.yaml
。。。。。。
env:
{{- range $key, $value := .Values.env }} //range 在传递env的参数是采用key vlaue 的方式采用的
- name: {{ $key }}
value: {{ $value| quote }}
{{- end }}
Helm 公共模板
定义一个变量,在公共模板中,谁都可以去调用它
{{- define "模板名字" -}}
{{- .Chart.Name -}}-{{ .Release.Name }}
{{- end -}}
deployment
kind: Deployment
metadata:
name: {{ template "模板名字" . }}//使用tmplate调用 公共函数
模板中也可以定义标签
在模板里面定义标签的时候要顶头写,不然后续调用的时候你得计算空格。
# 在 _helpers.tpl
{{- define "version" -}}
version: {{.Chart.name }}
app: {{template "name"}}
{{- end -}}
{{- defin "name" -}}
{{.Release.Name}}
{{- end -}}
在deploymemt.yaml
tets:
{{- include "version" . | nindent 3}} //调用上面的公共函数 ,公共函数中,有函数应用了另个函数,使用tmplate 是无法调用的,所以这个时候我们要使用 include