Helm是Kubernetes的包管理工具,如果把比作操作系统,那么Helm就好比yum,apt-get,homebrew。使用Helm template可以方便我们部署和管理自己的应用。本篇将基于Helm3.0+带你快速入门Helm template。
若需要执行本篇示例,需要准备:
在开始之前,我们简单理解一下Helm template的基本原理。其实也很简单,Helm使用go template模板语言来编写代表Kubernetes资源(deployment,service, etc...)的模板文件,并提供让用户配置这些模板变量的能力。在部署时Helm通过模板引擎将模板渲染成真正的Kubernetes资源文件,并将它们部署到节点上。
使用以下命令创建模板:
$ helm create mychart
复制代码
该命令会在当前目录下创建如下结构的文件夹:
mychart
├── Chart.yaml
├── charts
├── templates
│ ├── NOTES.txt
│ ├── _helpers.tpl
│ ├── deployment.yaml
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── service.yaml
│ ├── serviceaccount.yaml
│ └── tests
│ └── test-connection.yaml
└── values.yaml
helm install
或者 helm upgrade
可以指定新的值来覆盖默认值。[root@k8s-master ~]# mkdir -p mychart
[root@k8s-master mychart]# mkdir -p templates
[root@k8s-master mychart]# ls
templates
这里面是chart的描述信息
[root@k8s-master mychart]# vim Chart.yaml
[root@k8s-master mychart]# cat Chart.yaml
apiVersion: v2
name: mychart
description: A Helm chart for Kubernetes
type: application
version: 0.1.0
appVersion: 1.16.0
[root@k8s-master mychart]# ls
Chart.yaml templates
这里把基本需要的变量先写上
[root@k8s-master mychart]# cat values.yaml
replicaCount: 1
image:
repository: nginx
pullPolicy: IfNotPresent
tag: "1.16"
selectorLabels: "nginx"
[root@k8s-master mychart]# ls
Chart.yaml templates values.yaml
这个目录下就放着其模板文件
[root@k8s-master mychart]# cd templates/
[root@k8s-master templates]# ls
deployment.yaml service.yaml
创建一个空的
[root@k8s-master templates]# touch _helpers.tpl
部署好chart会显示
[root@k8s-master templates]# touch NOTES.txt
[root@k8s-master templates]# vim NOTES.txt
[root@k8s-master templates]# cat NOTES.txt
hello this is mychart
这样就将差异化的地方通过模板做了替换,heml之后会将其字段替换为具体值
模板引用方式,{{ .Release.Name }},
通过双括号注入,小数点开头表示从最顶层命名空间引用。
Release, release相关属性
Chart, Chart.yaml文件中定义的内容
Values, values.yaml文件中定义的内容
常用函数:
• quote:将值转换为字符串,即加双引号
• default:设置默认值,如果获取的值为空则为默认值
• indent和nindent:缩进字符串
• toYaml:引用一块YAML内容
• 其他函数:upper、title等
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
nodeSelector:
gpu: true
containers:
- name: web
image: nginx:1.19
[root@k8s-master templates]# kubectl apply -f deployment.yaml
Error from server (BadRequest): error when creating "deployment.yaml": Deployment in version "v1" cannot be handled as a Deployment: v1.Deployment.Spec: v1.DeploymentSpec.Template: v1.PodTemplateSpec.Spec: v1.PodSpec.NodeSelector: ReadString: expects " or n, but found t, error found in #10 byte of ...|":{"gpu":true}}}}}
|..., bigger context ...|nginx:1.19","name":"web"}],"nodeSelector":{"gpu":true}}}}}
|..
以为gpu的值true不是字符串类型,因为这个是布尔的类型,这里需要不管输入的是什么值都需要转成字符串,使用这个函数就非常有用了,quote:将值转换为字符串,即加双引号
[root@k8s-master ~]# cat mychart/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}
namespace: default
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Values.selectorLabels }}
template:
metadata:
labels:
app: {{ .Values.selectorLabels }}
spec:
nodeSelector:
gpu: {{ .Values.nodeSelector.gpu }}
containers:
- name: web
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
[root@k8s-master ~]# cat mychart/values.yaml
replicaCount: 1
image:
repository: nginx
pullPolicy: IfNotPresent
tag: "1.16"
selectorLabels: "nginx"
nodeSelector:
gpu: true
[root@k8s-master ~]# helm install web1 --dry-run mychart/
spec:
nodeSelector:
gpu: true
修改之后渲染
spec:
nodeSelector:
gpu: {{ quote .Values.nodeSelector.gpu }}
[root@k8s-master ~]# helm install web1 --dry-run mychart/
spec:
nodeSelector:
gpu: "true"
针对一些字符串是函数类型,那么使用该函数
这个是values.yml里面的定义
replicaCount: 1
image:
repository: nginx
pullPolicy: IfNotPresent
tag: ""
selectorLabels: "nginx"
nodeSelector:
gpu: true
namespace: ""
deployment.yml定义
metadata:
name: {{ .Release.Name }}
namespace: {{ .Values.namespace | default "default" }}
[root@k8s-master ~]# helm install web1 --dry-run mychart/
metadata:
name: web1
namespace: default
[root@k8s-master ~]# helm install web1 --set namespace=test --dry-run mychart/
metadata:
name: web1
namespace: test
indent和nindent函数都是缩进字符串,主要区别在于nindent会在缩进前多添加一个换行符。
metadata:
labels:
app: web
app: {{ .Release.Name | indent 6 }}
app: {{ .Release.Name | nindent 6 }
metadata:
labels:
app: web
app: web
app:
web
name: web
indent用的很少,nindent用的多,一般是结合引用内容块,也就是从另外一块yaml当中将其引用过来
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
ports:
- name: http
containerPort: 80
protocol: TCP
livenessProbe:
httpGet:
path: /
port: http
readinessProbe:
httpGet:
path: /
port: http
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- with .Values.nodeSelector }}
当然了,块这种通过引用,那种变量为键值类型的,那么在values里面定义以层级关系定义,在引用的时候通过.来层级引用,多个层级多个.去引用{{ .valuse.image.repository }},对于复杂的块的方式不适合.去取值,适合使用toYaml,不管有多少东西都拿过来。
image:
repository: nginx
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: "1.17"
示例 toYaml用法:(toYaml是顶头放的,所以需要换行缩进)
[root@k8s-master ~]# vim mychart/templates/deployment.yaml
containers:
- name: web
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
resources:
{{- toYaml .Values.resources | nindent 10 }}
[root@k8s-master mychart]# vim values.yaml
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
[root@master ~]# helm install web testchart/ --dry-run
- image: nginx:1.17
name: nginx
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
[root@k8s-master ~]# helm install web1 --set resources.limits.cpu="200m" --dry-run mychart/
resources:
limits:
cpu: 200m
resources和健康检查都可以写到values.yaml里面去,并且在deployment模板文件里面通过toYaml进行引用进来。