运维实战案例 容器部分 使用Statefulset部署MySQL主从集群

运维实战案例 容器部分 使用Statefulset部署MySQL主从集群

需求分析

  • 一主多从模式只能有一个写入端, 多个查询端需要能负载均衡和健康检查
  • 如何保证MASTER端恒定且连接方式不飘逸
  • 解决主从机配置文件不同的问题
  • 每台机器的配置文件中server-id不同, 如何用同一个配置文件模板为所有从机分配各自的配置文件
  • 如何进行数据的持久化

解决思路

  • 根据StatefulSet控制器的特点, 上一个Pod报告就绪后, 才会开始生成下一个Pod, 因此我们可以断定, 第一个就绪的Pod一定是MASTER端, 且如果MASTER端初始化出现问题, 整个后续都不会继续.

  • 根据Headless Service的特点, 首先启动的Pod一定对应的是mysql-0.mysql, 后续会被PodDNS自行补全, 因此MASTER端的唯一性和确定性也可以保证

  • 所有Pod又可以放入一个新的svc中管理, 通过ClusterIP实现负载均衡和健康检查

  • 之前我们学过, 在容器创建前依旧会有Init 容器存在, 且顺序执行, 将配置文件的放入和处理操作在Init 容器中执行, 既可以保证容器创建时有符合要求的配置文件, Init 容器本身顺序执行且必须执行完毕的特性也保证了只要逻辑得当, 生成的配置文件一定是符合要求的

  • 两个Service实现读写分离

  • 借助Init 容器实现对配置文件的操作

  • StatefulSet控制器实现有序建立和定位

  • PVC动态生成PV来实现数据持久化

image-20210516195845129

参考教程

注意事项

  • 实验采用的设置都不是生产环境下的设置, 并不具备生产环境的安全性
  • 重点在于构建的思路

ConfigMap部分

  • 通过ConfigMap实现将配置模板挂入Pod中的目的
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql
  labels:
    app: mysql
data:
  master.cnf: |
    # Apply this config only on the master.
    [mysqld]
    log-bin    
  slave.cnf: |
    # Apply this config only on slaves.
    [mysqld]
    super-read-only    

可以看到master.cnfslave.cnf被分别存放, slave.cnf中包括super-read-only参数来实现只读, 这一步是为了提供my.cnf的内容

Service部分

  • 创建读写分离所需要的两个服务
  • 写服务为Headless Service
# Headless service for stable DNS entries of StatefulSet members.
apiVersion: v1
kind: Service
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  ports:
  - name: mysql
    port: 3306
  clusterIP: None
  selector:
    app: mysql
---
# Client service for connecting to any MySQL instance for reads.
# For writes, you must instead connect to the master: mysql-0.mysql.
apiVersion: v1
kind: Service
metadata:
  name: mysql-read
  labels:
    app: mysql
spec:
  ports:
  - name: mysql
    port: 3306
  selector:
    app: mysql

无头服务为每个Pod提供一个DNS解析, 因为服务名为 mysql, 所以可以通过在同一 Kubernetes 集群和名字中的任何其他 Pod 内解析 <Pod 名称>.mysql 来访问 Pod, 又因为MASTER端永远第一个被建立, 因此其解析地址永远为mysql-0.mysql

Read相关的服务就是普通的服务, 通过ClusterIP提供负载均衡和健康检查

StatefulSet控制器部分

也是本实验最重要的部分, 可以说以下内容都是通过StatefulSet的特性来实现的

  • 配置文件中server-id的有序递增
  • Pod创建顺序的有序化
  • 新生成的Pod从上一个Pod复制数据的实现
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  serviceName: mysql
  replicas: 3
  template:
    metadata:
      labels:
        app: mysql
    spec:
      initContainers:
      - name: init-mysql
        image: mysql:5.7
        command:
        - bash
        - "-c"
        - |
          set -ex
          # Generate mysql server-id from pod ordinal index.
          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
          ordinal=${BASH_REMATCH[1]}
          echo [mysqld] > /mnt/conf.d/server-id.cnf
          # Add an offset to avoid reserved server-id=0 value.
          echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
          # Copy appropriate conf.d files from config-map to emptyDir.
          if [[ $ordinal -eq 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
        command:
        - bash
        - "-c"
        - |
          set -ex
          # Skip the clone if data already exists.
          [[ -d /var/lib/mysql/mysql ]] && 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值