Docker 部署 MySQL 之 PXC 集群部署【多机多节点】

465

背景

最近在进行 MySQL 集群搭建测试的研究中,对于业界主流方案自然不能跳过,在此,整理成完整的文章,希望道友能得到参考价值 …

此集群基于 docker 构建,不熟悉 docker 的朋友可以阅读Docker全家桶简介

  • PXC 集群介绍:PXC 是基于 Galera 协议的高可用集群方案
    可以实现多个节点间的数据同步复制以及读写,并且可保障数据库的服务高可用及数据强一致性。

  • 环境

CentOS版本: CentOS Linux release 7.9.2009 (Core)
MySQL 版本: 5.7.32
PXC 版本 : 	percona/percona-xtradb-cluster 最新

如需单机部署方案,请参考单机多节点方案

前期准备

  • Docker Swarm 环境

已对三台主机进行 swarm 集群。docker集群方案参考,Docker Swarm 集群环境搭建及弹性服务部署,博文后面也会单独讲到 swarm 集群的搭建。

  • 三台主机
IP端口容器角色
192.168.80.2219001pn1Master 节点
192.168.80.2229001pn2worker 节点
192.168.80.2239001pn3worker 节点
  • 开启四个 PXC 环境所涉及的端口(可选)

如果服务器没有防火墙措施可以跳过这一步。

3306:	# mysql 实例端口
4567:	# PXC cluster 相互通讯的端口
4444:	# 用于 SST(State Snapshot Transfer): 全量传输
4568:	# 用于 IST(Incremental state Transfer):增量传输传送
  • 部署前建议(可选)

关闭 SELINUX、如有 MYSQL 服务请将 MySQL 数据库服务停止。

安全增强型 Linux(Security-Enhanced Linux)SELinux 主要由美国国家安全局开发

一种方法【荐】,永久关闭 Selinux
vi /etc/selinux/configSELINUX 属性值设置成 disabled,然后 reboot 重启

另一种方法,或者执行命令 Linux 临时关闭 Selinux: setenforce 0

  • 配置 ntp 服务,确保时间同步
 [root@localhost ~]# yum -y install ntp ntpdate
 [root@localhost ~]# ntpdate 0.asia.pool.ntp.org
 [root@localhost ~]# hwclock --systohc
 [root@localhost ~]# date
 2021年 11月 08日 星期五 09:54:23 CST

创建 Docker Swarm 集群

为了使三台服务器进行连接,如果没有安装 docker,需要先执行命令: yum install -y docker

查看 docker 版本: docker -v
docker 的启动/关闭/重启:service docker startservice docker stopservice docker restart

然后,要在各个服务器中,开放所需的三个端口号(可选),未开启防火墙可跳过。
(开放后重启 docker 服务 : service docker restart)
2377:用于集群管理通信的TCP端口
4789:用于容器覆盖网络
7946:用于容器网络发现

firewall-cmd --zone=public --add-port=2377/tcp --permanent
firewall-cmd --zone=public --add-port=4789/tcp --permanent
firewall-cmd --zone=public --add-port=4789/udp --permanent
firewall-cmd --zone=public --add-port=7946/tcp --permanent
firewall-cmd --zone=public --add-port=7946/udp --permanent
firewall-cmd --reload

注意,以上的操作,要对三台虚拟机,全部进行配置!!!选择一台服务器作为管理集群的服务器,此处,我选择的是 192.168.80.221

运行命令:

docker swarm init

则会得到一个形如下面的管理者口令

[root@localhost /]# docker swarm init
Swarm initialized: current node (g706owlgszx493xhpsb44k9t0) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join \
    --token SWMTKN-1-4ea65xsm8xsyhrmn42qg125b10dxtcmt80gnuijnnskddces2n-6fok68mg86nf5lkah1wnnj6ra \
    192.168.80.221:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

然后在其他两个虚拟服务器中( 192.168.80.222192.168.80.223),在 docker 服务启动的前提下,都要执行上面的口令。

image.png

查看 swarm 集群的所有节点,只能在管理主机下192.168.80.221才能查看。

docker node ls

image.png

如果要删除一个节点,执行命令为 :docker node rm -f [节点的ID]
如果要解散 swarm 集群
先再 【manager 节点】上删除 所有 【worker 节点】
再强制删除自己,执行:docker swarm leave -f
最后,还需要在各个 【worker 节点】主机上执行:docker swarm leave

创建 Docker 虚拟网络

出于安全考虑,给 PXC 集群创建 Docker 内部虚拟网络,用于 PXC 集群独立使用
此处我自定义的虚拟网络名称为:swarm_mysql

docker network create -d overlay --attachable swarm_mysql

查看虚拟网络:

docker network inspect swarm_mysql

所有虚拟网络:

docker network ls

删除虚拟网络:

docker network rm swarm_mysql

image.png

搭建 PXC 集群

拉取镜像

PXC 官方提供了 Docker 镜像,所以我们可以很方便的搭建 PXC 集群

Docker 仓库中的 PXC官方镜像:https://hub.docker.com/r/percona/percona-xtradb-cluster

  • 此处直接安装最新的 PXC 镜像
docker pull percona/percona-xtradb-cluster

创建分布式容器

  • 第一个启动的 PXC 节点是【主节点】,它要初始化 PXC 集群。
  • PXC 启动之后,就没有【主节点】的角色了,此处只是随机选择了【192.168.80.221】,其实任意一个都可以。
  • 博主设置的是以 9001端口访问 集群,所以记得开启端口(也可以选用 3306 等任意不冲突的端口!)
  1. 创建主节点容器 【192.168.80.221

同时要记住:创建主节点之后,稍等一会儿才能连接(大概一两分钟)

docker run -d --name=pn1 --net=swarm_mysql -p 9001:3306 -v pnv1:/var/lib/mysql --privileged -e MYSQL_ROOT_PASSWORD=mT123456 -e CLUSTER_NAME=PXC1 -e XTRABACKUP_PASSWORD=mT123456 pxc

等待数据库启动完成 ,自动执行,正常情况下会发现 MySQL 服务启动了。此时,可以查看虚拟网络 : docker network inspect swarm_mysql,会发现,主节点ip成功配置进去了:

image.png

  1. 创建从节点容器

必须主节点可以访问了,才能创建从节点,否则会闪退!

加入第二个节点 【192.168.80.222

docker run -d --name=pn2 --net=swarm_mysql -p 9001:3306 -v pnv2:/var/lib/mysql --privileged -e MYSQL_ROOT_PASSWORD=mT123456 -e CLUSTER_NAME=PXC1 -e XTRABACKUP_PASSWORD=mT123456 -e CLUSTER_JOIN=pn1 pxc

从第二个节点创建开始,需要增加 -e CLUSTER_JOIN 参数,表示与【主节点】容器同步
此处的命令,与创建【主节点】不同的地方,也只有参数 --name(节点名)、-v(数据卷),其他酌情自定义

image.png

稍等一两分钟
可以查看节点状态:docker ps -a

image.png

  1. 加入第三个节点 【192.168.80.223

参考上面,则第三个节点创建命令为:

docker run -d --name=pn3 --net=swarm_mysql -p 9001:3306 -v pnv3:/var/lib/mysql --privileged -e MYSQL_ROOT_PASSWORD=mT123456 -e CLUSTER_NAME=PXC1 -e XTRABACKUP_PASSWORD=mT123456 -e CLUSTER_JOIN=pn1 pxc

可以查看节点状态:docker ps -a

image.png

  1. 查看挂载情况

需要进入 【主节点】的 mysql,运行查询语句:

show status like 'wsrep%';

测试发现,进入任意一个节点,都可以执行查询操作
于是,我在节点2 [192.168.80.221] 的查询结果如下:
可以看到 "wsrep_incoming_addresses" 的值就是我们三个容器的IP地址
对于其他参数解释,建议可以参考 —— 【MySQL Galera cluster集群常用参数说明

image.png

另外,我发现,在节点顺利启动后,可以通过查看虚拟网络信息,确认挂载情况

操作命令:

docker network inspect swarm_mysql
[root@localhost ~]# docker network inspect swarm_mysql
[
    {
        "Name": "swarm_mysql",
        "Id": "ir06z2hjlfduliphte8chwrop",
        "Created": "2021-01-14T15:46:33.522125189+08:00",
        "Scope": "swarm",
        "Driver": "overlay",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "10.0.0.0/24",
                    "Gateway": "10.0.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": true,
        "Containers": {
            "4d09f2b49a771f0976ea6379d1585059b1f54041ccdf975d540fc9e319258d3f": {
                "Name": "pn1",
                "EndpointID": "27662762e11842e96125cdca03a66941c7fe4c2574eea6a7cd29ed8a4b8cfea0",
                "MacAddress": "02:42:0a:00:00:02",
                "IPv4Address": "10.0.0.2/24",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.driver.overlay.vxlanid_list": "4097"
        },
        "Labels": {},
        "Peers": [
            {
                "Name": "localhost.localdomain-bedc99cf44f1",
                "IP": "192.168.80.221"
            },
            {
                "Name": "localhost.localdomain-986f2f07e8b7",
                "IP": "192.168.80.222"
            },
            {
                "Name": "localhost.localdomain-4a1e3925814d",
                "IP": "192.168.80.223"
            }
        ]
    }
]

集群同步验证

验证是极为简单的,直接在任意节点数据库连接上,创建 db、创建数据表、操作数据。

然后,正常情况下,其他节点刷新后,会发现对应的数据同步变化。