kubernetes1.28部署mysql5.7主从同步,使用Nfs制作持久卷存储,适用于centos7/9操作系统,
kubernetes中部署mysql5.7主从
博主的集群规模为3台机器实验环境
[root@master ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
master Ready control-plane 89d v1.28.2
node-1 Ready <none> 88d v1.28.2
node-2 Ready <none> 88d v1.28.2
部署流程:
1.准备nfs服务制作pv实现数据库的持久化
2.创建master和slave的配置文件,并定义为ConfigMap
3.定义secret用于保存mysql的用户名和密码,master与slave共用一个secret即可
4.创建StatefulSet用于创建mysql服务
5.定义service用于暴露mysql服务
6.在k8s集群中进入mysql配置mysql的主从同步
1.创建Namespace名称空间
[root@master ~]# mkdir master-slave/namespace
[root@master ~]# cd master-slave/namespace
[root@master namespace]# vim mysql-namespace.yml
apiVersion: v1
kind: Namespace
metadata:
name: mysql
[root@master namespace]# kubectl apply -f mysql-namespace.yml
namespace/mysql created
[root@master namespace]# kubectl get ns
NAME STATUS AGE
mysql Active 2s
2.利用NFS创建pv
2.1.所有机器安装nfs并配置共享目录
[root@master ~]# yum install -y nfs-utils rpcbind
[root@master ~]# mkdir /mnt/master/data -p
[root@master ~]# mkdir /mnt/slave/data -p
[root@master ~]# vim /etc/exports
/mnt/master/data 192.168.209.0/24(rw,no_root_squash)
/mnt/slave/data 192.168.209.0/24(rw,no_root_squash)
[root@master ~]# systemctl start rpcbind
[root@master ~]# systemctl start nfs
[root@master ~]# systemctl enable nfs rpcbind
2.2.创建pv与pvc
pv
[root@master ~]# cd master-slave/
[root@master master-slave]# mkdir mysql-pv
[root@master master-slave]# cd mysql-pv/
[root@master mysql-pv]# vim mysql-pv.yml
apiVersion: v1
kind: PersistentVolume
metadata:
name: master-pv
labels:
type: master-nfs
namespace: mysql
spec:
storageClassName: nfs
nfs:
server: 192.168.209.131
path: "/mnt/master/data"
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: slave-pv
labels:
type: slave-nfs
namespace: mysql
spec:
storageClassName: nfs
nfs:
server: 192.168.209.131
path: "/mnt/slave/data"
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
[root@master mysql-pv]# kubectl apply -f mysql-pv.yml
persistentvolume/master-pv created
persistentvolume/slave-pv created
[root@master mysql-pv]# kubectl get pv -n mysql
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
master-pv 5Gi RWX Retain Available nfs 4s
slave-pv 5Gi RWX Retain Available nfs
pvc
[root@master mysql-pv]# ls
mysql-pv.yml
[root@master mysql-pv]# vim mysql-pvc.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: master-pvc
namespace: mysql
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
storageClassName: nfs
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: slave-pvc
namespace: mysql
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
storageClassName: nfs
[root@master mysql-pv]# kubectl apply -f mysql-pvc.yml
persistentvolumeclaim/master-pvc created
persistentvolumeclaim/slave-pvc created
[root@master mysql-pv]# kubectl get pvc -n mysql
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
master-pvc Bound master-pv 5Gi RWX nfs 5s
slave-pvc Bound slave-pv 5Gi RWX nfs 5s
2.3创建secret用于保存mysql的用户名和密码,主从使用相同的 Secret 配置.
[root@master ~]# cd master-slave/
[root@master master-slave]# ls
mysql-pv namespace
[root@master master-slave]# mkdir secret
[root@master master-slave]# cd secret/
[root@master secret]# echo -n 'Mysql@123!' | base64
TXlzcWxAMTIzIQ==
[root@master secret]# vim mysql-secret.yml
apiVersion: v1
data:
password: TXlzcWxAMTIzIQ==
kind: Secret
metadata:
annotations:
name: mysql-server
namespace: mysql
type: Opaque
[root@master secret]# kubectl apply -f mysql-secret.yml
secret/mysql-server created
[root@master secret]# kubectl get secret -n mysql
NAME TYPE DATA AGE
mysql-server Opaque 1 34s
2.4分别创建master与slave的配置文件,并定义为ConfigMap
master
[root@master master-slave]# mkdir master-conf
[root@master master-slave]# cd master-conf/
[root@master master-conf]# cat mysql-master-conf.yml
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-master-conf
namespace: mysql
data:
my.cnf: |
[mysqld]
skip-host-cache
skip-name-resolve
datadir = /var/lib/mysql
socket = /var/run/mysqld/mysqld.sock
pid-file = /var/run/mysqld/mysqld.pid
user = mysql
server-id = 1
log-bin = master-bin
binlog-format = row
[client]
socket = /var/run/mysqld/mysqld.sock
[root@master master-conf]# kubectl apply -f mysql-master-conf.yml
configmap/mysql-master-conf created
[root@master master-conf]# kubectl get cm -n mysql
NAME DATA AGE
mysql-master-conf 1 6s
slave
[root@master master-slave]# mkdir slave-conf
[root@master master-conf]# cd ../slave-conf/
[root@master slave-conf]# cat mysql-slave-conf.yml
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-slave-conf
namespace: mysql
data:
my.cnf: |
[mysqld]
skip-host-cache
skip-name-resolve
datadir = /var/lib/mysql
socket = /var/run/mysqld/mysqld.sock
pid-file = /var/run/mysqld/mysqld.pid
user = mysql
server-id = 2
log-bin = slave-bin
binlog-format = row
[client]
socket = /var/run/mysqld/mysqld.sock
[root@master slave-conf]# kubectl apply -f mysql-slave-conf.yml
configmap/mysql-slave-conf created
[root@master slave-conf]# kubectl get cm -n mysql
NAME DATA AGE
mysql-master-conf 1 3m33s
mysql-slave-conf 1 5s
3.创建Service用于暴露mysql服务。
创建Headless service与NodePort两种服务方式,分别用于在集群内部访问MySQL和集群外部访问mysql.
headless server 主要用于集群内部访问,从库指定主库ip地址的时候可以指定headless 为主节点pod分配的DNS的名字格式为:
$<Pod Name>.$<service name>.$<namespace name>.svc.cluster.local
3.1创建master的Headless service
[root@master master-slave]# mkdir service/{master,slave} -p
[root@master master]# vim master-headless-svc.yml
apiVersion: v1
kind: Service
metadata:
name: master-headless-svc
labels:
app: mysql-master
namespace: mysql
spec:
ports:
- port: 3306
clusterIP: None
selector:
app: mysql-master #选择与带有mysql-master这个标签的pod关联
[root@master master]# kubectl apply -f master-headless-svc.yml
[root@master master]# kubectl get svc -n mysql
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
master-headless-svc ClusterIP None <none> 3306/TCP 6s
3.2创建slave的Headless service
[root@master service]# cd slave/
[root@master slave]# ls
[root@master slave]# vim slave-headless-svc.yml
apiVersion: v1
kind: Service
metadata:
name: slave-headless-svc
labels:
app: mysql-slave
namespace: mysql
spec:
ports:
- port: 3306
clusterIP: None
selector:
app: mysql-slave #选择与带有mysql-slave这个标签的pod关联
[root@master slave]# kubectl apply -f slave-headless-svc.yml
service/slave-headless-svc created
[root@master slave]# kubectl get svc -n mysql
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
master-headless-svc ClusterIP None <none> 3306/TCP 2m55s
slave-headless-svc ClusterIP None <none> 3306/TCP 10s
3.3为master创建NodePort的暴露方式实现集群外部访问
方便通过指定node的ip和暴露的端口通过集群外部或者在node节点上面访问主节点
[root@master slave]# cd ../master/
[root@master master]# vim master-nodeport-svc.yml
apiVersion: v1
kind: Service
metadata:
name: mysql-nodeport-svc
namespace: mysql
spec:
type: NodePort
ports:
- port: 3306
nodePort: 30001
targetPort: 3306
selector:
app: mysql-master
[root@master master]# kubectl apply -f master-nodeport-svc.yml
service/mysql-nodeport-svc created
[root@master master]# kubectl get svc -n mysql
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
master-headless-svc ClusterIP None <none> 3306/TCP 7m40s
mysql-nodeport-svc NodePort 10.96.22.112 <none> 3306:30001/TCP 5s
slave-headless-svc ClusterIP None <none> 3306/TCP 4m55s
4.创建StatefulSet资源用于管理mysql主从pod服务
master
[root@master master-slave]# mkdir mysql-server
[root@master master-slave]# cd mysql-server/
[root@master mysql-server]# vim master-statefulset.yml
kind: StatefulSet
apiVersion: apps/v1
metadata:
name: mysql-master
labels:
app: mysql-master
namespace: mysql
spec:
replicas: 1
serviceName: master-headless-svc
selector:
matchLabels:
app: mysql-master
template:
metadata:
labels:
app: mysql-master
spec:
volumes:
- name: data-time
hostPath:
path: /etc/localtime
type: ''
- name: config
configMap:
name: mysql-master-conf
- name: data
persistentVolumeClaim:
claimName: master-pvc
containers:
- name: mysql-master
image: registry.cn-hangzhou.aliyuncs.com/testpm-k8s/mysql:5.7
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-server
key: password
resources:
limits:
cpu: '2'
memory: 4Gi
requests:
cpu: 100m
memory: 100Mi
volumeMounts:
- name: data-time
mountPath: /etc/localtime
- name: data
mountPath: /var/lib/mysql
- name: config
readOnly: true
mountPath: /etc/mysql/conf.d/
[root@master mysql-server]# kubectl apply -f master-statefulset.yml
[root@master mysql-server]# kubectl get pod -n mysql
NAME READY STATUS RESTARTS AGE
mysql-master-0 1/1 Running 0 38s
slave
为从库pod配置pod的反亲和性,避免与主节点运行在一个node节点上面。
[root@master mysql-server]# cp master-statefulset.yml slave-statefulset.yml
[root@master mysql-server]# vim slave-statefulset.yml
kind: StatefulSet
apiVersion: apps/v1
metadata:
name: mysql-slave
labels:
app: mysql-slave
namespace: mysql
spec:
replicas: 1
serviceName: slave-headless-svc
selector:
matchLabels:
app: mysql-slave
template:
metadata:
labels:
app: mysql-slave
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- mysql-master
topologyKey: "kubernetes.io/hostname"
volumes:
- name: data-time
hostPath:
path: /etc/localtime
type: ''
- name: config
configMap:
name: mysql-slave-conf
- name: data
persistentVolumeClaim:
claimName: slave-pvc
containers:
- name: mysql-slave
image: registry.cn-hangzhou.aliyuncs.com/testpm-k8s/mysql:5.7
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-server
key: password
resources:
limits:
cpu: '2'
memory: 4Gi
requests:
cpu: 100m
memory: 100Mi
volumeMounts:
- name: data-time
mountPath: /etc/localtime
- name: data
mountPath: /var/lib/mysql
- name: config
readOnly: true
mountPath: /etc/mysql/conf.d/
[root@master mysql-server]# kubectl apply -f slave-statefulset.yml
[root@master mysql-server]# kubectl get pod -n mysql -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mysql-master-0 1/1 Running 0 128m 10.244.1.7 node-2 <none> <none>
mysql-slave-0 1/1 Running 0 117m 10.244.2.18 node-1 <none> <none>
测试mysql登陆是否正常
[root@master mysql-server]# kubectl exec -it -n mysql mysql-master-0 -- /bin/bash
root@mysql-master-0:/# mysql -uroot -p'Mysql@123!'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.34-log MySQL Community Server (GPL)
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
5.配置主从同步
master
创建同步时使用的用户和密码
[root@master mysql-server]# kubectl exec -it mysql-master-0 -n mysql -- mysql -uroot -p'Mysql@123!'
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' identified by 'Mysql@12345!';
Query OK, 0 rows affected, 1 warning (0.01 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.02 sec)
mysql> show master status\G #获取bin-log日志文件和位置点
*************************** 1. row ***************************
File: master-bin.000004
Position: 589
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)
mysql>
slave操作
[root@master mysql-server]# kubectl exec -it mysql-slave-0 -n mysql -- mysql -uroot -p'Mysql@123!'
mysql> CHANGE MASTER TO master_host='mysql-master-0.master-headless-svc.mysql.svc.cluster.local',master_port=3306,master_user='repl',master_password='Mysql@12345!',master_log_file='master-bin.000004',master_
og_pos=589;
Query OK, 0 rows affected, 2 warnings (0.12 sec)
mysql> start slave;
Query OK, 0 rows affected (0.03 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: mysql-master-0.master-headless-svc.mysql.svc.cluster.local
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-bin.000004
Read_Master_Log_Pos: 589
Relay_Log_File: mysql-slave-0-relay-bin.000005
Relay_Log_Pos: 321
Relay_Master_Log_File: master-bin.000005
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 154
Relay_Log_Space: 751
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: 33d9d7f5-ef81-11ef-ae3c-7eb2d43e1e0d
Master_Info_File: /var/lib/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
#都为yes时表示成功!
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
参数解释
master_host: 同步主节点的 DNS,使用 mysql-master-0.master-headless-svc.mysql.svc.cluster.local
master_port: 主节点服务端口
master_user: 主节点创建的同步用户
master_password: 主节点创建的同步用户的密码
master_log_file: 主库 Show Master 状态时,指定的binlog日志文件
master_log_pos: 主库 Show Master 状态时, binlog日志文件位置点
测试
[root@master mysql-server]# kubectl exec -it mysql-master-0 -n mysql -- mysql -uroot -p'Mysql@123!'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.34-log MySQL Community Server (GPL)
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> create database db1;
Query OK, 1 row affected (0.01 sec)
mysql> \q
Bye
[root@master mysql-server]# kubectl exec -it mysql-slave-0 -n mysql -- mysql -uroot -p'Mysql@123!'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 5
Server version: 5.7.34-log MySQL Community Server (GPL)
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| db1 |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.17 sec)
mysql>
6.通过nodeport暴露的端口登陆
[root@master ~]# kubectl get pod -n mysql -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mysql-master-0 1/1 Running 0 75m 10.244.1.12 node-2 <none> <none>
mysql-slave-0 1/1 Running 0 74m 10.244.2.22 node-1 <none> <none>
#master节点运行在node2上面,那就指定node2的ip地址进行登陆
[root@master ~]# mysql -uroot -h192.168.209.133 -P30001 -p'Mysql@123!'
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.7.34-log MySQL Community Server (GPL)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| db1 |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.02 sec)
MySQL [(none)]>
到此结束,有不对的地方或者更好的方式欢迎大家指教。。。