Blog

本文介绍一套可落地的 MySQL 高可用 架构,核心由四块拼在一起:

  • StatefulSet + 异步主从:固定 Pod 身份(mysql-0、mysql-1…),主库可写、从库只读,通过复制保持数据一致。
  • Ceph RBD 持久化:每个实例独占一块 RBD 卷,走块存储而非共享文件系统,更适合 InnoDB 的随机 IO 和崩溃恢复。
  • 故障自动转移:mysql-controller 持续探测主库健康;主 Pod 不可用或复制异常时,自动将从库提升为新主,并更新拓扑(ConfigMap / Service Endpoints),把切换时间压到秒级(1-2s)。
  • Gateway API TCPRoute:MySQL 走 3306/TCP,通过 TCPRoute 把集群外的流量(例如 MetalLB VIP + Envoy Gateway)转发到当前主库 Service,应用始终连同一个地址,无需感知背后哪台是主。

1. 拉取项目代码

git clone https://github.com/web-starbucket/k8s-script.git

2. 快速部署

先创建主备mysql kubectl apply -f mysql.yaml 《MySQL高可用 + Ceph RBD + 故障自动转移 + TCPRoute》文章正文配图 — STARBUCKET BLOG 《MySQL高可用 + Ceph RBD + 故障自动转移 + TCPRoute》文章正文配图(配图 2)— STARBUCKET BLOG

安装mysql控制器

kubectl apply -f mysql-controller.yaml

《MySQL高可用 + Ceph RBD + 故障自动转移 + TCPRoute》文章正文配图(配图 3)— STARBUCKET BLOG 《MySQL高可用 + Ceph RBD + 故障自动转移 + TCPRoute》文章正文配图(配图 4)— STARBUCKET BLOG

kubectl logs -f deploy/mysql-controller

《MySQL高可用 + Ceph RBD + 故障自动转移 + TCPRoute》文章正文配图(配图 5)— STARBUCKET BLOG

3. 测故障转移

# 宕掉当前主(例如 mysql-0)
kubectl delete pod mysql-0 --grace-period=0 --force
# 约 1–2s:升主 mysql-1

kubectl get cm mysql-topology -o jsonpath='{.data.primary-pod}{"\n"}'
kubectl get ep mysql

《MySQL高可用 + Ceph RBD + 故障自动转移 + TCPRoute》文章正文配图(配图 6)— STARBUCKET BLOG 《MySQL高可用 + Ceph RBD + 故障自动转移 + TCPRoute》文章正文配图(配图 7)— STARBUCKET BLOG

查看当前主库实列

SELECT @@hostname, @@read_only, @@super_read_only;

《MySQL高可用 + Ceph RBD + 故障自动转移 + TCPRoute》文章正文配图(配图 8)— STARBUCKET BLOG

4. 在线修改数据库账号密码

kubectl exec "$PRI" -c mysql -- mysql --protocol=SOCKET -uroot -p"$OLD" -e "
  ALTER USER 'root'@'localhost' IDENTIFIED BY 'remo@**123';
  ALTER USER 'root'@'%' IDENTIFIED BY 'remo@**123';
  ALTER USER 'root'@'127.0.0.1' IDENTIFIED BY 'remo@**123';
  ALTER USER 'repl'@'%' IDENTIFIED BY 'remo@**123';
  FLUSH PRIVILEGES;"


# 更新实际的从库
kubectl exec mysql-0 -c mysql -- mysql --protocol=SOCKET -uroot -p'remo@**123' -e "
  STOP REPLICA;
  CHANGE REPLICATION SOURCE TO SOURCE_PASSWORD='remo@**123';
  START REPLICA;"

kubectl patch secret mysql-auth --type merge -p '{"stringData":{
  "root-password":"remo@**123",
  "replication-password":"remo@**123"
}}'


kubectl rollout restart deploy/mysql-controller
kubectl rollout restart sts/mysql
kubectl logs -f deploy/mysql-controller

5. 删除残留从库pvc

查看使用

kubectl get pvc | grep mysql
kubectl get pod -l app=mysql -o wide
kubectl get sts mysql -o jsonpath='{.spec.replicas}{"\n"}'

删除未使用

kubectl delete pvc data-mysql-2 data-mysql-3

6. 注意

  • 从库也需开 log-bin + log_replica_updatesmysql.yaml 已配),否则升主后再挂回从库易缺事件

Comments & discussion

The first comment in each thread opens a topic. Signed-in readers can keep the conversation going under that topic.

No comments yet. Sign in to start a topic.

Start a new topic

Sign in to start a topic or join the discussion.