Akemi

Helm父子chart的关系与实战

2024/12/17

本文建议有helm基础再进行阅读
甚至没有看官方文档,纯自己试验和理解来的

父子chart的关系说明

helm的父chart和子chart说白了,关联性不大
通过以下几个方式进行联系:

1.父Chart的Chart.yaml

需要在其中定义依赖项dependencies,通过列表的方式指定子chart的位置
只有定义了依赖项,父Chart才知道有这么个子Chart
并且同时指定了condition,condition这个字段指示了子Chart与Values关联的位置

2.父Chart的Values.yaml

Values文件众所周知是存放了yaml部署需要的变量,并且通过go进行引用渲染
在渲染时,helm会将父Chart和子Chart的Values文件进行合并
子Chart当然可以使用自己的Values文件,如果子Values文件中没有指定,
就会使用合并之后的文件,换句话说就是从父Values文件中去找

对于合并Values的详细说明

父Values和子Values的合并并不是完全合并,
而是将父Values中,涉及子Chart那一层级的字段与子Values文件合并。
如果是完全合并的情况下,子template引用变量时,引用父Values是需要多加一层缩进的,
但因为这种分开合并的方式,使子template在定义时,直接通过Values.xxx就可以直接引用到

为什么说关联性不大

因为子Chart是独立的,模块化的,很容易迁移的。
在实际生产中,完全可以测试完成之后,直接把整个Chart放入父Chart的目录下然后
修改父Chart.yaml和父Values文件

子Chart的实际应用

最重要的是理解父子Chart目录之间的层级关系
这个案例就是生产环境中接入新服务到父Chart前进行的测试

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
1.创建父Chart
现在我有个根目录,我在这个根目录下创建
helm create helm-fa
helm-fa目录就是我的父目录,包括Chart,template文件夹等

2.定义子chart
首先要在父Chart的Chart.yaml中进行定义依赖项:
dependencies:
- name: infra
version: 0.5.2
repository: "file://./charts/infra"
condition: infra.enabled
这个定义就是告诉父Chart,子Chart的位置,以及子Chart的开关
即Values文件中infra.enabled字段,如果为true则启用依赖项

3.创建子chart
根据父Chart.yaml中指定的位置,进入charts创建
helm create helm-son
创建,此时父chart的目录结构,是父的chart文件夹中包含了一个子chart

子chart中也包含了values,template等文件

4.修改父Values文件、添加template部署文件
这两步之所以放在一块,是因为它俩是互相呼应的,template文件需要根据Values文件的层级结构
进行变量的引用。
chart在创建时是自带deployment的模板的,而我要使用statefulset的模板

所以建议使用AI直接生成,因为我也是这么做的
直接生成一个statefulset和对应values的模板
在此基础上进行修改

statefulset文件:
{{- if and .Values.apigateway .Values.apigateway.enabled }}
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ .Values.apigateway.name }}
spec:
serviceName: "{{ .Values.apigateway.name }}"
replicas: {{ .Values.apigateway.statefulset.replicas }}
selector:
matchLabels:
app: {{ .Values.apigateway.name }}
template:
metadata:
labels:
app: {{ .Values.apigateway.name }}
spec:
containers:
- name: {{ .Values.apigateway.name }}
image: "{{ .Values.apigateway.statefulset.image.repository }}:{{ .Values.apigateway.statefulset.image.tag }}"
imagePullPolicy: {{ .Values.apigateway.statefulset.image.pullPolicy }}
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: {{ .Values.apigateway.name }}
spec:
type: {{ .Values.apigateway.service.type }}
ports:
- port: {{ .Values.apigateway.service.port }}
targetPort: {{ .Values.apigateway.service.targetPort }}
selector:
app: {{ .Values.apigateway.name }}
{{- end }}

父Values文件:
infra:
enabled: true
apigateway:
enabled: true
name: api-gateway
statefulset:
replicas: 1
image:
repository: xxx
tag: xxx
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 8080
targetPort: 80

这两个文件是需要结合起来看的,就能发现statefulset.yaml中通过go引用的变量
在Values中都已经通过yaml的层级定义好了

这里引出一个问题,按照父Values的定义,
statefulset.yaml引用时,应该是Values.infra.xxx,为什么可以直接使用apigateway字段进行引用?

这个上面也提了,就是父Values和子Values合并时,只会合并infra后面的字段。毕竟helm认为它俩是同一个东西

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
5.添加一些字段
比如我这台机器是单点k8s,我就需要打污点,那么怎么做呢
我在statefulset.yaml中加入
{{- if .Values.tolerations }}
tolerations:
{{- toYaml .Values.tolerations | nindent 8 }}
{{- end }}
这里直接引用父values.yaml的tolertaions设置
如果想要在父values中单独判断,
那只需要把这个变量改成.Values.apigateway.tolerations就行

6.部署
helm install test ./

如图

CATALOG
  1. 1. 父子chart的关系说明
  2. 2. 子Chart的实际应用