Kubernetes 高可用 MariaDB Galera 集群部署

Kubernetes 高可用 MariaDB Galera 集群部署

一、架构概述

本文档详细介绍如何在 Kubernetes 集群中部署 MariaDB Galera 高可用集群。该集群采用一主两从的架构设计,包含以下三个节点:

节点角色 Pod 名称 NodePort 端口 说明
Master mariadb-master 30306 主节点,处理写入操作
Slave mariadb-slave 30307 从节点,处理只读操作
Backup mariadb-backup 30308 备份节点,兼作异步备份

集群架构图

mariadb-galera-arch.png

端口说明

端口 用途
3306 MySQL/MariaDB 标准连接端口
4567 Galera 集群内部通信端口
4568 IST (Incremental State Transfer) 端口
4444 SST (State State Transfer) 端口

二、前置准备

2.1 节点规划

确保 Kubernetes 集群中有至少三台可用于 MariaDB 的节点:

主机名 IP 地址 标签角色 资源配置
node-01 <NODE_IP_1> mariadb-server=master 7核 CPU / 50Gi 内存
node-02 <NODE_IP_2> mariadb-server=slave 3核 CPU / 30Gi 内存
node-03 <NODE_IP_3> mariadb-server=bk 3核 CPU / 30Gi 内存

2.2 NFS 存储服务器

准备一台 NFS 服务器用于存储备份数据:

  • 服务器 IP: <NFS_SERVER_IP>
  • 共享路径: /home/data/share/backups/mariadb/
  • 存储容量: 2000Gi

三、配置文件清单

部署所需的所有 YAML 配置文件:

文件名 资源类型 说明
mariadb-pv.yaml PersistentVolume NFS 存储卷定义
mariadb-pvc.yaml PersistentVolumeClaim PVC 声明
mariadb.yaml ConfigMap + Service MySQL 配置与集群服务
mariadb-master.yaml StatefulSet Master 节点部署
mariadb-slave.yaml StatefulSet Slave 节点部署
mariadb-backup.yaml StatefulSet Backup 节点部署
ps.sh Shell 脚本 部署与运维脚本

四、部署步骤

步骤 1:创建命名空间

kubectl create namespace bjac-mariadb

步骤 2:创建镜像拉取 Secret

本方案使用阿里云容器镜像仓库,需要创建 Registry 凭据:

kubectl create secret docker-registry aliyunregsecret \
  --docker-server=<YOUR_REGISTRY_SERVER> \
  --docker-username=<YOUR_REGISTRY_USERNAME> \
  --docker-password=<YOUR_REGISTRY_PASSWORD> \
  -n bjac-mariadb

说明:请根据实际镜像仓库信息修改用户名和密码。

步骤 3:为节点打标签

# 查看现有节点
kubectl get node --show-labels=true

# 为 MariaDB 节点打标签
kubectl label nodes sd-postgresql-01 mariadb-server=master
kubectl label nodes sd-postgresql-02 mariadb-server=slave
kubectl label nodes sd-postgresql-03 mariadb-server=bk

步骤 4:创建数据目录

在每台 MariaDB 服务器节点上创建数据目录:

# 所有节点创建数据目录
mkdir -p /home/mariadb/data
chmod -R 777 /home/mariadb/data

# 备份服务器创建备份目录
mkdir -p /home/data/share/backups/mariadb/
chmod -R 777 /home/data/share/backups/mariadb/

步骤 5:部署存储卷

# 先部署 PV 和 PVC
kubectl apply -f mariadb-pv.yaml
kubectl apply -f mariadb-pvc.yaml

# 验证存储卷状态
kubectl get pv
kubectl get pvc -n bjac-mariadb

输出示例:

NAME                CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM
nfs-pv-mariadb-bk  2000Gi    RWX            Retain           Bound    bjac-mariadb/nfs-pvc-backup

步骤 6:部署 ConfigMap 和 Service

kubectl apply -f mariadb.yaml

将创建:

  • ConfigMap mariadb-conf:包含 MariaDB 配置文件
  • Service mariadb-master-out:NodePort 30306
  • Service mariadb-slave-out:NodePort 30307
  • Service mariadb-backup-out:NodePort 30308

步骤 7:部署 MariaDB StatefulSet

按照以下顺序部署各节点:

# 部署 backup 节点(先启动,作为初始节点)
kubectl apply -f mariadb-backup.yaml

# 部署 master 节点
kubectl apply -f mariadb-master.yaml

# 部署 slave 节点
kubectl apply -f mariadb-slave.yaml

步骤 8:验证部署状态

# 查看 Pod 状态
kubectl get pod -n bjac-mariadb -o wide

# 查看服务状态
kubectl get svc -n bjac-mariadb

# 查看 PVC 状态
kubectl get pvc -n bjac-mariadb

五、配置文件详解

5.1 ConfigMap 配置 (mariadb.yaml)

apiVersion: v1
kind: ConfigMap
metadata:
  name: mariadb-conf
  namespace: bjac-mariadb
data:
  mariadb.cnf: |
    [client]
    default-character-set = utf8mb4

    [mysqld]
    # 字符集配置
    character-set-server = utf8mb4
    collation-server = utf8mb4_unicode_ci
    lower_case_table_names = 0

    # 性能优化参数
    key_buffer_size = 128M
    max_allowed_packet = 32M
    table_open_cache = 8192
    thread_cache_size = 8
    innodb_buffer_pool_size = 20G
    innodb_log_file_size = 512M

    # 连接配置
    max_connections = 2000
    open_files_limit = 65535

    # Binlog 配置
    binlog_format = row
    log_bin = mariadb-bin
    expire_logs_days = 30

    # Galera 集群配置
    [galera]
    wsrep_on = ON
    wsrep_provider = "/usr/lib/galera/libgalera_smm.so"
    wsrep_cluster_address = "gcomm://mariadb-master,mariadb-slave,mariadb-backup"
    wsrep-sst-method = rsync

5.2 Master 节点配置 (mariadb-master.yaml)

关键配置项说明:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mariadb-master
  namespace: bjac-mariadb
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mariadb-master
  template:
    spec:
      hostNetwork: true
      hostAliases:
      - ip: "<NODE_IP_1>"
        hostnames:
        - "mariadb-master"
      - ip: "<NODE_IP_2>"
        hostnames:
        - "mariadb-slave"
      - ip: "<NODE_IP_3>"
        hostnames:
        - "mariadb-backup"
      containers:
      - name: mariadb-master
        image: <YOUR_MARIADB_IMAGE>
        command: ["docker-entrypoint.sh", "mysqld", "--wsrep_node_address=mariadb-master"]
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "<YOUR_ROOT_PASSWORD>"
        volumeMounts:
        - name: mariadb-data
          mountPath: /var/lib/mysql/
        resources:
          limits:
            cpu: 7
            memory: 50Gi
      nodeSelector:
        mariadb-server: master

5.3 Galera 集群配置说明

集群通过以下关键参数实现同步复制:

参数 说明
wsrep_on 开启 Galera 复制
wsrep_provider Galera 库路径
wsrep_cluster_address 集群节点地址列表
wsrep-sst-method 全量同步方法 (rsync)
wsrep_node_address 当前节点地址

5.4 各节点启动命令差异

节点 启动参数 说明
Master --wsrep_node_address=mariadb-master 标准启动
Slave --wsrep_node_address=mariadb-slave 标准启动
Backup --wsrep-new-cluster --wsrep_node_address=mariadb-backup 首次引导集群

六、连接测试

6.1 内部连接测试

# 进入 Master 节点
kubectl exec -it pod/mariadb-master-0 -n bjac-mariadb -- bash

# 登录 MariaDB
mysql -u root -p

6.2 外部连接测试

用客户端工具连接各节点:

节点 Host Port 用户名 密码
Master <NodeIP> 30306 root <YOUR_PASSWORD>
Slave <NodeIP> 30307 root <YOUR_PASSWORD>
Backup <NodeIP> 30308 root <YOUR_PASSWORD>

6.3 DNS 解析测试

# 创建测试 Pod
kubectl run -i --tty --image busybox:1.28.4 dns-test --restart=Never --rm /bin/sh

# 测试 DNS 解析
nslookup mariadb-master.bjac-mariadb.svc.cluster.local
nslookup mariadb-slave.bjac-mariadb.svc.cluster.local
nslookup mariadb-backup.bjac-mariadb.svc.cluster.local

七、用户权限管理

7.1 创建只读用户

CREATE USER '<READONLY_USER>'@'%' IDENTIFIED BY '<READONLY_PASSWORD>';
GRANT SELECT ON <DATABASE_NAME>.* TO '<READONLY_USER>'@'%';
FLUSH PRIVILEGES;

7.2 创建读写用户

CREATE USER '<READWRITE_USER>'@'%' IDENTIFIED BY '<READWRITE_PASSWORD>';
GRANT ALL PRIVILEGES ON <DATABASE_NAME>.* TO '<READWRITE_USER>'@'%';
FLUSH PRIVILEGES;

7.3 修改用户密码

SET PASSWORD FOR '<READWRITE_USER>'@'%' = PASSWORD('<NEW_PASSWORD>');
FLUSH PRIVILEGES;

八、备份配置

Backup 节点支持定时备份功能。进入 Pod 开启 cron 服务:

kubectl exec -it pod/mariadb-backup-0 -n bjac-mariadb -- bash
service cron start

备份数据将存储在 NFS 路径:/home/data/share/backups/mariadb/


九、常用运维命令

9.1 查看状态

# 查看所有资源
kubectl get all -n bjac-mariadb

# 查看 Pod 日志
kubectl -n bjac-mariadb logs mariadb-master-0 --all-containers=true
kubectl -n bjac-mariadb logs mariadb-slave-0 --all-containers=true
kubectl -n bjac-mariadb logs mariadb-backup-0 --all-containers=true

# 查看资源详情
kubectl -n bjac-mariadb describe pod mariadb-master-0
kubectl -n bjac-mariadb describe pv nfs-pv-mariadb-bk
kubectl -n bjac-mariadb describe pvc nfs-pvc-backup

9.2 重启集群

# 删除所有 StatefulSet
kubectl delete -f mariadb-slave.yaml
kubectl delete -f mariadb-master.yaml
kubectl delete -f mariadb-backup.yaml

# 重新部署
kubectl apply -f mariadb-backup.yaml
kubectl apply -f mariadb-master.yaml
kubectl apply -f mariadb-slave.yaml

十、注意事项

  1. 数据安全:首次部署前确保数据目录为空,避免数据冲突
  2. 节点亲和性:使用 nodeSelector 确保 Pod 调度到指定节点
  3. 资源限制:根据实际业务负载调整 CPU 和内存限制
  4. 密码安全:生产环境务必修改默认密码
  5. 备份验证:定期验证备份数据的可用性

附录:资源清单

文件名                          资源类型            数量
mariadb-pv.yaml                PersistentVolume  1
mariadb-pvc.yaml               PersistentVolumeClaim  1
mariadb.yaml                   ConfigMap         1
                               Service           3
mariadb-master.yaml            StatefulSet       1
mariadb-slave.yaml             StatefulSet       1
mariadb-backup.yaml           StatefulSet       1

阅读更多

Ghost 邮箱订阅功能在中国大陆的困境:Mailgun 注册受阻实录

Ghost 邮箱订阅功能在中国大陆的困境:Mailgun 注册受阻实录

本文记录了 Ghost 博客邮箱订阅功能因 Mailgun 在中国大陆无法注册而被迫关闭的完整过程,包括注册尝试、工单沟通及最终应对方案。 一、背景:Ghost 与 Mailgun Ghost 博客平台内置了邮箱订阅(Newsletter)功能,读者可以通过输入邮箱地址订阅博客更新,Ghost 会自动将新文章以邮件形式推送给订阅者。这一功能的邮件发送能力依赖于第三方邮件服务——Mailgun。 Ghost 官方推荐使用 Mailgun 作为邮件传输层,配置方式如下: 配置项 说明 示例值 mail.from 发件人地址 newsletter@yourdomain.com mail.transport 传输协议 SMTP mail.options.host SMTP 主机 smtp.mailgun.org mail.options.port

By 菱角
Kubernetes 全栈监控体系:kube-prometheus-stack + 7 大 Exporter 生产实践

Kubernetes 全栈监控体系:kube-prometheus-stack + 7 大 Exporter 生产实践

本文基于 kube-prometheus-stack Helm Chart 在 Kubernetes 上构建完整监控体系的实战,覆盖 Prometheus、Grafana、Alertmanager 及 7 个专用 Exporter 的部署与配置。 一、监控体系全景架构 整套监控以 kube-prometheus-stack 为核心,通过 ServiceMonitor CRD 自动发现并采集 7 大数据源,配合 Alertmanager 分级告警与 Grafana 可视化: 组件 版本 作用 Prometheus v2.45.0 指标采集与存储,10 天数据保留 Alertmanager v0.25.0 告警路由与邮件推送,2 副本 HA

By 菱角
基于 Docker Compose 部署 Apache APISIX:全栈 API 网关实践

基于 Docker Compose 部署 Apache APISIX:全栈 API 网关实践

本文基于 APISIX 3.9.1 + Dashboard 3.0.1 + etcd 3.5.15 + Prometheus + Grafana 的生产级 Docker Compose 部署实践。 一、整体架构 本次部署采用 Docker Compose 编排五大组件,形成从配置管理到流量监控的完整闭环: 组件 版本 作用 端口 APISIX 3.9.1-debian API 网关核心,路由转发、插件执行 9080/9443 Dashboard 3.0.1-alpine 可视化配置管理界面 9000 etcd 3.5.15

By 菱角
在 Kubernetes 上部署 Apache Flink:生产实战指南

在 Kubernetes 上部署 Apache Flink:生产实战指南

本文基于 Flink 1.15.2 + Kubernetes 的生产环境部署实践。 一、架构概览 Flink 在 Kubernetes 上采用经典的 JobManager + TaskManager 主从架构,JobManager 负责作业调度与协调,TaskManager 承载实际的计算任务。 资源分配一览 组件 作用 副本数 Task Slots 内存配置 JobManager 作业调度、Checkpoint 管理、协调 1 — 8G TaskManager 执行计算任务 3 80/Pod 48G 总计 — 4 240 — 二、Namespace 隔离 为 Flink 创建独立 Namespace,

By 菱角