环境说明
- helm version:
v3.3.1
- kubernetes:
v1.17.9
- 使用 helm chart:
bitnami/mariadb
- 操作系统:
CentOS 7.8.2003
helm 部署 mariadb
前的准备
添加 helm 私服
1
2
3
4
5
6
|
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update # 更新仓库索引
helm search repo mariadb
bitnami/mariadb 9.3.12 10.5.10 Fast, reliable, scalable, and easy to use open-...
|
对 chart 进行 定制更改优化
下载对应 chart 文件
1
2
3
4
5
6
7
8
|
mkdir -p /data/helm/mariadb # create workspace
cd /data/helm/mariadb
helm fetch bitnami/mariadb
tar xf mariadb*.tgz # 解压文件
|
编辑更改 secondary
对应 statefulset 模板文件
因为我们这里使用的是自己创建的 localPv
进行数据的持久存储,而在默认的 secondary
对应的模板文件中,是没有指定使用 现有pvc
的逻辑,所有我们这里需要将这部分逻辑给添加一下。
1
2
3
4
5
6
7
8
9
10
11
12
|
vi mariadb/templates/secondary/statefulset.yaml
...
{{- if not .Values.secondary.persistence.enabled }}
- name: data
emptyDir: {}
{{- else if and .Values.secondary.persistence.enabled .Values.secondary.persistence.existingClaim }} # 添加 else if 语句
- name: data
persistentVolumeClaim:
claimName: {{ tpl .Values.secondary.persistence.existingClaim . }}
{{- else }}
..
|
创建 localPv
这里我们手动创建 两个pv
& pvc
,因为我们部署的是主程集群 primary
& secondary
多需要进行对应数据的持久化,并本地将其绑定在了节点 mn105
& mn106
上进行使用。
创建 StorageClass & pv 资源
对应 部署 yaml 文件如下所示,示例文件中分别创建了 localPv 的 StorageClass
资源对象,并将对应卷绑定策略设置为了 Immediate
立即绑定。如果使用的是 WaitForFirstConsumer
模式的话,是指原本实时发生的 pvc 和 pv 的绑定过程,被延迟到对应 Pod 第一次调度的时候在调度器中进行,详情请查阅此 文档。
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
|
cat > local-pv.yaml << EOF
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: Immediate # Immediate or WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: mariadb-primary-pv-local
labels:
role: primary
spec:
capacity:
storage: 100Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-storage
local:
path: /data/k8s/localpv/mariadb-master
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- mn105
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: mariadb-secondary-pv-local
labels:
role: secondary
spec:
capacity:
storage: 100Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-storage
local:
path: /data/k8s/localpv/mariadb-slave
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- mn106
EOF
kubectl apply -f ./local-pv.yaml # 执行资源对象的创建
storageclass.storage.k8s.io/local-storage created
persistentvolume/mariadb-primary-pv-local created
persistentvolume/mariadb-secondary-pv-local created
kubectl get pv|grep Available
mariadb-primary-pv-local 100Gi RWO Retain Available local-storage 32s
mariadb-secondary-pv-local 100Gi RWO Retain Available local-storage 32s
|
创建 localPv 指定文件夹
注意: localPv 创建时指定的文件夹,不会自己去创建。当pod调度时发现对应绑定的文件夹不存在时,会导致 pod 无法正常被调度。
mn105 节点
1
|
mkdir -p /data/k8s/localpv/mariadb-master
|
mn106节点
1
|
mkdir -p /data/k8s/localpv/mariadb-slave
|
创建 localPv pvc
资源对象
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
|
kubectl create ns mariadb # 创建部署命名空间
cat > local-pvc.yaml << EOF
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: mariadb-primary-pvc-local
namespace: mariadb
labels:
type: local
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Gi
storageClassName: local-storage
selector:
matchLabels:
role: primary
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: mariadb-secondary-pvc-local
namespace: mariadb
labels:
type: local
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Gi
storageClassName: local-storage
selector:
matchLabels:
role: secondary
EOF
kubectl apply -f ./local-pvc.yaml # 创建资源
persistentvolumeclaim/mariadb-primary-pvc-local created
persistentvolumeclaim/mariadb-secondary-pvc-local created
|

helm 部署对应资源
创建 prod-values.yaml 部署文件
可以使用如下命令进行查看默认的 values.yaml
配置文件
1
|
helm show values bitnami/mariadb > values.yaml
|
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
cat > prod-values.yaml << EOF
architecture: replication
auth:
rootPassword: "123456" # root 密码
database: ancun # 初始化添加的 数据库
username: "ancun"
password: "123456"
replicationUser: replicator
replicationPassword: "123456"
primary:
replicaCount: 1
configuration: |-
[mysqld]
skip-name-resolve
explicit_defaults_for_timestamp
basedir=/opt/bitnami/mariadb
plugin_dir=/opt/bitnami/mariadb/plugin
port=3306
socket=/opt/bitnami/mariadb/tmp/mysql.sock
tmpdir=/opt/bitnami/mariadb/tmp
max_allowed_packet=16M
bind-address=0.0.0.0
pid-file=/opt/bitnami/mariadb/tmp/mysqld.pid
log-error=/opt/bitnami/mariadb/logs/mysqld.log
character-set-server=UTF8
collation-server=utf8_general_ci
[client]
port=3306
socket=/opt/bitnami/mariadb/tmp/mysql.sock
default-character-set=UTF8
plugin_dir=/opt/bitnami/mariadb/plugin
[manager]
port=3306
socket=/opt/bitnami/mariadb/tmp/mysql.sock
pid-file=/opt/bitnami/mariadb/tmp/mysqld.pid
resources:
limits:
memory: 8000Mi
cpu: 2000m
requests:
memory: 4000Mi
cpu: 1000m
livenessProbe:
enabled: true
initialDelaySeconds: 120
periodSeconds: 10
timeoutSeconds: 1
failureThreshold: 3
successThreshold: 1
readinessProbe:
enabled: true
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 1
failureThreshold: 3
successThreshold: 1
extraFlags: "--max-connect-errors=1000 --max_connections=155"
extraEnvVars:
- name: TZ
value: "Asia/Shanghai"
persistence:
enabled: true
existingClaim: mariadb-primary-pvc-local
accessModes:
- ReadWriteOnce
size: 100Gi
service:
type: NodePort
port: 3306
secondary:
replicaCount: 1
configuration: |-
[mysqld]
skip-name-resolve
explicit_defaults_for_timestamp
basedir=/opt/bitnami/mariadb
port=3306
socket=/opt/bitnami/mariadb/tmp/mysql.sock
tmpdir=/opt/bitnami/mariadb/tmp
max_allowed_packet=16M
bind-address=0.0.0.0
pid-file=/opt/bitnami/mariadb/tmp/mysqld.pid
log-error=/opt/bitnami/mariadb/logs/mysqld.log
character-set-server=UTF8
collation-server=utf8_general_ci
[client]
port=3306
socket=/opt/bitnami/mariadb/tmp/mysql.sock
default-character-set=UTF8
[manager]
port=3306
socket=/opt/bitnami/mariadb/tmp/mysql.sock
pid-file=/opt/bitnami/mariadb/tmp/mysqld.pid
resources:
limits:
memory: 8000Mi
cpu: 2000m
requests:
memory: 4000Mi
cpu: 1000m
livenessProbe:
enabled: true
initialDelaySeconds: 120
periodSeconds: 10
timeoutSeconds: 1
failureThreshold: 3
successThreshold: 1
readinessProbe:
enabled: true
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 1
failureThreshold: 3
successThreshold: 1
extraFlags: "--max-connect-errors=1000 --max_connections=155"
extraEnvVars:
- name: TZ
value: "Asia/Shanghai"
persistence:
enabled: true
existingClaim: mariadb-secondary-pvc-local
accessModes:
- ReadWriteOnce
size: 100Gi
service:
type: NodePort
port: 3306
metrics:
enabled: false
image:
registry: docker.io
repository: bitnami/mysqld-exporter
tag: 0.12.1-debian-10-r444
pullPolicy: IfNotPresent
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9104"
resources:
limits:
memory: 256Mi
cpu: 100m
requests:
memory: 256Mi
cpu: 100m
serviceMonitor:
enabled: true
interval: 30s
EOF
|
执行应用的部署
1
2
3
4
|
ls
local-pvc.yaml local-pv.yaml mariadb mariadb-9.3.12.tgz prod-values.yaml
helm upgrade --install mariadb -f ./prod-values.yaml -n mariadb ./mariadb/
|

这里部署后,需要注意一下,在从库中默认是只读的,root 除外
。为了进行验证我们可以进入 从库
容器查看一下对应进程的 args

获取外部连接地址
在 helm 部署文件中,我们把对应 service 资源类型设置为了 NodePort
。外部连接的话,只需要获取到对应随机的端口号,组合集群中任意节点ip进行连接即可。
获取 NodePort 端口号
1
2
3
4
|
kubectl get svc -n mariadb
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mariadb-primary NodePort 10.101.91.176 <none> 3306:31011/TCP 3h12m
mariadb-secondary NodePort 10.97.222.104 <none> 3306:31848/TCP 3h12m
|


安装后的测试
测试主从复制
这里测试使用的用户均已 root
用户进行
在主中创建数据库,查看 slave 这边是否有对应同步

在主中对应数据库创建表,查看 slave 这边是否有对应同步
1
2
3
|
use testing;
create table test_tb (id int);
|

上面测试输出结果,可以看到正常进行了同步
slave 端只读
此次测试在 slave
端进行,并使用 helm 文件中创建的用户 ancun
进行
1
2
3
4
5
6
7
8
|
mysql -uancun -p
show databases;
use ancun;
create table test_tb (id int);
ERROR 1290 (HY000): The MariaDB server is running with the --read-only option so it cannot execute this statement
|

参考文档及链接
https://github.com/bitnami/charts/tree/master/bitnami/mariadb/#installing-the-chart
https://github.com/bitnami/bitnami-docker-mariadb/issues/174
总结
主从集群部署完毕后,这里还有两个问题需要提及和记录一下,第一个
: 由于使用的是 localPv 并做了节点亲和,pod 使用对应 localpv 的 pvc
进行数据卷挂载时,将会 继承
其亲和调度策略。如果这时对应 primary(master)
节点主机出现 down 机,主从集群将会被破坏且无法使用 kubernetes 调度策略实现 pod 自恢复
,在生产环境中 有条件
的话,这里建议是进行使用分布式存储,可满足 pod 调度在 任意
节点 那种。第二个
: 由于 localPv 使用的是对应主机中的 磁盘目录
进行挂载,如果此时磁盘出现损坏,同样会导致集群被破坏,且 数据可能丢失问题
,建议做好定期的数据备份,并对 对应磁盘使用 raid
去提高磁盘稳定和可靠性。