在K8s集群中搭建Mysql主从集群

在k8中搭建Mysql集群,通过statefulset进行Pod部署,使用configMap指定不同的配置文件,使用secret指定Mysql密码,使用storageClass进行数据的持久化存储,下面为本次案例的环境介绍:

k8s集群版本:1.23.5
持久化存储:nfs
mysql版本:5.7.42

1、创建命名空间

[root@master mysql-cluster]# cat namespace.yaml 
apiVersion: v1
kind: Namespace
metadata:
  name: mysql-cluster1

2、创建Secret

`注意使用-n,否则会有换行符`
[root@node-1 ~]# echo -n "123456" | base64
MTIzNDU2
[root@node-1 ~]# echo -n "root" | base64
cm9vdA==

[root@master mysql-cluster]# cat secret.yaml 
apiVersion: v1
kind: Secret
metadata:
  name: mysql-secret
  namespace: mysql-cluster1
type: Opaque
data:
  mysql-root-username: cm9vdAo=
  mysql-root-password: MTIzNDU2Cg==
  
  
[root@master mysql-cluster]# kubectl apply -f secret.yaml 
secret/mysql-secret created


[root@master mysql-cluster]# kubectl get secret -n mysql-cluster1
NAME                  TYPE                                  DATA   AGE
default-token-wrr22   kubernetes.io/service-account-token   3      6m6s
mysql-secret          Opaque                                2      21s

3、创建动态存储

[root@master mysql-cluster]# cat storageClass.yaml 
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: mysql-cluster-storage
provisioner: nfs.csi.k8s.io
volumeBindingMode: Immediate
parameters:
  server: 192.168.253.21
  share: /nfsdata/mysql-cluster1

4、创建configmap

[root@master mysql-cluster]# cat cluster-config.map 
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-cluster-config
  namespace: mysql-cluster1
data:
  master.cnf: |
    [mysqld]

    log_bin=mysql-bin
    server-id=1
    gtid_mode=on
    enforce_gtid_consistency=1

  slave.cnf: |
    [mysqld]

    log_bin=mysql-bin
    server-id=2
    gtid_mode=on
    enforce_gtid_consistency=1

5、创建headless service

[root@master mysql-cluster]# cat cluster-headlessService.yaml 
apiVersion: v1
kind: Service
metadata:
  name: mysql-headless
  namespace: mysql-cluster1
  labels:
    app: mysql-headless
spec:
  ports:
  - name: mysql-headless
    port: 3306
  clusterIP: None
  selector:
    app: mysql-cluster       # 必须匹配statefulset创建的Pod的标签
    
[root@master mysql-cluster]# kubectl apply -f cluster-headlessService.yaml 
service/mysql-headless created

[root@master mysql-cluster]# kubectl apply -f cluster-statefulset.yaml 
statefulset.apps/mysql created

6、创建statefulset

[root@master mysql-cluster]# cat cluster-statefulset.yaml 
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
  namespace: mysql-cluster1
  labels:
    app: mysql-cluster
spec:
  serviceName: mysql-headless       # 必须匹配headless service的名称
  replicas: 2
  selector:
    matchLabels:
      app: mysql-cluster
  template:
    metadata:
      labels:
        app: mysql-cluster
    spec:
    # 创建初始化容器,根据pod的名称匹配configmap的key,如果为0,拷贝master.cnf到/mnt/conf.d;否则拷贝slave.cnf到/mnt/conf.d
      initContainers:
      - name: init-mysql
        image: busybox
        imagePullPolicy: IfNotPresent
        command:
        - sh
        - -c
        - |
          if [[ "$(hostname)" =~ -0$ ]];then
            cp /mnt/config/master.cnf /mnt/conf.d/server.cnf
          else
            cp /mnt/config/slave.cnf /mnt/conf.d/server.cnf
          fi
        volumeMounts:
        - name: cluster-config
          mountPath: /mnt/config
        # 经过if判断后,cluster-config-dir中已经有了具体的配置文件
        - name: cluster-config-dir
          mountPath: /mnt/conf.d
      containers:
      - name: mysql
        image: mysql:5.7.42
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 3306
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: mysql-root-password
        # 在初始化容器中,将cluster-config-dir中的文件挂载到/etc/mysql/conf.d/目录
        volumeMounts:
        - name: cluster-config-dir
          mountPath: /etc/mysql/conf.d/
        - name: mysql-cluster-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: cluster-config
        configMap:
          name: mysql-cluster-config
      - name: cluster-config-dir
        emptyDir: {}
  volumeClaimTemplates:
  - metadata:
      name: mysql-cluster-storage
    spec:
      accessModes:
      - ReadWriteMany
      resources:
        requests:
          storage: 1Gi
      storageClassName: mysql-cluster-storage
      
[root@master mysql-cluster]# kubectl get pods -n mysql-cluster1
NAME      READY   STATUS    RESTARTS   AGE
mysql-0   1/1     Running   0          10s
mysql-1   1/1     Running   0          6s

7、Mysql主从配置

主库设置

[root@master mysql-cluster]# kubectl exec -it mysql-0 -n mysql-cluster1 -- /bin/bash
Defaulted container "mysql" out of: mysql, init-mysql (init)
bash-4.2# mysql -uroot -p123456


mysql> grant all on *.* to slave@'%' identified by "xhy@@0310";
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

从库设置
从库指定主库的host时,需要使用Pod的DNS,因为Pod的IP不是稳定的,随着Pod的重启可能会发生变化,通过statefulset创建的Pod的DNS是稳定的,Pod的DNS命名规则是<Pod-name>.<service-name>.<namespace-name>.svc.cluster.local

[root@master mysql-cluster]# kubectl exec -it mysql-1 -n mysql-cluster1 -- /bin/bash
Defaulted container "mysql" out of: mysql, init-mysql (init)
bash-4.2# mysql -uroot -p123456
mysql> CHANGE MASTER TO
    ->   MASTER_HOST='mysql-0.mysql-headless.mysql-cluster1.svc.cluster.local',
    ->   MASTER_USER='slave',
    ->   MASTER_PASSWORD='xhy@@0310',
    ->   MASTER_PORT=3306,
    ->   MASTER_AUTO_POSITION=1;
Query OK, 0 rows affected, 2 warnings (0.01 sec)

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

# 查看主从状态
mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: mysql-0.mysql-headless.mysql-cluster1.svc.cluster.local
                  Master_User: slave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000003
          Read_Master_Log_Pos: 627
               Relay_Log_File: mysql-1-relay-bin.000003
                Relay_Log_Pos: 840
        Relay_Master_Log_File: mysql-bin.000003
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

看到Slave_IO_Running和Slave_SQL_Running都为YES,表示主从集群成功

一、前置条件 1、已经有K8S环境,可参考K8S安装手册; 2、需要安装Helm,可以参考Helm安装手册。 二、创建MySQL主从部署 1、创建mysql-operator 通过mysql-operator可以方便的管理MySQL集群,它的安装方式可以参考mysql-operator安装手册。 2、创建MySQL主从部署 在K8S搭建MySQL主从,一般使用MySQL官方提供的镜像,可以使用以下命令创建MySQL主从部署。 ``` helm install mysql-replication --set primary.mysqlRootPassword=root,secondary.mysqlRootPassword=root custom-mysql ``` 执行上述命令后,会在K8S中创建mysql-replication的部署实例。 三、验证MySQL主从 1、查看MySQL主从状态 可以使用以下命令查看MySQL主从状态。 ``` kubectl exec -it mysql-replication-0 -- bash -c "mysql -uroot -p'root' -e 'SHOW MASTER STATUS\G'" kubectl exec -it mysql-replication-1 -- bash -c "mysql -uroot -p'root' -e 'SHOW SLAVE STATUS\G'" ``` 2、测试主从复制 可以使用以下命令在MySQL主节点上创建一个测试表。 ``` kubectl exec -it mysql-replication-0 -- bash -c "mysql -uroot -p'root' -e 'CREATE DATABASE test;USE test;CREATE TABLE t1 (id int primary key,name varchar(20));INSERT INTO t1 VALUES (1,\"test\");'" ``` 然后在MySQL从节点上查询该表。 ``` kubectl exec -it mysql-replication-1 -- bash -c "mysql -uroot -p'root' -e 'SELECT * FROM test.t1;'" ``` 如果查询结果和主节点上的结果一致,则说明主从复制已经成功。 四、总结 通过上述步骤,我们可以在K8S搭建MySQL主从部署,并且验证了主从复制的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值