Kubernetes 中实现 MySQL 的读写分离

Kubernetes 中实现 MySQL 的读写分离

在 Kubernetes 中实现 MySQL 的读写分离,可以通过主从复制架构来实现。在这种架构中,MySQL 主节点(Master)负责处理所有写操作,而 MySQL 从节点(Slave)负责处理所有读操作。下面是一个详细的步骤指南:

步骤 1:创建 Kubernetes 集群

确保你有一个运行良好的 Kubernetes 集群,建议有3个以上的节点,以便更好地分配资源并实现高可用性。

步骤 2:创建 MySQL 主从复制 Docker 镜像

  1. 首先,需要构建一个支持主从复制的 MySQL 镜像,或直接使用现有支持主从复制的 MySQL 镜像。

  2. 如果要自己配置,可以从 MySQL 官方镜像开始,通过设置 my.cnf 文件来支持主从复制。

  3. 主要的配置如下:

    • 主节点配置(Master):设置 server-id,并启用二进制日志(log-bin)。

    • 从节点配置(Slave):设置不同的 server-id,并配置为从属节点。

步骤 3:创建 Kubernetes Secret 存储 MySQL 密码

为了安全性,我们可以使用 Kubernetes Secret 来存储 MySQL 密码。

复制代码
apiVersion: v1
kind: Secret
metadata:
 name: mysql-secret
type: Opaque
data:
 mysql-root-password: <base64编码的root密码>
 mysql-replication-user: <base64编码的replication用户名>
 mysql-replication-password: <base64编码的replication密码>

步骤 4:部署 MySQL 主节点

  1. 创建主节点的配置文件 mysql-master-deployment.yaml
复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
 name: mysql-master
spec:
 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
         valueFrom:
           secretKeyRef:
             name: mysql-secret
             key: mysql-root-password
       - name: MYSQL_REPLICATION_USER
         valueFrom:
           secretKeyRef:
             name: mysql-secret
             key: mysql-replication-user
       - name: MYSQL_REPLICATION_PASSWORD
         valueFrom:
           secretKeyRef:
             name: mysql-secret
             key: mysql-replication-password
       ports:
       - containerPort: 3306
       volumeMounts:
       - name: mysql-persistent-storage
         mountPath: /var/lib/mysql
     volumes:
     - name: mysql-persistent-storage
       persistentVolumeClaim:
         claimName: mysql-pv-claim
  1. 创建 MySQL 主节点的 Service:
复制代码
apiVersion: v1
kind: Service
metadata:
 name: mysql-master
spec:
 ports:
 - port: 3306
   targetPort: 3306
 selector:
   app: mysql
   role: master

步骤 5:部署 MySQL 从节点

  1. 创建从节点的配置文件 mysql-slave-deployment.yaml
复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
 name: mysql-slave
spec:
 replicas: 2
 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
         valueFrom:
           secretKeyRef:
             name: mysql-secret
             key: mysql-root-password
       - name: MYSQL_REPLICATION_USER
         valueFrom:
           secretKeyRef:
             name: mysql-secret
             key: mysql-replication-user
       - name: MYSQL_REPLICATION_PASSWORD
         valueFrom:
           secretKeyRef:
             name: mysql-secret
             key: mysql-replication-password
       - name: MYSQL_MASTER_HOST
         value: "mysql-master"
       ports:
       - containerPort: 3306
       volumeMounts:
       - name: mysql-persistent-storage
         mountPath: /var/lib/mysql
     volumes:
     - name: mysql-persistent-storage
       persistentVolumeClaim:
         claimName: mysql-pv-claim
  1. 创建 MySQL 从节点的 Service:
复制代码
apiVersion: v1
kind: Service
metadata:
 name: mysql-slave
spec:
 ports:
 - port: 3306
   targetPort: 3306
 selector:
   app: mysql
   role: slave

步骤 6:设置主从复制

在从节点启动后,执行以下命令来配置主从复制:

  1. 登录主节点,创建用于复制的用户:

    复制代码
    CREATE USER 'replication'@'%' IDENTIFIED BY 'replication_password';
    GRANT REPLICATION SLAVE ON *.* TO 'replication'@'%';
    FLUSH PRIVILEGES;
  2. 获取主节点状态:

    复制代码
    SHOW MASTER STATUS;
  3. 登录到从节点,将其配置为主节点的从属节点:

    复制代码
    CHANGE MASTER TO
        MASTER_HOST='mysql-master',
       MASTER_USER='replication',
       MASTER_PASSWORD='replication_password',
       MASTER_LOG_FILE='<上一步中获取的 File>',
       MASTER_LOG_POS=<上一步中获取的 Position>;
    START SLAVE;
  4. 检查从节点状态以确认同步是否成功:

    复制代码
    SHOW SLAVE STATUS\G

步骤 7:配置读写分离

在 Kubernetes 中,可以使用一个自定义的 Service 来实现读写分离:

  1. 创建 MySQL 读写分离的 Service:

    复制代码
    apiVersion: v1
    kind: Service
    metadata:
     name: mysql-read-write
    spec:
     ports:
     - port: 3306
       targetPort: 3306
     selector:
       app: mysql
       role: master
    ---
    apiVersion: v1
    kind: Service
    metadata:
     name: mysql-read-only
    spec:
     ports:
     - port: 3306
       targetPort: 3306
     selector:
       app: mysql
       role: slave
  2. 通过应用层(例如应用代码)选择访问不同的 Service 来实现读写分离:

    • 写操作:通过 mysql-read-write Service 连接。

    • 读操作:通过 mysql-read-only Service 连接。

步骤 8:测试读写分离

  1. 将写操作请求发送到 mysql-read-write 服务,验证数据是否被正确写入。

  2. 将读操作请求发送到 mysql-read-only 服务,确保从节点上能够读到主节点写入的数据。

步骤 9:监控与维护

可以通过 Prometheus 和 Grafana 对 MySQL 集群进行监控,关注主从复制的延迟和节点的健康状态,以便及时处理故障。

总结

主节点负责处理写操作,从节点负责处理读操作,应用可以根据需求连接到不同的 Service 来实现高效的数据库读写分离。