在 Kubernetes 上搭建 MySQL 主从复制

在云原生计算日益普及的今天,基于 Kubernetes(k8s)平台对数据库进行高可用配置变得愈发重要。本文将探讨如何在 Kubernetes 中搭建 MySQL 的主从复制架构,尤其是当主库没有从库信息时的处理方式。

什么是 MySQL 主从复制?

在 MySQL 主从复制中,主库负责处理所有的写操作,而从库则负责读取操作,从而实现负载均衡。这一架构可以提高数据访问的性能,并提供数据的冗余备份。当主库发生故障时,从库可以快速顶替主库,确保系统的可用性。

MySQL 主从复制架构图

erDiagram
    主库 {
        string id
        string 数据
    }
    从库 {
        string id
        string 数据
    }
    主库 ||--o{ 从库 : "复制"

Kubernetes 中部署 MySQL

在 Kubernetes 上部署 MySQL 可以通过以下几个步骤进行:

  1. 创建 MySQL 的配置文件
  2. 编写 StatefulSet 资源定义
  3. 创建 Service 以提供稳定的访问路径

1. 创建 MySQL 的配置文件

首先,我们需要创建一个 ConfigMap 来管理 MySQL 的配置。在 MySQL 中,我们需要配置 my.cnf 文件,其中包括复制所需的设置。

apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-config
data:
  my.cnf: |
    [mysqld]
    server-id=1
    log_bin=mysql-bin
    bind-address=0.0.0.0

2. 编写 StatefulSet 资源定义

接下来,创建 StatefulSet 用于部署 MySQL 实例。以下风格的代码可以帮助您设置主库和从库的 StatefulSet。

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql-master
spec:
  serviceName: mysql-master
  replicas: 1
  selector:
    matchLabels:
      app: mysql
      role: master
  template:
    metadata:
      labels:
        app: mysql
        role: master
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: rootpassword
        volumeMounts:
        - name: config
          mountPath: /etc/mysql/my.cnf
          subPath: my.cnf
      volumes:
      - name: config
        configMap:
          name: mysql-config
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql-slave
spec:
  serviceName: mysql-slave
  replicas: 1
  selector:
    matchLabels:
      app: mysql
      role: slave
  template:
    metadata:
      labels:
        app: mysql
        role: slave
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: rootpassword
        - name: MYSQL_MASTER_HOST
          value: mysql-master
        volumeMounts:
        - name: config
          mountPath: /etc/mysql/my.cnf
          subPath: my.cnf
      volumes:
      - name: config
        configMap:
          name: mysql-config

3. 创建 Service 以提供稳定的访问路径

为了确保从库能顺利连接到主库,您需要配置 Kubernetes 服务。

apiVersion: v1
kind: Service
metadata:
  name: mysql-master
spec:
  ports:
    - port: 3306
  clusterIP: None
  selector:
    app: mysql
    role: master
---
apiVersion: v1
kind: Service
metadata:
  name: mysql-slave
spec:
  ports:
    - port: 3306
  clusterIP: None
  selector:
    app: mysql
    role: slave

配置主从复制

在部署 MySQL 之后,您需要手动执行一些命令以配置主从复制。首先,通过主库的 MySQL 客户端创建一个复制用户。

CREATE USER 'replicator'@'%' IDENTIFIED WITH mysql_native_password BY 'replicator_password';
GRANT REPLICATION SLAVE ON *.* TO 'replicator'@'%';
FLUSH PRIVILEGES;
SHOW MASTER STATUS;

在主库上运行上述命令后,您会看到当前的日志文件和位置,这些信息在从库端配置时非常重要。接下来,在从库上执行以下命令以启动复制:

CHANGE MASTER TO
    MASTER_HOST='mysql-master',
    MASTER_USER='replicator',
    MASTER_PASSWORD='replicator_password',
    MASTER_LOG_FILE='mysql-bin.000001',
    MASTER_LOG_POS=<Log_Position>;

START SLAVE;

记得将 <Log_Position> 替换成您在主库上执行 SHOW MASTER STATUS; 时得到的实际位置。

常见问题

  1. 主库可以同时有多个从库吗? 是的,主库可以有多个从库。

  2. 如何处理主库的故障? 通过监控工具或者有自动故障转移功能的系统可以快速切换到从库。

  3. 如何在从库上查看复制状态? 可以使用命令 SHOW SLAVE STATUS\G; 来查看从库的复制状态。

结论

在 Kubernetes 中搭建 MySQL 主从复制是实现高可用性和负载均衡的有效方法。本文中涵盖了从配置文件到 StatefulSet 和 Service 的完整过程,并给出了示例代码。尽管在主库没有从库信息的情况下配置可能会有些复杂,但通过手动命令设置仍可顺利完成。

通过以上步骤,您应该能够在 Kubernetes 集群中成功搭建 MySQL 主从复制环境。希望对您有所帮助,期待您在后续的工作中能大展身手,提高系统的性能和可靠性!