这是我参与8月更文挑战的第11天,活动详情查看:8月更文挑战
目标
自行编写一个可运行的chart,该chart启动一个springboot 服务
脚手架
官方给的demo其实就是最好的脚手架,我们只需要根据demo里面的 内容修改,改成我们需要的 配置既可
该demo chart是以deployment控制器部署一个nginx容器
创建脚手架
#生成一个mychart 名称的 chart包
helm create mychart
查看目录树结构,可以看到如下
- Chart.yaml 该chart包描述文件
- values.yaml 值定义文件 (非常重要)
- tlp 帮助文件
- NOTES 部署完成后的tip文件
- test 测试文件
[root@k8s-node1 mychart]# tree
├── charts
├── Chart.yaml
├── templates
│ ├── deployment.yaml
│ ├── _helpers.tpl
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── NOTES.txt
│ ├── serviceaccount.yaml
│ ├── service.yaml
│ └── tests
│ └── test-connection.yaml
└── values.yaml
梳理结构
接下来我们将先不需要的文件删除,因为我们是打造一个springboot运行的chart ,且前不打算用ingresss,只使用NodePort提供访问。。且直接在线运行,不需要测试。。另外该服务不涉及权限,就是单纯跑个小接口,所以将删除以下文件
删除以下文件
├── charts #空目录
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── serviceaccount.yaml
│ └── tests
│ └── test-connection.yaml
删除完之后的结构
梳理完之后的目录结构就比较清晰了,接下来我们开始分析 各配置文件
配置文件分析
一个一个配置文件来分析,一步一步掌握如何修改和理解配置文件
Chart.yaml
查看Chart.yaml文件,将空格和#开始的注释文件过滤掉,将主要内容展示出来
[root@k8s-node1 mychart]# cat Chart.yaml | grep -v ^# | grep -v ^$
apiVersion: v2
name: mychart
description: A Helm chart for Kubernetes
type: application
version: 0.1.0
appVersion: "1.16.0"
- apiVersion helm3兼容的api
- name chart包名称
- description 对该chart的描述 比如是springboot小接口
- type 类型(数据库,应用,中间件等)
- version 该chart目前的版本
- appVersion 对应的app版本,假设我们这个项目是刚开始。写个0.1之类的
values.yaml
查看values.yaml文件,同样将空格和#开始的注释文件过滤掉,将主要内容展示出来
[root@k8s-node1 mychart]# cat values.yaml | grep -v ^# | grep -v ^$ | grep -v "#"
replicaCount: 1
image:
repository: nginx
pullPolicy: IfNotPresent
tag: ""
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
create: true
annotations: {}
name: ""
podAnnotations: {}
podSecurityContext: {}
securityContext: {}
service:
type: ClusterIP
port: 80
ingress:
enabled: false
className: ""
annotations: {}
hosts:
- host: chart-example.local
paths:
- path: /
pathType: ImplementationSpecific
tls: []
resources: {}
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
nodeSelector: {}
tolerations: []
affinity: {}
该yaml文件全部是 template目录下 配置文件 需要的值,因为我们把hpa,ingress,服务账号等删除了,所以该配置文件中 这3个部分的也可以删除
只剩下控制器的 副本数和镜像 以及service的服务访问方式和端口 相关配置,其他配置都是空值
service.yaml
service就是k8s 中的service配置,只是使用的helm 配置文件语法,但很多地方还是一眼就能看明白
[root@k8s-node1 mychart]# cat templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: {{ include "mychart.fullname" . }}
labels:
{{- include "mychart.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
{{- include "mychart.selectorLabels" . | nindent 4 }}
deployment.yaml
deployment同理也是k8s中deployment的配置,在这里也是用的helm语法,这其中因为我们删除了values部分内容,
如果不知道怎么删除,可以先使用helm lint 检查语法, 会提示多少行有问题,然后删除既可
其中亲和性,容忍之类如果不配置,也可以删除掉
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "mychart.fullname" . }}
labels:
{{- include "mychart.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "mychart.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "mychart.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
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 }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
NOTES.txt
接下来我们渲染一下,但不实际部署
helm install --debug --dry-run testchart .
在最后出现的NOTES部分 就是在NOTES.txt定义的内容,就是应用部署之后的使用说明文件,一样也要将之前 删除values.yaml内容 对应的删除掉
可以借助helm lint 定位行数
_helpers.tpl
模版定义文件,将使用相同内容 的地方组合,抽象出来
可以看到很多 define 这个关键词,,这部分内容 将以 include 关键词插入到service和deployment配置文件中
labels例子
{{/*
Common labels
*/}}
{{- define "mychart.labels" -}}
helm.sh/chart: {{ include "mychart.chart" . }}
{{ include "mychart.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
springboot-chart
接下来需要改造成 我们要使用的 springboot应用chart 包
1. 修改Chart.yaml配置选项
改个名字和描述,以及app版本
name: springboot-api
description: springboot small api
appVersion: "1.0.0"
2. 修改values.yaml配置选项
修改image名称和地址,以及服务访问,我们的springboot是8080端口,为了区分副本数,改为2
replicaCount: 2
image:
repository: springboot
tag: v1
service:
type: NodePort
port: 8080
3. 修改deployment.yaml配置选项
因为service.yaml 值全部在values里面了。所以这里不需要修改,直接改deployment就可以了
只需要修改containerPort 为了方便启动,将2段删除 livenessProbe: readinessProbe: 不是二行哦。
containerPort: 8080
到这里,一个简单配置的chart 包修改完成了,接下来使用helm lint
检查配置,使用helm install --debug --dry-run testchart .
渲染debug 没有使用就直接运行了
直接部署 testchart 名称也可语义化一点 比如: test-order-api
helm install --debug --dry-run testchart .
可以看出服务部署成功了,使用集群IP:31928 既可访问接口
总结
chart包的制作 涉及到kubernetes yaml配置和helm 模版本语法,需要经常练习,方能掌握
如果想要学习大佬们怎么写chart包的,可以上Artifact Hub查看 相关的模版