k8s中实现mysql主备

news2024/11/26 18:38:01

文章目录

  • 一、k8s中实现mysql主备
    • 1.1 环境信息
    • 1.2 部署nfs-provisioner
      • 1.2.1 安装nfs
      • 1.2.2 部署nfs-provisioner
    • 1.3 安装mysql
    • 1.4 备库上查看是否同步

一、k8s中实现mysql主备

1.1 环境信息

机器操作系统ipmysql版本k8s版本storageClass
master1CentOS7.8192.168.0.20mysql5.7.421.27.1nfs
node1CentOS7.8192.168.0.21mysql5.7.421.27.1nfs

1.2 部署nfs-provisioner

说明:
  使用statefulSet部署双机MySQL,所以需要提供storageClass,这里使用nfs-provisioner。

1.2.1 安装nfs

这里nfs安装在node1节点上
mkdir /mnt/nfs && sh nfs_install.sh /mnt/nfs 192.168.0.0/24

nfs_install.sh

#!/bin/bash

### How to install it? ###
### 安装nfs-server,需要两个参数:1、挂载点  2、允许访问nfs-server的网段 ###

### How to use it? ###
### Client节点`yum -y install nfs-utils rpcbind`,然后挂载nfs-server目录到本地 ###
### 如:echo "192.168.0.20:/mnt/data01  /mnt/data01  nfs  defaults  0 0" >> /etc/fstab && mount -a ###

mount_point=$1
subnet=$2

function nfs_server() {
  systemctl stop firewalld
  systemctl disable firewalld
  setenforce 0
  sed -i 's/^SELINUX.*/SELINUX\=disabled/' /etc/selinux/config
  yum -y install nfs-utils rpcbind
  mkdir -p $mount_point
  echo "$mount_point ${subnet}(rw,sync,no_root_squash)" >> /etc/exports
  systemctl start rpcbind && systemctl enable rpcbind
  systemctl restart nfs-server && systemctl enable nfs-server
  chown -R nfsnobody:nfsnobody $mount_point
}

function usage() {
echo "Require 2 argument: [mount_point] [subnet]
eg: sh $0 /mnt/data01 192.168.10.0/24"
}

declare -i arg_nums
arg_nums=$#
if [ $arg_nums -eq 2 ];then
  nfs_server
else
  usage
  exit 1
fi

1.2.2 部署nfs-provisioner

master1节点上执行 kubectl create namespace devops && kubectl apply -f nfs-provisioner.yaml

nfs-provisioner.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-provisioner
  namespace: devops
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: nfs-provisioner-runner
rules:
- apiGroups: [""]
  resources: ["persistentvolumes"]
  verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
  resources: ["persistentvolumeclaims"]
  verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
  resources: ["storageclasses"]
  verbs: ["get", "list", "watch"]
- apiGroups: [""]
  resources: ["events"]
  verbs: ["create", "update", "patch"]
- apiGroups: [""]
  resources: ["services", "endpoints"]
  verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: run-nfs-provisioner
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: nfs-provisioner-runner
subjects:
- kind: ServiceAccount
  name: nfs-provisioner
  namespace: devops
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: leader-locking-nfs-provisioner
  namespace: devops
rules:
- apiGroups: [""]
  resources: ["endpoints"]
  verbs: ["get", "list", "watch", "create", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: leader-locking-nfs-provisioner
  namespace: devops
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: leader-locking-nfs-provisioner
subjects:
- kind: ServiceAccount
  name: nfs-provisioner
  namespace: devops
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-provisioner
  namespace: devops
spec:
  selector:
    matchLabels:
       app: nfs-provisioner
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-provisioner
    spec:
      serviceAccountName: nfs-provisioner
      containers:
        - name: nfs-provisioner
          image: docker.io/gmoney23/nfs-client-provisioner:latest
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: example.com/nfs
            - name: NFS_SERVER
              value: 192.168.0.21
            - name: NFS_PATH
              value: /mnt/nfs
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.0.21
            path: /mnt/nfs
---
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: nfs
provisioner: example.com/nfs
#reclaimPolicy: Retain

1.3 安装mysql

kubectl apply -f deploy.yaml

deploy.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: mysql
  labels:
    app: mysql

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql
  namespace: mysql
  labels:
    app: mysql
data:
  master.cnf: |
    [client]
    default-character-set=utf8mb4
    [mysql]
    default-character-set=utf8mb4
    [mysqld]
    max_connections=2000
    default-time_zone='+8:00'
    character-set-server=utf8mb4
    collation-server=utf8mb4_unicode_ci
    innodb_buffer_pool_size=536870912
    datadir=/var/lib/mysql
    pid-file=/var/run/mysqld/mysqld.pid
    log-error=/var/lib/mysql/error.log
    log-bin=mysqllog
    skip-name-resolve
    lower-case-table-names=1
    log_bin_trust_function_creators=1
  slave.cnf: |
    [client]
    default-character-set=utf8mb4
    [mysql]
    default-character-set=utf8mb4
    [mysqld]
    max_connections=2000
    default-time_zone='+8:00'
    character-set-server=utf8mb4
    collation-server=utf8mb4_unicode_ci
    innodb_buffer_pool_size=536870912
    datadir=/var/lib/mysql
    pid-file=/var/run/mysqld/mysqld.pid
    log-error=/var/lib/mysql/error.log
    super-read-only
    skip-name-resolve
    log-bin=mysql-bin
    lower-case-table-names=1
    log_bin_trust_function_creators=1

---
apiVersion: v1
kind: Secret
metadata:
  name: mysql-secret
  namespace: mysql
  labels:
    app: mysql
type: Opaque
data:
  password: TnNiZzExMTEqQCE= # Nsbg1111*@!
  replicationUser: Y29weQ== #copy
  replicationPassword: TnNiZzExMTEqQCE= #Nsbg1111*@!

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

---
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: docker.io/library/mysql:5.7.42
        command: 
        - bash
        - "-c"
        - |
          set -ex
          #从pod的hostname中通过正则获取序号,如果没有截取到就退出程序
          ordinal=`cat /etc/hostname | awk -F"-" '{print $2}'` || exit 1
          #将serverId输入到对应的配置文件中,路径可以随意(与之后的对应上就行),但是文件名不能换
          echo [mysqld] > /etc/mysql/conf.d/server-id.cnf
          # 由于server-id不能为0,因此给ID加100来避开它
          server_id=$((100 + $ordinal))
          echo "server-id=$server_id" >> /etc/mysql/conf.d/server-id.cnf
          if [[ ${ordinal} -eq 0 ]]; then
            # 如果Pod的序号为0,说明它是Master节点,从ConfigMap里把Master的配置文件拷贝到/mnt/conf.d目录下
            cp /mnt/config-map/master.cnf /etc/mysql/conf.d
          else
            # 否则,拷贝ConfigMap里的Slave的配置文件
            cp /mnt/config-map/slave.cnf /etc/mysql/conf.d
          fi
          echo "ending..."
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: password
        - name: MYSQL_REPLICATION_USER
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: replicationUser
        - name: MYSQL_REPLICATION_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: replicationPassword
        volumeMounts:
        - name: conf
          mountPath: /etc/mysql/conf.d
        - name: config-map
          mountPath: /mnt/config-map
      containers:
      - name: mysql
        image: docker.io/library/mysql:5.7.42
        lifecycle:
         postStart:
          exec:
            command:
            - bash
            - "-c"
            - |
              set -ex
              cd /var/lib/mysql
              #查看是否存在名为mysqlInitOk的文件,我们自己生产的标识文件,防止重复初始化集群
              if [ ! -f mysqlInitOk ]; then
                echo "Waiting for mysqld to be ready(accepting connections)"
                #执行一条mysql的命令,查看mysql是否初始化完毕,如果没有就反复执行直到可以运行
                  #until mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e "use mysql;SELECT 1;"; do sleep 1; done
                  sleep 5s
                  echo "Initialize ready"
                  #判断是master还是slave
                  pod_seq=`cat /etc/hostname | awk -F"-" '{print $2}'`
                  if [ $pod_seq -eq 0 ];then
                    #创建主从账户
                  mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e "create user '${MYSQL_REPLICATION_USER}'@'%' identified by '${MYSQL_REPLICATION_PASSWORD}';"
                  #设置权限
                  mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e "grant replication slave on *.* to '${MYSQL_REPLICATION_USER}'@'%' with grant option;"
                  #刷新配置
                  mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e "flush privileges;"
                  #初始化master
                  mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e "reset master;"
                else
                  #设置slave连接的master
                  #mysql-0.mysql.mysql的由来{pod-name}.{service-name}.{namespace}
                  mysql -e \
                  "change master to master_host='mysql-0.mysql.mysql',master_port=3306, \
                  master_user='${MYSQL_REPLICATION_USER}',master_password='${MYSQL_REPLICATION_PASSWORD}', \
                  master_log_file='mysqllog.000001',master_log_pos=154;"
                  #重置slave
                  mysql -e "reset slave;"
                  #开始同步
                  mysql -e "start slave;"
                  #改成只读模式
                  mysql -e "set global read_only=1;"
                fi
                #运行完毕创建标识文件,防止重复初始化集群
                touch mysqlInitOk
              fi
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: password
        - name: MYSQL_REPLICATION_USER
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: replicationUser
        - name: MYSQL_REPLICATION_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: replicationPassword
        ports:
        - name: mysql
          containerPort: 3306
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
        - name: conf
          mountPath: /etc/mysql/conf.d
        - name: run-mysql
          mountPath: /var/run/mysql
        resources:
          requests:
            cpu: 500m
            memory: 2Gi
        #设置存活探针
        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: 10
          timeoutSeconds: 1
      volumes:
      - name: config-map
        configMap:
          name: mysql
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes:
      - ReadWriteOnce
      storageClassName: nfs
      resources:
        requests:
          storage: 5Gi
  - metadata: 
      name: conf
    spec:
      accessModes:
      - ReadWriteOnce
      storageClassName: nfs
      resources:
        requests:
          storage: 100Mi
  - metadata: 
      name: run-mysql
    spec:
      accessModes:
      - ReadWriteOnce
      storageClassName: nfs
      resources:
        requests:
          storage: 100Mi

1.4 备库上查看是否同步

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1173208.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Xbox漫游指南

以Xbox series s为例 开机启动 用手柄连接,注意两颗电池要方向相反插入,虽然里面2个插槽长一样; Xbox APP极其难用,放弃,直接用手柄连接 转区 只需要一个空U盘,大小不限制,格式化为NTPS格式…

【51单片机】DS1302时钟(学习笔记)

一、DS1302时钟 1、DS1302介绍 DS1302是由美国DALLAS公司推出的具有涓细电流充电能力的低功耗实时时钟芯片。它可以对年、月、日、周、时、分、秒进行计时,且具有闰年补偿等多种功能 RTC(Real Time Clock):实时时钟,是一种集成电路&#xf…

基础课22——云服务(SaaS、Pass、laas、AIaas)

1.云服务概念和类型 云服务是一种基于互联网的计算模式,通过云计算技术将计算、存储、网络等资源以服务的形式提供给用户,用户可以通过网络按需使用这些资源,无需购买、安装和维护硬件设备。云服务具有灵活扩展、按需使用、随时随地访问等优…

Spring-IOC容器深度剖析详解

🎈个人公众号:🎈 :✨✨✨ 可为编程✨ 🍟🍟 🔑个人信条:🔑 知足知不足 有为有不为 为与不为皆为可为🌵 🍉本篇简介:🍉 本篇由表及里分析Spring-IOC容器始末,如…

LeetCode算法心得——找到冠军(反向推理)

大家好,我是晴天学长,今天的周赛第二题,需要的小伙伴可以关注支持一下哦!后续会继续更新的。 1) .找到冠军 一场比赛中共有 n 支队伍,按从 0 到 n - 1 编号。每支队伍也是 有向无环图(DAG) 上的…

Technology Strategy Pattern 学习笔记2-Creating the Strategy-World Context

Creating the Strategy-World Context 1 PESTEL 1.1 从6个方案看外部 PoliticalEconomicSocialTechnologicalEnvironmentalLegal 1.2 参考URL https://zhuanlan.zhihu.com/p/192522082https://www.docin.com/p-449396129.htmlhttps://blog.csdn.net/xiaoyw71/article/deta…

发现一款PDF转换成翻页电子书的网站

​随着科技的发展,电子书越来越受到人们的喜爱。而PDF格式的文件也越来越多地被人们使用。那么,如何将PDF文件转换成翻页电子书呢?今天就为大家推荐一款好用的PDF转翻页电子书网站。 一、网站介绍 这款网站是一款非常实用的在线转换工具&…

7.spark sql编程

概述 spark 版本为 3.2.4,注意 RDD 转 DataFrame 的代码出现的问题及解决方案 本文目标如下: RDD ,Datasets,DataFrames 之间的区别入门 SparkSession创建 DataFramesDataFrame 操作编程方式运行 sql 查询创建 DatasetsDataFrames 与 RDDs 互相转换 使用…

Navicat连接mysql 8.0.35 2059错误解决办法

这2天在家重装电脑,顺便把mysql升级8.0,安装完成后,用Navicat连接,报错2059,如下 网上查了一下, 【报错原因】mysql8.0 之前的版本中加密规则是 mysql_native_password,而 mysql8.0 之后的版本…

超越 GLIP! | RegionSpot: 识别一切区域,多模态融合的开放世界物体识别新方法

本文的主题是多模态融合和图文理解,文中提出了一种名为RegionSpot的新颖区域识别架构,旨在解决计算机视觉中的一个关键问题:理解无约束图像中的各个区域或patch的语义。这在开放世界目标检测等领域是一个具有挑战性的任务。 关于这一块&…

Vim快速插入常用代码模板

1 修改home目录下.vimrc 家目录中ls -a找到隐藏文件.vimrc 2 编辑.vimrc 输入i编辑&#xff0c;在尾巴插入代码&#xff0c;按:wq保存并退出。 noremap io i#include <stdio.h><Esc>o<Esc> noremap im iint main(int argc, char *argv[])<Esc> map …

使用自定义函数拟合辨识HPPC工况下的电池数据(适用于一阶RC、二阶RC等电池模型)

该程序可以离线辨识HPPC工况下的电池数据&#xff0c;只需要批量导入不同SOC所对应的脉冲电流电压数据&#xff0c;就可以瞬间获得SOC为[100% 90% 80% 70% 60% 50% 40% 30% 20% 10% 0%]的所有电池参数,迅速得到参数辨识的结果并具有更高的精度&#xff0c;可以很大程度上降低参…

第7章-使用统计方法进行变量有效性测试-7.1-假设检验

目录 女士品茶 假设检验 样本与总体 原假设与备择假设 检验法、拒绝域与检验统计量 显著性水平 决策方法——临界值法和p值&#xff08;p-value&#xff09;法 假设检验步骤 参考文献 假设检验&#xff0c;我们从女士品茶这个故事开始说起。希望这篇文章能给您带来极大…

三、操作系统

&#xff08;一&#xff09;概述 操作系统是管理整个系统的软、硬件资源的系统&#xff0c;既是人和硬件之间的一种接口&#xff0c;也是应用软件与硬件之间的接口。 &#xff08;二&#xff09;进程管理 1.进程的状态 进程的状态是操作系统对进程进行管理的时候设置的几种状…

CLion2022安装

1. CLion下载 地址&#xff1a;https://www.jetbrains.com.cn/clion/download/other.html 下载你需要的版本&#xff0c;这里以2022.2.4为例 之后获取到对应的安装包 2. 安装 1、双击运行安装包&#xff0c;next 2、选择安装路径&#xff0c;建议非系统盘&#xff0c;nex…

Jetpack:029-Jetpack中的网格布局

文章目录 1. 概念介绍2. 使用方法3. 代码与效果3.1 示例代码3.2 运行效果 4. 内容总结 我们在上一章回中介绍了Jetpack中Card相关的内容&#xff0c;本章回中主要介 网格布局。闲话休提&#xff0c;让我们一起Talk Android Jetpack吧&#xff01; 1. 概念介绍 我们在本章回中…

第九章《搞懂算法:决策树是怎么回事》笔记

决策树算法是机器学习中很经典的一个算法&#xff0c;它既可以作为分类算法&#xff0c;也可以作为回归算法。 9.1 典型的决策树是什么样的 决策树算法是依据“分而治之”的思想&#xff0c;每次根据某属性的值对样本进行分类&#xff0c;然后传递给下个属性继续进行分类判断…

【CMU15445】Fall 2019, Project 3: Query Execution 实验记录

目录 实验准备实验测试Task 1: CREATING A CATALOG TABLE SQL 执行是由数据库解析器转化为一个由多个 executor 组成的 Query Plan 来完成的&#xff0c;本实验选择了火山模型来完成 query execution&#xff0c;这一次的 project 就是实现各种 exeutor&#xff0c;从而可以通过…

2014年亚太杯APMCM数学建模大赛C题公共基础课教师专业化培养方式研究求解全过程文档及程序

2014年亚太杯APMCM数学建模大赛 C题 公共基础课教师专业化培养方式研究 原题再现 近年来&#xff0c;世界基础工业、信息产业、服务业的跨越式发展引发了大量人才需求&#xff0c;导致了职业教育的飞速发展&#xff0c;除原有专科层次高等职业教育院校外&#xff0c;大量普通…