Helm是一款强大而灵活的 Kubernetes 软件包管理和运维工具,类似于apt、yum等包管理工具。运用Helm可以极大的简化Kubernetes应用部署。我使用的是Helm3,相比于Helm2其最大的变化是去掉了Tiller,使用起来更加方便。有关Helm2和Helm3的具体区别可以查看官方介绍changes-since-helm-2。
homebrew(macOS)方式
brew install kubernetes-helm
wget方式
$ wget -c https://get.helm.sh/helm-v3.0.2-linux-amd64.tar.gz
$ tar -zxvf helm-v3.0.0-linux-amd64.tar.gz
$ mv linux-amd64/helm /usr/bin/helm
snap 方式
snap install helm --classic
要正常使用请确保当前环境已配置$HOME/.kube/config
,或者参考helm env
进行相关配置
方式一:
新建GitHub仓库指定分支gh-pages设置hub pages作为仓库服务
使用示例:
# 添加私有repo(https://heinigai.github.io/testing-helm/是我创建的repo地址)
helm repo add mytestrepo https://heinigai.github.io/testing-helm/
# 创建chart包
helm create hello
# 编写chart后打包
helm package mychart
# 生成index信息
helm repo index ./ --url https://heinigai.github.io/testing-helm/
# 提交修改至仓库
git commit -a -m"xx"
git push
# 更新repo
helm repo update
# 查看repo包信息
helm search repo mytestrepo
方式二:
chartmuseum作为仓库服务
使用示例:
# 安装chartmuseum
curl -LO https://s3.amazonaws.com/chartmuseum/release/latest/bin/linux/amd64/chartmuseum
chmod +x ./chartmuseum
mv ./chartmuseum /usr/local/bin
chartmuseum --debug --port=8080 --storage="local" --storage-local-rootdir="./chartstorage" >./chartmuseum.log 2>&1 &
# 安装push插件
helm plugin install https://github.com/chartmuseum/helm-push
# 添加repo
helm repo add mychartmuseum http://localhost:8080
# 推送chart
helm push hello/ chartmuseum
内置对象Values提供对传入 chart 的值的访问。其内容来自四个来源:
其中最复杂也是最常用的是父子chart之间的value值传递。分2种情况进行说明:
使用export格式
如果说一个子chart在其values.yaml的root下有一个叫做exports的key,那么它的父chart就可以直接在requirements里面通过指定需要import的key来将值import到自身的values.yaml里面,例子如下:
# parent's requirements.yaml file
...
import-values:
- data
# child's values.yaml file
...
exports:
data:
myint: 99
helm 会发现,我们指定了要 import data 这个 key,所以就去 child 的 values.yaml 里面寻找,发现了这个 key 有被 export,于是就 import 了它的内容。
这时候的 parent 的 values 如下:
# parent's values file
...
myint: 99
需要注意,在 parent 的 values 中 data 这个 key 不会被 import 进来,只会 import data 的内容。如果希望把这个 key 也一起 import 进来,可以使用下面说的方法。
使用child/parent格式
如果我们想要获得一些不在 exports 这个 key 下面的值,我们就必须指定在 child 中要 import 的路径,以及在 parent 中的对应路径,如下:
# parent's requirements.yaml file
dependencies:
- name: subchart1
repository: http://localhost:10191
version: 0.1.0
...
import-values:
- child: default.data
parent: myimports
根据如上的这个 requirements 文件,helm 将会在 child 的 chart 中寻找 default.data 的值,并导入到 parent 中的 myimports 这个路径下。
假设 parent 和 child 初始的 values 如下:
# parent's values.yaml file
myimports:
myint: 0
mybool: false
mystring: "helm rocks!"
# subchart1's values.yaml file
default:
data:
myint: 999
mybool: true
那么导入之后,真正渲染出来的 parent 的 values 的值为:
# parent's final values
myimports:
myint: 999
mybool: true
mystring: "helm rocks!"
可以看出来,parent 中的 values 把 myint 和 mybool 从 subchart1 里面 import 了进来。
假设子chart的名字是hello, 要修改hello的values.yaml文件的root下的image的值,那么可以在父chart中通过一下方式进行修改:
# in parent's values.yaml
...
hello:
image: 'xxxx/test:hello'
这样hello的values.yaml文件的image值就会被覆盖修改
如果父chart下的所有子chart都有一个共同的变量A,要通过以上方式修改其值显示比较麻烦,这时可以用关键字global;示例如下:
# subchart1's values.yaml file
global:
affinityValue: "test"
# in parent's values.yaml
...
global:
affinityValue: "debug"
这样所有子chart的global.affinityValue都将被覆盖修改
# 创建一个名为test的charts
helm create test
# chart检查
helm lint mychart
# 打包charts
helm package test
# 添加仓库并命名为testrepo
helm repo add testrepo http://localhost:8080
#查看所有仓库
helm repo list
# 更新testrepo仓库
helm repo update testrepo
# 查看 testrepo 仓库的chart包
helm search repo testrepo
# 安装chart包
helm install myredis ./redis
helm install -f myvalues.yaml myredis ./redis
helm install --set name=prod myredis ./redis
helm install --set-string long_int=1234567890 myredis ./redis
helm install --set-file my_script=dothings.sh myredis ./redis
helm install --set foo=bar --set foo=newbar myredis ./redis
# 更新依赖
helm dep up ./redis
# 卸载命名空间t1下的myredis应用
helm uninstall myredis -n t1
# 查看命名空间t1下的所有应用
helm list -n t1
# 查看app
helm show chart stable/postgresql
# 查看app所有信息
helm show all stable/postgresql
# 查看app的yaml
helm get manifest mychart-0-1581772160
表达式
模板表达式:{{ .Chart.name }}
, {{- .Chart.name -}}
表示去掉表达式输出结果前后的空格.
quote 函数
是Sprig 模板库提供的一种字符串函数,用途就是用双引号将字符串括起来,如果需要双引号",则需要添加\来进行转义,而squote函数的用途则是用双引号将字符串括起来,而不会对内容进行转义。
...
k8s: {{ quote .Values.course.k8s }}
管道
是可以按顺序完成一系列事情的一种方法,以上表达式一般用如下的写法:
...
k8s: {{ .Values.course.k8s | quote }}
default 函数
该函数允许我们在模板内部指定默认值,以防止该值被忽略掉了。
# 如果 values.yaml 没有定义 hello,则默认取值为 Hello World
myvalue: {{ .Values.hello | default "Hello World" | quote }}
运算符
if/else 条件
条件块的基本结构如下
{{ if PIPELINE }}
# Do something
{{ else if OTHER PIPELINE }}
# Do something else
{{ else }}
# Default case
{{ end }}
使用示例:
...
{{- if eq .Values.course.python "django" }}
web: true
{{- end }}
使用 with 修改范围
它用来控制变量作用域,语法结构:
{{ with PIPELINE }}
# restricted scope
{{ end }}
使用示例:
...
# with修饰后,. 即表示 .Values.nodeSelector
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
range 循环
类似于for、foreach或者类似功能的循环机制。
data:
{{- range $key, $value := .Values.course }}
{{ $key }}: {{ $value | quote }}
{{- end }}
courselist:
{{- range .Values.courselist }}
- {{ . | title | quote }} # .(点)引用数组元素值
{{- end }}