众所周知helm chart中有几个文件:
Chart.yaml图表文件
template资源文件
Values.yaml变量文件
_helpers.tpl模板函数文件
定义规范
定义规范就是“官方推荐的”,默认自带的东西
使用helm create创建出来的chart就是这些东西都带的
Chart图表文件
这个文件没什么东西
1 2 3 4 5 6 7 8 9 10 11 12
| apiVersion: v2 name: qa-data-platform description: A Helm chart for Kubernetes version: 0.5.1 appVersion: "1.16.0"
基本上不太重要
需要注意的是 这几个ky是可以被chart.name这样的方式直接引用到 比如这两个version是被_helpers.tpl中的函数引用了
但是不重要,毕竟没有环境的app tag会简单到像是1.16这种,顶多当成一个chart的version
|
父子chart
如果想要使用父子chart的结构,需要在父Chart.yaml中新增定义依赖项
像是这样
1 2 3 4 5 6 7 8 9 10 11
| apiVersion: v2 name: qa-data-platform description: A Helm chart for Kubernetes version: 0.5.1 appVersion: "1.16.0"
dependencies: - name: wangsheng version: 22.0.0 repository: "@wangsheng" ←这是一个别名,如果真的有helm仓库,也可以直接填url condition: wangsheng.enabled ←开启依赖项条件,即wangsheng.enabled字段为true
|
_helpers.tpl助手函数文件
这是最唬人的一个文件,用的是Helm模板语言
官方的规范在里面定义了:应用的名称、pod的labels、selector的labels、sa名称等
要我说直接变量文件里指定一个name,然后这些东西全都用这个name就行,就不需要绕来绕去了
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
| 定义qa-ws应用的名称 {{- define "qa-ws.fullname" -}} {{- if .Values.ws.fullNameOverride }} 如果有ws.fullNameOverride就用fullNameOverride {{- .Values.ws.fullNameOverride | trunc 63 | trimSuffix "-" }} {{- else }} 如果没有ws.fullNameOverride,也没有ws.nameOverride,就默认用chart.name {{- $name := default .Chart.Name .Values.ws.nameOverride }} {{- if contains $name .Release.Name }} 如果release的name包含了变量name,就用release的name {{- .Release.Name | trunc 63 | trimSuffix "-" }} {{- else }} 如果不包含,就把$name赋给release并且格式化成字符串后输出 {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} {{- end }} {{- end }} {{- end }}
定义sa名称 {{- define "wangsheng-chart.serviceAccountName" -}} {{- if .Values.serviceAccount.create }} 如果serviceAccount.create字段为true {{- default (include "wangsheng-chart.fullname" .) .Values.serviceAccount.name }} 并且如果serviceAccount.name没有定义,则默认使用wangsheng-chart.fullname {{- else }} 如果serviceAccount.create字段为false {{- default "default" .Values.serviceAccount.name }} {{- end }} {{- end }}
|
Values.yaml变量文件
这个也没什么可讲的,变量文件和模板文件是呼应的,用yaml缩进的方式来定义
helm模板解析
着重解读一下资源文件,也就是yaml部署文件
关键字段介绍
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| if 条件判断语句,后面可以接and not这种逻辑运算符,如果为真则渲染域中内容
with 条件判断语句,判断如果该字段存在且不为空,就会渲染这个域中的内容
include 表示引用_helpers.tpl中的一些函数——最后会指向Values文件
toYaml 表示将下面获取到的字段使用yaml格式返回,经常与| nindent一起使用,且经常用于多行内容 | nindent 8 表示向后8个空格,防止yaml的缩进出现错误
default 默认定义,优先级最低,字段不存在或为空时会使用
merge 合并字段,如果B字段存在则合并到A,常与with一起使用
end 宣告结束一个域,因为with和if都会领域展开
|
模板解读
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
| {{- if and .Values.bge .Values.bge.enabled }} 如果bge字段存在且enabled字段为true,则进行部署 apiVersion: apps/v1 kind: Deployment metadata: name: {{ include "qa-data-platform-bge.fullname" . }} 在_helpers.tpl中定义的,具体会在定义规范里讲 labels: {{- include "qa-data-platform-bge.labels" . | nindent 4 }} 见定义规范 spec: {{- if not .Values.autoscaling.enabled }} 如果autoscaling.enabled不为true,则加载这一段,并获取replicaCount replicas: {{ .Values.replicaCount }} {{- end }} selector: matchLabels: {{- include "qa-data-platform-bge.selectorLabels" . | nindent 6 }} 见定义规范 template: metadata: {{- with .Values.podAnnotations }} annotations: {{- toYaml . | nindent 8 }} {{- end }} labels: {{- include "qa-data-platform-bge.selectorLabels" . | nindent 8 }}见定义规范 spec: {{- with default .Values.imagePullSecrets .Values.global.common.imagePullSecrets }} 默认使用.Values.imagePullSecrets,如果不存在,则使用.Values.global.common.imagePullSecrets imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} serviceAccountName: {{ include "qa-data-platform.serviceAccountName" . }} securityContext: 获取podSecurityContext并解析为yaml,向后缩进8字符 {{- toYaml .Values.podSecurityContext | nindent 8 }} containers: - name: {{ .Chart.Name }} Chart.yaml中定义 securityContext: {{- toYaml .Values.securityContext | nindent 12 }} image: "{{ .Values.bge.image.repository }}:{{ .Values.bge.image.tag | default .Chart.AppVersion }}" {{- with .Values.bge.image.command }} command: 如果bge.image中定义了command,就引入command这段,直到end {{- toYaml . | nindent 12 }} {{- end }} imagePullPolicy: {{ .Values.bge.image.pullPolicy }} ports: - name: http containerPort: {{ .Values.bge.service.port }} protocol: TCP {{- with .Values.bge.env }} env: 获取env,并以yaml方式返回 {{- toYaml . | nindent 12 }} {{- end }} {{- if .Values.bge.healthCheck.enabled }} livenessProbe: 健康检查是否开启,如果开启则引入这一段直到end httpGet: path: {{ default `/` .Values.bge.healthCheck.healthPath }} port: http readinessProbe: httpGet: path: {{ default `/` .Values.bge.healthCheck.healthPath }} port: http startupProbe: httpGet: path: {{ default `/` .Values.bge.healthCheck.healthPath }} port: http failureThreshold: 30 periodSeconds: 10 {{- end }} resources: 以yaml格式获取资源配额 {{- toYaml .Values.bge.resources | nindent 12 }} {{- with .Values.bge.volumeMounts }} volumeMounts: {{- toYaml . | nindent 12 }} {{- end }} {{- with merge .Values.global.common.nodeSelector .Values.nodeSelector }} 合并父子变量文件后,判断是否存在,如果存在则引入nodeSelector配置 nodeSelector: {{- toYaml . | nindent 8 }} {{- end }} {{- with .Values.affinity }} affinity: {{- toYaml . | nindent 8 }} 判断是否存在亲和性配置,存在则用yaml引入 {{- end }} {{- with .Values.global.common.tolerations }} tolerations: {{- toYaml . | nindent 8 }} {{- end }} {{- with .Values.bge.volumes }} volumes: {{- toYaml . | nindent 8 }} {{- end }} {{- with .Values.bge.hostAliases }} hostAliases: {{- toYaml . | nindent 8 }} {{- end }} {{- end }} 第一行if的域的闭合
|
引入子Chart与应用
那么现在我要在一个父子结构的chart中新加入一个应用、或者直接加一个子chart,应该遵循什么样的规范?
添加子chart
这个在另外一篇博客中讲了
主要是chart.yaml中依赖项添加与父子变量文件的管理
迁移或添加新应用
根据上面的内容:
1.为新的应用添加应用的名称、pod的labels等内容,在_helpers.tpl中
2.使用合适的变量存放位置,一般推荐在父变量中方便管理
3.对比新旧环境差异,对于节点容忍度、镜像拉取密钥、镜像仓库位置、节点亲和性等需要逐一对比