ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

Kubernetes系列-部署MySQL主从(k8s)

2022-05-01 12:01:39  阅读:203  来源: 互联网

标签:name Kubernetes MySQL cnf Master mysql master k8s root


Kubernetes系列-部署MySQL主从

 

分析需要解决的问题,制定解决思路:

1.启动顺序:Master 的Pod 必须先于 Slave 的 Pod 起来;
2.如果某个Pod挂掉了,应该自动重新启动一个Pod,这个新建的Pod应该沿用原来的数据;
3.Master 与 Slave 的配置文件不同,特别是server_id;
4.Master 与 Slave 在服务启动之后还需要执行一些命令,它们也不一样,具体为:
    1)Master需要执行授权命令,授权的用户名和密码希望用户自己来配置,而不是写死;
    2)Slave需要执行CHANGE MASTER命令,需要知道Master的地址。

解决以上问题,那么项目就可以成功部署,下面让我们来一个个解决:

  1. 关于启动顺序问题。这个好说,利用 StatefulSet 轻松就能解决,它的一个特点就是会将所有的Pod副本进行编号,然后按照编号顺序一个一个的启动,Pod命名规则为 statefulsetName-N 其中N为编号,从0开始。例如,StatefulSet名称为 mysql ,那么第一个启动的Pod名称必为 mysql-0 。
  2. 关于重建Pod后的数据问题。因为重建的新Pod不一定还在原来的Node上,因此,想用原来的数据必须要使用分布式或共享Volume。我们可以使用NFS或其它的分布式存储来解决此问题。另外,如果几个副本(例如mysql-1,mysql-2,mysql-3)同时重建,必须保证新建立的 mysql-1 仍然沿用原来的 mysql-1 的数据。这个问题我们可以使用PV和PVC来解决。
  3. 配置文件不同的问题。不考虑其他,就server_id不同的问题,我们可以利用容器启动前的initContainer来解决在每个容器启动前插入更改配置文件信息,还可以传入容器启动后执行的脚本文件
  4. 用户名和密码可以使用 Secret 传递进来。Master地址因为不是固定的,所以不建议使用IP地址,我们可以借助 Headless Service 加上 DNS 来解决。如果我们能传入Service的名称进来,那么就可以使用这种方式来与其它Pod进行通信:PodName.ServiceName 。例如,如果Service名称为mysqlsvc,那么master的DNS名称为 mysql-0.mysqlsvc ,这个名称是不会变化的。当Master完成授权工作后,Slave可通过授权帐号查询到binlog文件名及位置信息(注意授权时要给 replication client 权限才可以查询)。
  5. 此次部署是自己制作的镜像,你也可以通过已有镜像进行部署。

有了解决思路,下面开始部署项目。

构建initContainer镜像

1、编写MySQL配置文件

[root@master cnf]# cat my.cnf 
[mysqld]
log-bin   = binlog
server-id = 1
gtid_mode = on
enforce_gtid_consistency = 1
log_slave_updates   = 1 
pid-file    = /var/run/mysqld/mysqld.pid
socket      = /var/run/mysqld/mysqld.sock
datadir     = /var/lib/mysql
#log-error  = /var/log/mysql/error.log
# By default we only accept connections from localhost
#bind-address   = 127.0.0.1
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

2、编写initContainer执行脚本

[root@master cnf]# cat my.sh 
#!/bin/bash
pod_seq=`hostname | awk -F"-" '{print $2}'`
conf=/cnf
if [ $pod_seq -eq 0 ];then
    cp $conf/my.cnf /mysql
    cp $conf/init.sh /mysql
else
    id=$((pod_seq+1))
    sed -ri "/server/c server-id = $id" /mysql/my.cnf 
fi

3、编写postStart执行脚本

[root@master cnf]# cat init.sh 
#!/bin/bash
pod_seq=`echo $POD_NAME |awk -F"-" '{print $2}'`
while : ;do
    if [ $pod_seq -eq 0 ] ; then
        mysql -uroot -p$MYSQL_ROOT_PASSWORD -e "show databases" && mysql -uroot -p$MYSQL_ROOT_PASSWORD -e "grant replication slave on *.* to '$REPLIC_USER'@'%' identified by '$REPLIC_PASSWORD' && REPLIC_USER
        sleep 1
    else
        mysql -uroot -p$MYSQL_ROOT_PASSWORD -e "show databases" && mysql -uroot -p$MYSQL_ROOT_PASSWORD -e "change master to master_host='mysql-0.mysqlsvc',master_user='$REPLIC_USER',master_password='$REPLIC_PASSWORD',master_auto_position=1;" && mysql -uroot -p$MYSQL_ROOT_PASSWORD -e "start slave" && break 
        sleep 1
    fi
done

4、构建镜像及上传镜像

[root@master cnf]# cat Dockerfile 
FROM alpine
COPY my.cnf my.sh init.sh /cnf/
[root@master cnf]# docker build -t registry.cn-shenzhen.aliyuncs.com/jun-lin/my-cnf:[tag] .
[root@master cnf]# docker pull registry.cn-shenzhen.aliyuncs.com/jun-lin/my-cnf:[tag]

在Kubernetes中创建MySQL主从集群

  • 使用 secret 传入所有的用户名及密码
  • 使用 downwardAPI 获取 Pod 名称

编写yaml文件:

vim secret
---
apiVersion: v1
kind: Secret
metadata:
  name: mysql
  namespace: default
type: Opaque
data:
  root_pass: bGVlZG9u               # 用base64转码后的字符
  rep_user: c2xhdmU=
  rep_pass: c2xhdmVwYXNz

vim mysql
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: mysqlsvc
  replicas: 3
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      initContainers:
      - image: registry.cn-shenzhen.aliyuncs.com/jun-lin/my-cnf:v7
        name: cnf
        command: ["sh","/cnf/my.sh"]
        volumeMounts:
        - mountPath: /mysql
          name: conf-volume
      containers:
      - name: mysql
        image: mysql:5.7
        imagePullPolicy: IfNotPresent
        env:
        - name: SVC_NAME
          value: mysqlsvc               
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql
              key: root_pass
        - name: REPLIC_USER
          valueFrom:
            secretKeyRef:
              name: mysql
              key: rep_user
        - name: REPLIC_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql
              key: rep_pass
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        lifecycle:
          postStart:
            exec:
              command: ["sh","/etc/mysql/mysql.conf.d/init.sh"]
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: sql
          mountPath: /var/lib/mysql
        - name: conf-volume
          mountPath: /etc/mysql/mysql.conf.d
      volumes:
      - name: conf-volume
        nfs:
          server: 192.168.127.129
          path: "/conf"
  volumeClaimTemplates:
  - metadata:
      name: sql
    spec:
      storageClassName: mysql   #此处为你部署的SC
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi

---
apiVersion: v1
kind: Service
metadata:
  name: mysqlsvc
  labels:
    app: mysql
spec:
  selector:
    app: mysql
  clusterIP: None
  ports:
  - name: mysql
    port: 3306

pv
[root@master pv]# cat pv01.yaml 
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv01
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: mysql
  nfs:
    path: /mysql
    server: 192.168.127.129

 

这里使用的nfs挂载(省略)

检查是否部署成功

通过以上文件创建出集群,等一段时间后查看:

[root@master yaml]# kubectl get po
NAME      READY   STATUS    RESTARTS   AGE
mysql-0   1/1     Running   0          68s
mysql-1   1/1     Running   0          51s
mysql-2   1/1     Running   0          26s

随便连接一台Slave查看主从状态:

[root@master yaml]# kubectl exec -it mysql-1 bash
root@mysql-1:/# mysql -uroot -p$MYSQL_ROOT_PASSWORD -e "show slave status\G"
mysql: [Warning] Using a password on the command line interface can be insecure.
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: mysql-0.mysqlsvc
                  Master_User: slave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: binlog.000003
          Read_Master_Log_Pos: 478
               Relay_Log_File: mysql-1-relay-bin.000003
                Relay_Log_Pos: 685
        Relay_Master_Log_File: binlog.000003
             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: 478
              Relay_Log_Space: 3075591
              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: 58cd7b75-38f6-11eb-af61-da9f9717a2b4
             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: 58cd7b75-38f6-11eb-af61-da9f9717a2b4:1-6
            Executed_Gtid_Set: 58cd7b75-38f6-11eb-af61-da9f9717a2b4:1-6,
666af852-38f6-11eb-bd33-aeab33df8f07:1-5
                Auto_Position: 1
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version:

部署成功

标签:name,Kubernetes,MySQL,cnf,Master,mysql,master,k8s,root
来源: https://www.cnblogs.com/zjl-throb/p/16212494.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有