开发自己的helm chart
helm chart项目结构
创建一个新的helm chart项目
看一下创建出的目录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| [root@paas-m-k8s-master-1 hello-helm]# tree hello-helm/ hello-helm/ ├── charts ├── Chart.yaml ├── templates │ ├── deployment.yaml │ ├── _helpers.tpl │ ├── hpa.yaml │ ├── ingress.yaml │ ├── NOTES.txt │ ├── serviceaccount.yaml │ ├── service.yaml │ └── tests │ └── test-connection.yaml └── values.yaml
3 directories, 10 files
|
各文件目录的作用:
Chart.yaml
Chart.yaml ,声明了当前 Chart 的名称、版本等基本信息,这些信息会在该 Chart 被放入仓库后,供用户使用时查看
文件的字段也比较简单
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| apiVersion: v2 // 不要改 name: hello-helm // chart应用名,一般建好了也不用改 description: 描述
# 类型,可以是 'application' 或者 'library'. # application类型说明这个chart是个应用,可以部署 # library类型的chart不能直接部署,是作为其他chart的依赖库使用 type: application
# chart的版本,每次发布要递增 version: 0.1.0
# 内部应用的版本,比如我这个chart是部署redis的,这里应该写redis的版本 appVersion: "5.0.8"
|
values.yaml
我们在部署时修改的配置参数抽象出来,存放在values.yaml文件里。
当部署chart时,可以根据自己的需求就行修改。
values.yaml中的配置参数会被使用到templates 目录下的部署文件中。
templates 目录
templates 文件夹内放的是应用部署所需要使用的 YAML 文件,比如 Deployment 和 Service的yaml文件。
我们打开自动生成的一个deployment.yaml文件

这里会用到很多helm template的语法。
helm在部署应用时,会解析template下的文件,对文件进行“编译”,然后交给K8s执行。
具体内容可以查看官方文档Helm | Getting Started
这里只简单说说重要的
模板命令放在{{ }}之间
可以使用Chart.yaml中的数据
用到了chart的AppVersion
使用本次install的版本信息,.Release
当前执行的template相关信息,.Template
函数
template里可以使用一些内置函数。比如default函数,设置一个默认值。如果前面忘记设置这个默认值会生效。
还有截图中的nindent函数控制缩进
Helm | Template Function List
管道符 | 和linux下的用法一样
条件控制语句
if/else, 用来创建条件语句
with, 用来限定作用域。
range, 提供”for each”类型的循环
include 可以引入定义的模板,关于定义模板查看官方文档。上面截图中include语句后面的.,是传给模板的作用域。
charts目录
charts目录下可以包含其他chart。
不必须,入门的时候先不管这个。
其他文件
NOTES.txt:显示给用户的帮助文档。用户执行helm install时看到的
_helpers.tpl:模板文件,可以复用。入门阶段不要管这个。
.helmignore:来指定你不想包含在你的helm chart中的文件
好了,现在把各个文件大体看一下即可。然后我们把templates目录下的文件都删除。开始创建自己的helm chart。
helm Chart初体验
之前我们部署过一个单节点的redis
K8S上部署一个redis (qq.com)
在部署过程中,我们依次创建了configmap,pvc,deployment,svc等资源。
现在我们把这个部署创建成自己的helm chart
依次建好几个文件
入门起见,这里也很简单,你一看就明白。
Chart.yaml
1 2 3 4 5 6 7 8 9
| apiVersion: v2 name: my-redis description: simple redis demo
type: application
version: 1.0.0
appVersion: "5.0.5"
|
values.yaml
1 2 3 4 5 6 7 8 9 10
| name: my-redis
image: redis:5.0.5-alpine replicas: 1 storageClassName: nfs-client storageSize: 1Gi
redis: dir: /data/data requirepass: 123456
|
templates/NOTES.txt
1 2 3 4 5 6 7 8 9 10
| Thank you for installing {{ .Chart.Name }}.
Your release is named {{ .Release.Name }}.
redis 密码为: {{ .Values.redis.requirepass }}
To learn more about the release, try:
$ helm -n {{ .Release.Namespace }} status {{ .Release.Name }} $ helm -n {{ .Release.Namespace }} get all {{ .Release.Name }}
|
templates/几个部署yaml
1 2 3 4 5 6 7 8
| apiVersion: v1 kind: ConfigMap metadata: name: {{ .Values.name }}-config data: redis-config: | dir {{ .Values.redis.dir }} requirepass {{ .Values.redis.requirepass }}
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| apiVersion: v1 kind: PersistentVolumeClaim metadata: name: {{ .Values.name }}-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: {{ .Values.storageSize }} storageClassName: {{ .Values.storageClassName }} volumeMode: Filesystem
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| apiVersion: apps/v1 kind: Deployment metadata: name: {{ .Values.name }}-deploy labels: app: redis spec: replicas: {{ .Values.replicas }} selector: matchLabels: app: redis template: metadata: labels: app: redis spec: volumes: - name: redis-data persistentVolumeClaim: claimName: {{ .Values.name }}-pvc - name: config configMap: name: {{ .Values.name }}-config items: - key: redis-config path: redis.conf containers: - name: redis image: {{ .Values.image }} command: - "sh" - "-c" - "redis-server /data/conf/redis.conf" ports: - containerPort: 6379 protocol: TCP resources: limits: cpu: "1" volumeMounts: - name: redis-data mountPath: {{ .Values.redis.dir }} - name: config mountPath: /data/conf
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| apiVersion: v1 kind: Service metadata: name: {{ .Values.name }}-svc labels: app: redis spec: type: NodePort ports: - name: redis-port port: 6379 targetPort: 6379 selector: app: redis
|
部署
1 2 3 4 5 6
| kubectl create ns my-redis // 安装 helm -n my-redis install my-redis .
// 调试修改代码后升级安装 helm -n my-redis upgrade my-redis .
|

好了,效果还可以。
总体感受是,helm chart写起来不难,它内置的函数很多,可以编写比较复杂的流程。
将变量提取到values文件中,避免了每次部署需要去多个文件修改变量的问题,减少了出错的可能。