Kubernetes MySQL 主从集群:5分钟搭建数据永不丢失的「数据库兄弟连」

一、为什么要这么玩?

在 Kubernetes 这个「容器游乐场」里,传统数据库就像被宠坏的孩子:

  • 动不动就「我要固定名字!」(稳定标识)
  • 哭喊着「数据不能丢!」(持久存储)
  • 还要求「兄弟要整齐!」(有序扩缩容)

StatefulSet 就像贴心保姆,帮我们把这些熊孩子(MySQL)调教得服服帖帖!

二、架构图:兄弟连的「秘密基地」

+----------------+          +----------------+
|   MySQL 大哥   |          |   MySQL 二哥   |
|  (主节点)      |          |  (从节点)      |
+----------------+          +----------------+
      ▲                     ▲
      │                     │
+-----+-----+           +-----+-----+
|  DNS 路标           |       | 读请求分流器   |
|  (mysql-0.mysql)    |       |  (mysql-read)  |
+------------------+       +----------------+
      ▲                     ▲
      │                     │
+-----+-----+           +-----+-----+
| 本地硬盘仓库       |       | 本地硬盘仓库   |
|  (/data/mysql)     |       |  (/data/mysql2)|
+------------------+       +----------------+

在这里插入图片描述

三、完整配置:给熊孩子们的「家规」

1. 本地存储:秘密基地的选址

# 01-persistentVolume-1.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mysql-data-1
spec:
  capacity:
    storage: 15Gi
  accessModes:
  - ReadWriteOnce  # 独门独户,禁止合租
  local:
    path: /data/svr/mysql  # 仓库地址
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values: ["worker-node"]  # 固定在某个工人节点

2. 存储规则:仓库使用说明书

# 02-storageclass.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: local-storage
provisioner: kubernetes.io/no-provisioner  # 手动管理仓库
volumeBindingMode: WaitForFirstConsumer  # 等人来了再开门

3. 命名空间:熊孩子们的专属小区

# 03-mysql-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: mysql-world  # 小区名字
  labels:
    app: mysql-family  # 住户标签

4. 配置文件:兄弟俩的个性设定

# 04-mysql-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-settings
  namespace: mysql-world
data:
  master.cnf: |
    [mysqld]
    server-id=1  # 大哥身份证号
    log-bin=big-brother-bin  # 大哥的日记本
  slave.cnf: |
    [mysqld]
    server-id=2  # 二哥身份证号
    super-read-only  # 二哥只读模式

5. 密码保险箱:防止熊孩子乱改密码

# 05-mysql-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: mysql-secret
  namespace: mysql-world
type: Opaque
data:
  password: MTIzNDU2  # 123456 的加密版

6. 服务配置:兄弟俩的联系方式

# 06-mysql-services.yaml
apiVersion: v1
kind: Service
metadata:
  name: mysql
  namespace: mysql-world
spec:
  ports:
  - name: mysql-port
    port: 3306
  clusterIP: None  # 大哥专线,不接电话
  selector:
    app: mysql-family
---
apiVersion: v1
kind: Service
metadata:
  name: mysql-read
  namespace: mysql-world
spec:
  ports:
  - name: mysql-port
    port: 3306
  selector:
    app: mysql-family  # 二哥接电话

7. 兄弟连组建:StatefulSet 点兵

# 07-mysql-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql-brothers
  namespace: mysql-world
spec:
  serviceName: mysql  # 大哥的专线
  replicas: 2  # 1 大哥 + 1 二哥
  template:
    metadata:
      labels:
        app: mysql-family
    spec:
      containers:
      - name: mysql
        image: mysql:5.7  # 使用 MySQL 5.7 版本
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: password
        ports:
        - name: mysql-port
          containerPort: 3306
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql  # 仓库挂载点
        - name: config
          mountPath: /etc/mysql/conf.d  # 配置文件位置
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes:
      - "ReadWriteOnce"
      storageClassName: local-storage
      resources:
        requests:
          storage: 3Gi  # 每人 3G 仓库

四、部署流程:兄弟连的诞生

  1. 创建仓库
kubectl apply -f 01-persistentVolume-{1..3}.yaml
  1. 划小区
kubectl apply -f 03-mysql-namespace.yaml
  1. 发装备
kubectl apply -f 04-mysql-configmap.yaml
kubectl apply -f 05-mysql-secret.yaml
  1. 接电话
kubectl apply -f 06-mysql-services.yaml
  1. 召唤兄弟
kubectl apply -f 07-mysql-statefulset.yaml
  1. 检查状态
kubectl get pods -n mysql-world
NAME            READY   STATUS    RESTARTS   AGE
mysql-brothers-0 2/2     Running   0          3m
mysql-brothers-1 2/2     Running   0          2m

五、主从同步:兄弟间的悄悄话

1. 大哥授权:

kubectl exec -it mysql-brothers-0 -n mysql-world -- bash
mysql -uroot -p123456 -e "GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' IDENTIFIED BY 'replpass';"

2. 二哥拜师:

kubectl exec -it mysql-brothers-1 -n mysql-world -- bash
mysql -uroot -p123456 -e "CHANGE MASTER TO 
  MASTER_HOST='mysql-brothers-0.mysql-world',
  MASTER_USER='repl',
  MASTER_PASSWORD='replpass',
  MASTER_LOG_FILE='big-brother-bin.000001',
  MASTER_LOG_POS=0;"
mysql -uroot -p123456 -e "START SLAVE;"

3. 验证同步:

# 大哥写数据
kubectl exec mysql-brothers-0 -n mysql-world -- \
  mysql -uroot -p123456 -e "CREATE DATABASE test; INSERT INTO test.people VALUES ('豆包', 25);"

# 二哥查数据
kubectl exec mysql-brothers-1 -n mysql-world -- \
  mysql -uroot -p123456 -e "SELECT * FROM test.people;"

六、扩军:召唤三弟

kubectl scale statefulset mysql-brothers -n mysql-world --replicas=3

⚠️ 三弟需要手动拜师(同二哥步骤)

七、生产环境秘籍

  1. 云存储
# 使用 NFS 动态存储
volumeClaimTemplates:
- metadata:
    name: data
  spec:
    storageClassName: nfs
    accessModes:
    - ReadWriteMany
    resources:
      requests:
        storage: 50Gi
  1. 负载均衡
# 安装 MetalLB 分配外部 IP
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.7/config/manifests/metallb-native.yaml
  1. 监控报警
# 安装 Prometheus Operator
kubectl apply -f https://github.com/prometheus-operator/prometheus-operator/releases/latest/download/bundle.yaml

八、总结

通过 StatefulSet,我们实现了:

  • 名字不变mysql-brothers-0 永远是大哥
  • 数据不丢:仓库跟着 Pod 跑
  • 兄弟齐心:主从同步自动完成

现在你可以傲娇地说:「在我的 Kubernetes 动物园里,MySQL 是最听话的动物!」

🐳 提示:部署前记得在节点创建 /data/svr/mysql 目录哦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值