Kubernetes部署MySQL主从复制

Kubernetes集群为一主二从

1.部署架构图

2.创建ConfigMap

2.1 主节点ConfigMap配置

新建主节点mysqld.cnf资源清单文件mysql-source-cnf.yaml,并输入以下内容:

bash 复制代码
kind: ConfigMap
apiVersion: v1
metadata:
    name: mysql-source-cnf
data:
    mysqld.cnf: |-
        [mysqld]
        server-id=1
        read-only=0
        host-cache-size=0
        skip-name-resolve

2.2 从节点ConfigMap配置

新建从节点mysqld.cnf资源清单文件mysql-replica-cnf.yaml,并输入以下内容:

bash 复制代码
kind: ConfigMap
apiVersion: v1
metadata:
    name: mysql-replica-cnf
data:
    mysqld.cnf: |-
        [mysqld]
        server-id=2
        read-only=1
        host-cache-size=0
        skip-name-resolve

2.3 创建资源

bash 复制代码
[root@k8s-master01]# kubectl apply -f mysql-replica-cnf.yaml -f mysql-sourcecnf.yaml

3.创建Secret

3.1 Secret配置

我们创建一个 Secret 用来存储 MySQL root 用户的密码,主从使用相同的 Secret 配置。 运行 echo -n "123456!" | base64 命令生成 base64 编码的密码。 使用 vi 编辑器,新建 MySQL Secret 资源清单文件 mysql-secret.yaml ,并输入以下内容:

bash 复制代码
kind: Secret
apiVersion: v1
metadata:
    name: mysql-secret
data:
    MYSQL_ROOT_PASSWORD: MTIzNDU2
    type: Opaque

3.2 创建资源

bash 复制代码
[root@k8s-master01]# kubectl apply -f mysql-secret.yaml

4. 创建Service

4.1 创建主节点headless服务

新建 MySQL 主节点 headless 资源清单文件 mysql-source-svc.yaml ,并输入以下 内容:

bash 复制代码
kind: Service
apiVersion: v1
metadata:
    name: mysql-source-headless
    labels:
        app: mysql-source
spec:
    ports:
    - name: tcp-3306
      protocol: TCP
      port: 3306
      targetPort: 3306
    selector:
        app: mysql-source
    clusterIP: None
    type: ClusterIP

执行下面的命令,创建资源。

bash 复制代码
[root@k8s-master01]# kubectl apply -f mysql-replica-svc.yaml

4.2 创建从节点headless服务

新建 MySQL 从节点 headless 资源清单文件 mysql-replica-svc.yaml ,并输入以 下内容:

bash 复制代码
kind: Service
apiVersion: v1
metadata:
    name: mysql-replica-headless
    labels:
    app: mysql-replica
spec:
    ports:
    - name: tcp-3306
      protocol: TCP
      port: 3306
      targetPort: 3306
    selector:
      app: mysql-replica
    clusterIP: None
    type: ClusterIP

执行下面的命令,创建资源

bash 复制代码
[root@k8s-master01]# kubectl apply -f mysql-replica-svc.yaml

4.3 创建外部访问服务

使用最简单的 NodePort 方式发布 k8s 集群上的 MySQL 服务给外部应用访问,指定的端口为 31306。

新建 MySQL 从节点 headless 资源清单文件 mysql-external-svc.yaml ,并输入以 下内容:

bash 复制代码
apiVersion: v1
kind: Service
metadata:
    name: mysql-source-external
spec:
    type: NodePort
    selector:
        app: mysql-source
    ports:
      - port: 3306
        targetPort: 3306
        nodePort: 31306

执行下面的命令,创建资源。

bash 复制代码
[root@k8s-master01]# kubectl apply -f mysql-external-svc.yaml

5.创建StatefulSet

在 Kubernetes 集群中部署数据库服务时,我们面临着选择有状态服务(StatefulSet)与无状态服务 (Deployment)之间的决策。对于 MySQL 这类数据库服务,我们选择使用 StatefulSet 而不是 Deployment,原因如下:

  • 稳定的网络身份:StatefulSet 为每个 Pod 分配了一个持久且唯一的网络标识符,这对于 MySQL 这 类需要固定主机名或网络地址以维持主从复制关系的数据库服务至关重要。
  • 持久化存储:StatefulSet 易于与持久化存储卷结合使用,确保数据库数据的持久保存,即便是在 Pod 重启或重新调度后。
  • 适合有状态应用:StatefulSet 是为有状态应用设计的,如数据库和消息队列,它提供了必要的支持 来维护这些应用的状态。

5.1 创建主节点StatefulSet

新建 MySQL 主节点 StatefulSet 资源清单文件 mysql-source-sts.yaml ,并输入以 下内容:

bash 复制代码
kind: StatefulSet
apiVersion: apps/v1
metadata:
    name: mysql-source
    labels:
        app: mysql-source
spec:
    replicas: 1
    selector:
        matchLabels:
            app: mysql-source
    template:
        metadata:
            labels:
                app: mysql-source
    spec:
        volumes:
            - name: host-time
              hostPath:
                path: /etc/localtime
                type: ''
            - name: config
              configMap:
                name: mysql-source-cnf
                defaultMode: 420
        containers:
            - name: mysql-source
              image: mysql:8.4.3
              imagePullPolicy: IfNotPresent
              ports:
                - containerPort: 3306
              env:
                - name: MYSQL_ROOT_PASSWORD
                  valueFrom:
                    secretKeyRef:
                        name: mysql-secret
                        key: MYSQL_ROOT_PASSWORD
              resources:
                limits:
                    cpu: '2'
                    memory: 4Gi
                requests:
                    cpu: 100m
                    memory: 100Mi
              volumeMounts:
                  - name: host-time
                    mountPath: /etc/localtime
                  - name: data
                    mountPath: /var/lib/mysql
                  - name: config
                    readOnly: true
                    mountPath: /etc/mysql/conf.d/
    volumeClaimTemplates:
      - metadata:
            name: data
        spec:
            accessModes: ["ReadWriteOnce"]
            resources:
                requests:
                    storage: 10Gi
            storageClassName: nfs-client
            volumeMode: Filesystem
    serviceName: mysql-source-headless

执行下面的命令,创建资源。

bash 复制代码
[root@k8s-master01]# kubectl apply -f mysql-source-sts.yaml

5.2 创建从节点StatefulSet

新建 MySQL 从节点 StatefulSet 资源清单文件 mysql-replica-sts.yaml ,并输入 以下内容:

bash 复制代码
kind: StatefulSet
apiVersion: apps/v1
metadata:
    name: mysql-replica
    labels:
        app: mysql-replica
spec:
    replicas: 1
    selector:
        matchLabels:
            app: mysql-source
    template:
        metadata:
            labels:
                app: mysql-source
    spec:
        volumes:
            - name: host-time
              hostPath:
                path: /etc/localtime
                type: ''
            - name: config
              configMap:
                name: mysql-source-cnf
                defaultMode: 420
        containers:
            - name: mysql-source
              image: mysql:8.4.3
              imagePullPolicy: IfNotPresent
              ports:
                - containerPort: 3306
              env:
                - name: MYSQL_ROOT_PASSWORD
                  valueFrom:
                    secretKeyRef:
                        name: mysql-secret
                        key: MYSQL_ROOT_PASSWORD
              resources:
                limits:
                    cpu: '2'
                    memory: 4Gi
                requests:
                    cpu: 100m
                    memory: 100Mi
              volumeMounts:
                  - name: host-time
                    mountPath: /etc/localtime
                  - name: data
                    mountPath: /var/lib/mysql
                  - name: config
                    readOnly: true
                    mountPath: /etc/mysql/conf.d/
    volumeClaimTemplates:
      - metadata:
            name: data
        spec:
            accessModes: ["ReadWriteOnce"]
            resources:
                requests:
                    storage: 10Gi
            storageClassName: nfs-client
            volumeMode: Filesystem
    serviceName: mysql-source-headless

执行下面的命令,创建资源

bash 复制代码
[root@k8s-master01]# kubectl apply -f mysql-replica-sts.yaml

5.3 验证MySQL主从Pod状态

查看 Pod 状态

bash 复制代码
[root@k8s-master01]# kubectl get pod -o wide
NAME   READY   STATUS   RESTARTS   AGE   IP   NODE
NOMINATED NODE READINESS GATES
mysql-replica-0   1/1   Running   0   13m   10.244.58.243   k8s-node02
<none>   <none>
mysql-source-0   1/1   Running   0   13m   10.244.58.246   k8s-node02
<none>   <none>

验证自定义配置是否生效6.

bash 复制代码
[root@k8s-master01]# kubectl exec -it mysql-source-0 -- mysql -uroot -p123456 -
e "show variables like '%max_conn%';"
mysql: [Warning] Using a password on the command line interface can be insecure.
+------------------------+---------+
| Variable_name          | Value   |
+------------------------+---------+
| max_connect_errors     | 1000000 |
| max_connections        | 2048    |
| mysqlx_max_connections | 100     |
+------------------------+---------+

6.配置主从同步

6.1 主节点配置

6.1.1进入MySQL主节点容器内部

bash 复制代码
[root@k8s-master01 3]# kubectl exec -it mysql-source-0 -- mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.4.3 MySQL Community Server - GPL

Copyright (c) 2000, 2024, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners. 

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

6.1.2 创建主从同步用户

在主服务器上创建同步使用的用户 repuser 并赋予指定的权限

bash 复制代码
-- 创建用户并设置密码
mysql> CREATE USER 'repuser'@'%' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.01 sec) 

-- 赋予权限
mysql> GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'repuser'@'%';
Query OK, 0 rows affected (0.01 sec)

-- 刷新权限
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

6.1.3 查看Master状态

bash 复制代码
mysql> SHOW BINARY LOG STATUS;
+---------------+----------+--------------+------------------+-------------------
+
| File            | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set
|
+---------------+----------+--------------+------------------+-------------------
+
| binlog.000002   | 886      |              |                   |  
|
+---------------+----------+--------------+------------------+-------------------
+
1 row in set (0.00 sec)

6.2 从节点配置

6.2.1 进入MySQL从节点容器内部

bash 复制代码
[root@k8s-master01 3]# kubectl exec -it mysql-replica-0 -- mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.4.3 MySQL Community Server - GPL

Copyright (c) 2000, 2024, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

6.2.2 配置主从同步

sql 复制代码
mysql> CHANGE REPLICATION SOURCE TO
    SOURCE_HOST='mysql-source-headless.default.svc.cluster.local',
    SOURCE_PORT=3306,
    SOURCE_USER='repuser',
    SOURCE_PASSWORD='123456',
    SOURCE_LOG_FILE='binlog.000002',
    SOURCE_LOG_POS=886,
    GET_SOURCE_PUBLIC_KEY=1;

Query OK, 0 rows affected, 2 warnings (0.03 sec)

6.2.3 启动主从同步

bash 复制代码
mysql> start replica;

6.3.3 查看主从同步状态

bash 复制代码
mysql> show replica status\G;

**************** 1. row ***************************
        Replica_IO_State: Waiting for source to send event
            Source_Host: mysql-source-headless.default.svc.cluster.local
            Source_User: repuser
            Source_Port: 3306
            Connect_Retry: 60
            Source_Log_File: binlog.000002
            Read_Source_Log_Pos: 886
            Relay_Log_File: mysql-replica-0-relay-bin.000002
            Relay_Log_Pos: 325
            Relay_Source_Log_File: binlog.000002
            Replica_IO_Running: Yes # 重点注意
            Replica_SQL_Running: Yes # 重点注意

7. 验证主从同步

确认同步状态,在主节点新建数据库及表并添加数据,然后在从节点查询以验证主从同步是否正常。

相关推荐
超级无敌永恒暴龙战士1 小时前
MySQL-delete tableName from ...
数据库·mysql
小猿姐4 小时前
KubeBlocks For MySQL 云原生设计分享
mysql·云原生·架构
hyy27952276845 小时前
自动化运维之k8s——Kubernetes集群部署、pod、service微服务、kubernetes网络通信
运维·kubernetes·自动化
Java水解5 小时前
MySQL 中的 UPDATE 语句
后端·mysql
lovebugs5 小时前
🚀 Kubernetes核心命令详解:Java开发者必备指南
java·后端·kubernetes
Crazy________6 小时前
03MySQL——DCL权限控制,四种常用函数解析
sql·mysql
手握风云-7 小时前
MySQL数据库精研之旅第十一期:打造高效联合查询的实战宝典(二)
数据库·mysql
Jasonakeke8 小时前
【重学MySQL】八十九、窗口函数的分类和使用
数据库·mysql
hhzz8 小时前
Kubernetes 的20 个核心命令分类详解
云原生·容器·kubernetes