You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kubernetes/Docker Swarm中自动部署可扩缩的MariaDB Galera集群?

自动扩缩MariaDB Galera集群的最佳实践

我来帮你理清这个问题的最优解法——你完全不用手动创建一堆ConfigMap,也能实现MariaDB Galera集群的自动扩缩容,核心思路就是动态生成节点专属配置,而不是提前给每个节点准备静态配置文件。

核心逻辑:用环境变量+启动脚本替代静态ConfigMap

Galera节点里的wsrep_node_address、wsrep_node_name这类专属参数,以及wsrep_cluster_address的集群成员列表,都可以通过Kubernetes自动注入的环境变量,配合启动脚本动态生成,只需要一个通用的配置模板即可。

具体实现步骤

1. 准备通用配置模板(仅一个ConfigMap)

先创建一个包含占位符的Galera配置模板,把它放到单个ConfigMap里:

# mariadb-galera-template ConfigMap内容
[mysqld]
wsrep_cluster_name="mariadb-cluster"
wsrep_node_address="{{NODE_IP}}"
wsrep_node_name="{{NODE_NAME}}"
wsrep_cluster_address="{{CLUSTER_MEMBERS}}"
# 其他通用配置(如端口、字符集等)
port=3306
character-set-server=utf8mb4

2. 编写启动脚本动态生成配置

写一个start-galera.sh脚本,用来替换模板里的占位符,同时处理集群初始化逻辑:

#!/bin/bash
set -e

# 替换模板中的节点专属变量
sed -i "s/{{NODE_IP}}/$POD_IP/g" /etc/mysql/my.cnf.tmpl
sed -i "s/{{NODE_NAME}}/$POD_NAME/g" /etc/mysql/my.cnf.tmpl
sed -i "s/{{CLUSTER_MEMBERS}}/gcomm://$CLUSTER_DNS/g" /etc/mysql/my.cnf.tmpl

# 将生成好的配置移到MariaDB默认读取路径
mv /etc/mysql/my.cnf.tmpl /etc/mysql/my.cnf

# 处理集群启动:第一个节点用bootstrap模式初始化集群,其余节点自动加入
if [[ $POD_NAME == *"-0" ]]; then
    echo "Bootstrapping new Galera cluster..."
    exec mysqld --wsrep-new-cluster
else
    echo "Joining existing Galera cluster..."
    exec mysqld
fi

把这个脚本也放到一个ConfigMap里,记得给它执行权限(defaultMode: 0755)。

3. 用Headless Service维护集群成员DNS

在Kubernetes中创建Headless Service,它会自动为所有Galera Pod生成可解析的DNS记录,这样新节点就能通过DNS获取整个集群的成员列表:

apiVersion: v1
kind: Service
metadata:
  name: mariadb-galera-headless
spec:
  clusterIP: None
  selector:
    app: mariadb-galera
  ports:
    - name: mysql
      port: 3306
    - name: galera
      port: 4567
    - name: ist
      port: 4568
    - name: sst
      port: 4444

4. 用StatefulSet部署(推荐用于有状态应用)

StatefulSet天生适配MariaDB这类有状态集群:它会给每个Pod分配固定的名称(如mariadb-galera-0、mariadb-galera-1)、稳定的存储卷,还能保证有序启动/终止。

关键配置片段:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mariadb-galera
spec:
  serviceName: "mariadb-galera-headless"
  replicas: 3
  selector:
    matchLabels:
      app: mariadb-galera
  template:
    metadata:
      labels:
        app: mariadb-galera
    spec:
      initContainers:
        # 初始化容器:复制配置模板和启动脚本到容器内
        - name: copy-resources
          image: busybox:latest
          command:
            - sh
            - -c
            - |
              cp /config/my.cnf.tmpl /etc/mysql/
              cp /scripts/start-galera.sh /scripts/
          volumeMounts:
            - name: config-template
              mountPath: /config
            - name: scripts
              mountPath: /scripts
            - name: mysql-config
              mountPath: /etc/mysql
      containers:
        - name: mariadb-galera
          image: mariadb:10.6-galera
          command: ["/scripts/start-galera.sh"]
          env:
            # 自动注入Pod的IP和名称
            - name: POD_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            # Headless Service的DNS名,用来获取集群成员
            - name: CLUSTER_DNS
              value: "mariadb-galera-headless.default.svc.cluster.local"
          volumeMounts:
            - name: mysql-config
              mountPath: /etc/mysql
            - name: scripts
              mountPath: /scripts
            - name: data
              mountPath: /var/lib/mysql
      volumes:
        - name: config-template
          configMap:
            name: mariadb-galera-template
        - name: scripts
          configMap:
            name: mariadb-galera-scripts
            defaultMode: 0755
        - name: mysql-config
          emptyDir: {}
  # 动态申请持久化存储卷
  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 10Gi

5. 实现自动扩缩容

当你需要扩容时,只需要执行:

kubectl scale statefulset mariadb-galera --replicas=5

新的Pod会自动读取Headless Service的DNS记录,通过启动脚本生成专属配置并加入集群;缩容时,Galera会自动移除下线节点,无需手动修改任何配置。

为什么不用多个ConfigMap?

你说得没错,手动创建N个ConfigMap完全不具备可扩展性,也不符合云原生的自动化理念。动态配置生成的方式只需要1-2个ConfigMap,所有节点共享模板,通过环境变量注入专属信息,完美适配自动扩缩容场景。


内容的提问来源于stack exchange,提问作者hamedb71

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:05:26