首页 > 数据库 >k8s部署MySQL主从数据库

k8s部署MySQL主从数据库

时间:2022-09-20 10:48:30浏览次数:109  
标签:name MySQL yaml xtrabackup master mysql k8s root 主从

参考:https://kubernetes.io/zh-cn/docs/tasks/run-application/run-replicated-stateful-application/

我的测试集群

root@master:~/mysql# kubectl get nodes -owide
NAME     STATUS   ROLES                  AGE    VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
master   Ready    control-plane,master   136d   v1.23.4   192.168.0.101   <none>        Ubuntu 20.04.4 LTS   5.15.0-46-generic   docker://20.10.12
node1    Ready    <none>                 136d   v1.23.4   192.168.0.102   <none>        Ubuntu 20.04.4 LTS   5.15.0-46-generic   docker://20.10.12
node2    Ready    <none>                 136d   v1.23.4   192.168.0.103   <none>        Ubuntu 20.04.4 LTS   5.15.0-46-generic   docker://20.10.12

1、创建PV

root@master:~/mysql# cat persistentVolume.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: example-mysql-pv
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Delete
  storageClassName: local-storage
  local:
    path: /data/svr/projects/mysql
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - node1
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: example-mysql-pv-2
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Delete
  storageClassName: local-storage
  local:
    path: /data/svr/projects/mysql2
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - node1
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: example-mysql-pv-3
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Delete
  storageClassName: local-storage
  local:
    path: /data/svr/projects/mysql3
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - node1
root@master:~/mysql# kubectl apply -f persistentVolume.yaml

2、创建sc

root@master:~/mysql# cat storageclass.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
root@master:~/mysql# kubectl apply -f storageclass.yaml

3、创建ns

root@master:~/mysql# cat mysql-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: mysql
  labels:
    app: mysql
root@master:~/mysql# kubectl apply -f mysql-namespace.yaml

4、创建一个cm

root@master:~/mysql# cat mysql-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql
  namespace: mysql
  labels:
    app: mysql
data:
  master.cnf: |
    # 主库配置
    [mysqld]
    log-bin=mysqllog
    skip-name-resolve
  slave.cnf: |
    # 从库配置
    [mysqld]
    super-read-only
    skip-name-resolve
    log-bin=mysql-bin
    replicate-ignore-db=mysql
root@master:~/mysql# kubectl apply -f mysql-configmap.yaml

5、创建secret

root@master:~/mysql# cat 05-mysql-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: mysql-secret
  namespace: mysql
  labels:
    app: mysql
type: Opaque
data:
  password: MTIzNDU2 # echo -n "123456" | base64
root@master:~/mysql# kubectl apply -f mysql-secret.yaml

6、创建service

root@master:~/mysql# cat mysql-service.yaml
# 为 StatefulSet 成员提供稳定的 DNS 表项的无头服务(Headless Service)
apiVersion: v1
kind: Service
metadata:
  name: mysql
  namespace: mysql
  labels:
    app: mysql
spec:
  ports:
  - name: mysql
    port: 3306
  clusterIP: None
  selector:
    app: mysql
---
# 用于连接到任一 MySQL 实例执行读操作的客户端服务
# 对于写操作,你必须连接到主服务器:mysql-0.mysql
apiVersion: v1
kind: Service
metadata:
  name: mysql-read
  namespace: mysql
  labels:
    app: mysql
spec:
  ports:
  - name: mysql
    port: 3306
  selector:
    app: mysql
root@master:~/mysql# kubectl apply -f mysql-service.yaml

7、创建statefulset

root@master:~/mysql# cat mysql-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
  namespace: mysql
  labels:
    app: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  serviceName: mysql
  replicas: 2
  template:
    metadata:
      labels:
        app: mysql
    spec:
      initContainers:
      - name: init-mysql
        image: mysql:5.7
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: password
        command:
        - bash
        - "-c"
        - |
          set -ex
          # 基于 Pod 序号生成 MySQL 服务器的 ID。
          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
          ordinal=${BASH_REMATCH[1]}
          echo [mysqld] > /mnt/conf.d/server-id.cnf
          # # 添加偏移量以避免使用 server-id=0 这一保留值。由于 server-id 不能为 0,因此给 ID 加 100 来避开它
          echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
          # 如果 Pod 的序号为 0,说明它是 Master 节点,从 ConfigMap 里把 Master 的配置文件拷贝到 /mnt/conf.d 目录下
          # 否则,拷贝 ConfigMap 里的 Slave 的配置文件
          if [[ $ordinal == 0  ]]; then
            cp /mnt/config-map/master.cnf /mnt/conf.d
          else
            cp /mnt/config-map/slave.cnf /mnt/conf.d
          fi
        volumeMounts:
        - name: conf
          mountPath: /mnt/conf.d
        - name: config-map
          mountPath: /mnt/config-map
      - name: clone-mysql
        #image: gcr.io/google-samples/xtrabackup:1.0
        image: registry.cn-shenzhen.aliyuncs.com/jbjb/csi:xtrabackup-1.0
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: password
        command:
        - bash
        - "-c"
        - |
          set -ex
          # 拷贝操作只需要在第一次启动时进行,所以数据已经存在则跳过
          [[ -d /var/lib/mysql/mysql ]] && exit 0
          # Master 节点(序号为 )不需要这个操作,跳过主实例(序号索引 0)的克隆。
          [[ $(hostname) =~ -([0-9]+)$ ]] || exit 1
          ordinal=${BASH_REMATCH[1]}
          [[ $ordinal == 0 ]] && exit
          # 从原来的对等节点克隆数据。使用 ncat 指令,远程地从前一个节点拷贝数据到本地
          ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql
          # 准备备份。执行 --prepare,这样拷贝来的数据就可以用作恢复了
          xtrabackup --prepare --target-dir=/var/lib/mysql
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
          subPath: mysql
        - name: conf
          mountPath: /etc/mysql/conf.d
      containers:
      - name: mysql
        image: mysql:5.7
        env:
#        - name: MYSQL_ALLOW_EMPTY_PASSWORD
#          value: "1"
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: password
        ports:
        - name: mysql
          containerPort: 3306
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
          subPath: mysql
        - name: conf
          mountPath: /etc/mysql/conf.d
        resources:
          requests:
            cpu: 500m
            memory: 0.5Gi
        livenessProbe:
          exec:
            command: ["mysqladmin", "ping", "-uroot", "-p${MYSQL_ROOT_PASSWORD}"]
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
        readinessProbe:
          exec:
            command: ["mysqladmin", "ping", "-uroot", "-p${MYSQL_ROOT_PASSWORD}"]
          initialDelaySeconds: 5
          periodSeconds: 2
          timeoutSeconds: 1
      - name: xtrabackup
        image: registry.cn-shenzhen.aliyuncs.com/jbjb/csi:xtrabackup-1.0
        ports:
        - name: xtrabackup
          containerPort: 3307
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: password
        command:
        - bash
        - "-c"
        - |
          set -ex
          cd /var/lib/mysql
          # 从备份信息文件里读取 MASTER_LOG_FILE 和 MASTER_LOG_POS 这 2 个字段的值,用来拼装集群初始化 SQL
          if [[ -f xtrabackup_slave_info ]]; then
            # 如果 xtrabackup_slave_info 文件存在,说明这个备份数据来自于另一个 Slave 节点
            # 这种情况下,XtraBackup 工具在备份的时候,就已经在这个文件里自动生成了 "CHANGE MASTER TO" SQL 语句
            # 所以,只需要把这个文件重命名为 change_master_to.sql.in,后面直接使用即可
            mv xtrabackup_slave_info change_master_to.sql.in
            # 所以,也就用不着 xtrabackup_binlog_info 了
            rm -f xtrabackup_binlog_info
          elif [[ -f xtrabackup_binlog_info ]]; then
            # 如果只是存在 xtrabackup_binlog_info 文件,说明备份来自于 Master 节点,就需要解析这个备份信息文件,读取所需的两个字段的值
            [[ $(cat xtrabackup_binlog_info) =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1
            rm xtrabackup_binlog_info
            # 把两个字段的值拼装成 SQL,写入 change_master_to.sql.in 文件
            echo "CHANGE MASTER TO MASTER_LOG_FILE='${BASH_REMATCH[1]}',\
                  MASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in
          fi
          # 如果存在 change_master_to.sql.in,就意味着需要做集群初始化工作
          if [[ -f change_master_to.sql.in ]]; then
            # 但一定要先等 MySQL 容器启动之后才能进行下一步连接 MySQL 的操作
            echo "Waiting for mysqld to be ready(accepting connections)"
            until mysql -h 127.0.0.1 -uroot -p${MYSQL_ROOT_PASSWORD} -e "SELECT 1"; do sleep 1; done
            echo "Initializing replication from clone position"
            # 将文件 change_master_to.sql.in 改个名字
            # 防止这个 Container 重启的时候,因为又找到了 change_master_to.sql.in,从而重复执行一遍初始化流程
            mv change_master_to.sql.in change_master_to.sql.orig
            # 使用 change_master_to.sql.orig 的内容,也就是前面拼装的 SQL,组成一个完整的初始化和启动 Slave 的 SQL 语句
            mysql -h 127.0.0.1 -uroot -p${MYSQL_ROOT_PASSWORD} << EOF
          $(< change_master_to.sql.orig),
            MASTER_HOST='mysql-0.mysql.mysql',
            MASTER_USER='root',
            MASTER_PASSWORD='${MYSQL_ROOT_PASSWORD}',
            MASTER_CONNECT_RETRY=10;
          START SLAVE;
          EOF
          fi
          # 使用 ncat 监听 3307 端口。
          # 它的作用是,在收到传输请求的时候,直接执行 xtrabackup --backup 命令,备份 MySQL 的数据并发送给请求者
          exec ncat --listen --keep-open --send-only --max-conns=1 3307 -c \
            "xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1 --user=root --password=${MYSQL_ROOT_PASSWORD}"
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
          subPath: mysql
        - name: conf
          mountPath: /etc/mysql/conf.d
      volumes:
      - name: conf
        emptyDir: {}
      - name: config-map
        configMap:
          name: mysql
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes:
      - "ReadWriteOnce"
      storageClassName: local-storage
      resources:
        requests:
          storage: 5Gi
root@master:~/mysql# kubectl apply -f mysql-statefulset.yaml

8、验证

root@master:~/mysql# kubectl get all -n mysql
NAME          READY   STATUS    RESTARTS   AGE
pod/mysql-0   2/2     Running   0          21d
pod/mysql-1   2/2     Running   0          21d

NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
service/mysql        ClusterIP   None             <none>        3306/TCP   25d
service/mysql-read   ClusterIP   10.108.100.108   <none>        3306/TCP   25d

NAME                     READY   AGE
statefulset.apps/mysql   2/2     21d
root@master:~# kubectl get pv -o wide
NAME                 CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                 STORAGECLASS    REASON   AGE   VOLUMEMODE
example-mysql-pv     5Gi        RWO            Delete           Bound       mysql/data-mysql-0    local-storage            25d   Filesystem
example-mysql-pv-2   5Gi        RWO            Delete           Bound       mysql/data-mysql-1    local-storage            25d   Filesystem
example-mysql-pv-3   5Gi        RWO            Delete           Available                         local-storage            25d   Filesystem

标签:name,MySQL,yaml,xtrabackup,master,mysql,k8s,root,主从
From: https://www.cnblogs.com/likaifei/p/16710181.html

相关文章

  • k8s pv与pvc持久化存储(静态与动态)
    k8spv与pvc持久化存储(静态与动态)PersistenVolume(PV):对存储资源创建和使用的抽象,使得存储作为集群中的资源管理PV分为静态和动态,动态能够自动创建PV•PersistentVolumeC......
  • 14 张图详解 Zookeeper + Kafka on K8S 环境部署
    转载自:https://www.cnblogs.com/liugp/p/16706192.html一、概述ApacheZooKeeper 是一个集中式服务,用于维护配置信息、命名、提供分布式同步和提供组服务,ZooKeeper致......
  • k8s 容器自动重启 错误 代码
    参考文章https://betterprogramming.pub/understanding-docker-container-exit-codes-5ee79a1d58f6ExitCodesCommonexitcodesassociatedwithdockercontainersar......
  • delete语句嵌套-mysql
    需求:我需要从tableA之中找到name字段的Filter的记录,得到此记录的id,然后根据id删除tableA中的该条记录;--但是我使用如下xql语句的时候deletefromtableAwhereidin(s......
  • Java学习-第一部分-第三阶段-第三节:MySQL基础
    零基础学MySQL笔记目录:(https://www.cnblogs.com/wenjie2000/p/16378441.html)一个问题淘宝网,京东、微信,抖音都有各自的功能,那么当我们退出系统的时候,下次再访问时,为什......
  • MySQL实现备份案例(2)
    案例1:MySQL8.0实现数据库冷备份和还原10.0.0.10--MySQL8.0#停止数据库[[email protected]]#systemctlstopmysqld.service#备份数据[root@CentOS8~]#scp-......
  • mysql忘记密码找回
     Windows下如果MySQL密码忘记了root密码导致无法登录,如下图所示,   这个时候怎么办,只能重置root密码了。1.打开任务管理器查看MySql服务是否启动,如果已启动则先......
  • MySQL实现备份(1)
    基础知识:备份类型:完全备份和部分备份冷备份、热备份、温备份温备份适用于:myisam热备份适用于:innodb物理备份和逻辑备份完全备份和部分备份完全备份:备份所......
  • 大家都在用MySQL count(*)统计总数,到底有什么问题?
    在日常开发工作中,我经常会遇到需要统计总数的场景,比如:统计订单总数、统计用户总数等。一般我们会使用MySQL的count函数进行统计,但是随着数据量逐渐增大,统计耗时也越来越长......
  • mysql 在insert时防止出现主键冲突错误的方法
    在mysql中插入数据的时候常常因为主键存在而冲突报错,下面有两个解决方法:1、在insert语句中添加ignore关键字,如:insertignoreintotable(id,name)values('1','usern......