本文使用静态存储卷实现(非存储类),目的是比较简单易入门。
部署mysql5.7集群的请看这篇文章

软件版本
mysql8.0.18
xtrabackup8.0.9
该步可跳过,可直接使用作者现成镜像
FROM paigeeworld/centos7:latestMAINTAINER jstang <389634070@qq.com>RUN rpm --rebuilddb && \yum -y install wget hostname mariadb && \wget https://downloads.percona.com/downloads/Percona-XtraBackup-LATEST/Percona-XtraBackup-8.0.9/binary/redhat/7/x86_64/percona-xtrabackup-80-8.0.9-1.el7.x86_64.rpm && \yum -y localinstall percona-xtrabackup-80-8.0.9-1.el7.x86_64.rpmRUN rm percona-xtrabackup-80-8.0.9-1.el7.x86_64.rpm -rfEXPOSE 3307
这个是构建镜像和把镜像上传到作者的dockerHub的jstang账户上

1、准备NFS服务,查看NFS服务器IP为192.168.1.11,准备三个持久化磁盘(块)

[root@m-nfs~]# yum install nfs-utils
[root@m-nfs~]# mkdir -p /net/mysql-0 /net/mysql-1 /net/mysql-2
[root@m-nfs~]# ifconfig | head -2| tail -1|awk '{print $2}'
192.168.1.11 # 查看nfs服务器IP
[root@m-nfs~]# echo '/net/mysql-0 *(rw,no_root_squash)' >> /etc/exports
[root@m-nfs~]# echo '/net/mysql-1 *(rw,no_root_squash)' >> /etc/exports
[root@m-nfs~]# echo '/net/mysql-2 *(rw,no_root_squash)' >> /etc/exports
[root@m-nfs~]# systemctl restart nfs-server
[root@m-nfs~]# showmount -e 本机IP # 验证

2、创建三个持久卷(mysql-0、mysql-1、mysql-2)

  apiVersion: v1kind: PersistentVolumemetadata:name: pv-a|pv-b|pv-cspec:capacity:storage: 1GiaccessModes: - ReadWriteOnce- ReadOnlyMany#persistentVolumeReclaimPolicy: Retain # 当声明被释放,pv将保留(不清理和删除)persistentVolumeReclaimPolicy: Recycle # 当声明被释放,空间将回收再利用nfs:server: 192.168.1.11path: /net/mysql-0 | /net/mysql-1 | /net/mysql-2

3、创建configMap配置字典

apiVersion: v1
kind: ConfigMap
metadata:name: mysqllabels:app: mysql
data:master.cnf: |# Apply this config only on the master.[mysqld]log-binslave.cnf: |# Apply this config only on slaves.[mysqld]super-read-only

4、部署headless服务,有状态服务都需要,让服务旗下的Pod彼此发现

apiVersion: v1
kind: Service
metadata:name: mysql-headlesslabels:app: mysql
spec:ports:- name: mysqlport: 3306clusterIP: Noneselector:app: mysql

5. 部署SatefulSet应用

apiVersion: apps/v1
kind: StatefulSet
metadata:name: mysql-ss
spec: selector: matchLabels: app: mysql serviceName: mysql-headlessreplicas: 1template: metadata:labels:app: mysql spec:initContainers:- name: init-mysqlimage: mysql:8.0.18command:- bash- "-c"- |set ex# 从hostname中获取索引,比如(mysql-1)会获取(1)[[ `hostname` =~ -([0-9]+)$ ]] || exit 1ordinal=${BASH_REMATCH[1]}echo [mysqld] > /mnt/conf.d/server-id.cnf# 为了不让server-id=0而增加偏移量echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf# 拷贝对应的文件到/mnt/conf.d/文件夹中if [[ $ordinal -eq 0 ]]; thencp /mnt/config-map/master.cnf /mnt/conf.d/elsecp /mnt/config-map/slave.cnf /mnt/conf.d/fivolumeMounts:- name: confmountPath: /mnt/conf.d- name: config-mapmountPath: /mnt/config-map- name: clone-mysqlimage: jstang/xtrabackup:2.3command:- bash- "-c"- |set -ex# 整体意思:# 1.如果是主mysql中的xtrabackup,就不需要克隆自己了,直接退出# 2.如果是从mysql中的xtrabackup,先判断是否是第一次创建,因为第二次重启本地就有数据库,无需克隆。若是第一次创建(通过/var/lib/mysql/mysql文件是否存在判断),就需要克隆数据库到本地。# 如果有数据不必克隆数据,直接退出()[[ -d /var/lib/mysql/mysql ]] && exit 0# 如果是master数据也不必克隆[[ `hostname` =~ -([0-9]+)$ ]] || exit 1ordinal=${BASH_REMATCH[1]}[[ $ordinal -eq 0 ]] && exit 0# 从序列号比自己小一的数据库克隆数据,比如mysql-2会从mysql-1处克隆数据ncat --recv-only mysql-ss-$(($ordinal-1)).mysql-headless 3307 | xbstream -x -C /var/lib/mysql# 比较数据xtrabackup --prepare --target-dir=/var/lib/mysqlvolumeMounts:- name: datamountPath: /var/lib/mysqlsubPath: mysql- name: confmountPath: /etc/mysql/conf.dcontainers:- name: mysqlimage: mysql:8.0.18args: ["--default-authentication-plugin=mysql_native_password"]env:- name: MYSQL_ALLOW_EMPTY_PASSWORDvalue: "1"ports:- name: mysqlcontainerPort: 3306volumeMounts:- name: datamountPath: /var/lib/mysqlsubPath: mysql- name: confmountPath: /etc/mysql/conf.dresources:requests:cpu: 50mmemory: 50MilivenessProbe:exec:command: ["mysqladmin", "ping"]initialDelaySeconds: 30periodSeconds: 10timeoutSeconds: 5readinessProbe:exec:command: ["mysql", "-h", "127.0.0.1", "-e", "SELECT 1"]initialDelaySeconds: 5periodSeconds: 2timeoutSeconds: 1- name: xtrabackupimage: jstang/xtrabackup:2.3ports:- name: xtrabackupcontainerPort: 3307command:- bash- "-c"- |set -ex# 确定binlog 克隆数据位置(如果binlog存在的话).cd /var/lib/mysql# 如果存在该文件,则该xrabackup是从现有的从节点克隆出来的。if [[ -s xtrabackup_slave_info ]]; thenmv xtrabackup_slave_info change_master_to.sql.inrm -f xtrabackup_binlog_infoelif [[ -f xtrabackup_binlog_info ]]; then         [[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1rm xtrabackup_binlog_infoecho "CHANGE MASTER TO MASTER_LOG_FILE='${BASH_REMATCH[1]}',\MASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.infi     if [[ -f change_master_to.sql.in ]]; thenecho "Waiting for mysqld to be ready (accepting connections)"until mysql -h 127.0.0.1 -e "SELECT 1"; do sleep 1; doneecho "Initializing replication from clone position"mv change_master_to.sql.in change_master_to.sql.origmysql -h 127.0.0.1 <<EOF$(<change_master_to.sql.orig),MASTER_HOST='mysql-ss-0.mysql-headless',MASTER_USER='root',MASTER_PASSWORD='',MASTER_CONNECT_RETRY=10;START SLAVE;EOFfiexec ncat --listen --keep-open --send-only --max-conns=1 3307 -c \"xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1 --user=root"volumeMounts:- name: datamountPath: /var/lib/mysqlsubPath: mysql- name: confmountPath: /etc/mysql/conf.dresources:requests:cpu: 10mmemory: 10Mivolumes:- name: confemptyDir: {}- name: config-mapconfigMap:name: mysqlvolumeClaimTemplates:- metadata:name: dataspec:    accessModes:- ReadWriteOnceresources:requests:storage: 0.1Gi

5. 查看状态
5.1 容器运行情况

5.2 主从复制情况

6. 测试
6.1 mysql-0创建数据库

create database ui;
create table ui.user(name varchar(255));
insert into ui.user(name) values("jstang");

5.2 从数据库查数据(查到就成功了。)

select * from ui.user;