docker安装PXC集群
- 创建数据卷
- 创建集群专用网络
- 创建证书
主流mysql高可用的方式有以下几种
准备三台服务器
host | IP | 说明 |
---|---|---|
node1 | 192.168.31.130 | PXC集群1 |
node2 | 192.168.31.131 | PXC集群2 |
node3 | 192.168.31.132 | PXC集群3 |
创建docker swarm集群
主节点node1执行
#docker swarm init --advertise-addr "节点IP"
docker swarm init --advertise-addr "192.168.31.130"
这里由于我已经初始化过,所以使用
#查看加入主节点的token
docker swarm join-token worker
复制如上命令到node2,node3节点依次执行即可
查询当前swarm集群所有节点数量
docker node ls
不出意外应该是如图中效果,如果出现加入失败,需要检查2377端口是否放行
创建数据卷
新增pxc集群数据卷,因为最低三节点所以新建三个。
#pxc-node1
docker volume create pxc_cluster_node1
#pxc-node2
docker volume create pxc_cluster_node2
#pxc-node3
docker volume create pxc_cluster_node3
创建集群专用网络
创建pxc容器网络段(Docker Swarm多机)
#--driver overlay --attachable 表示创建swarm集群网络且不是service的容器也能加入此网络
docker network create --driver overlay --attachable --subnet=192.169.0.0/24 pxc_cluster_network
创建证书
创建 MySQL 证书(重要:pxc8.0默认开启了同步加密方式需要每个node节点配置一模一样的证书才能通过认证。参考加密PXC流量
创建一个 ~/pxc-docker-test/config 目录。
mkdir -p ~/pxc-docker-test/config
进入config目录新增一个custom.cnf文件并将以下内容填入
[mysqld]
ssl-ca = /cert/ca.pem
ssl-cert = /cert/server-cert.pem
ssl-key = /cert/server-key.pem
[client]
ssl-ca = /cert/ca.pem
ssl-cert = /cert/client-cert.pem
ssl-key = /cert/client-key.pem
[sst]
encrypt = 4
ssl-ca = /cert/ca.pem
ssl-cert = /cert/server-cert.pem
ssl-key = /cert/server-key.pem
创建一个 ~/pxc-docker-test/cert目录用来生成自签名SSL证书。
mkdir -m 777 -p ~/pxc-docker-test/cert
使用官方镜像生成证书到~/pxc-docker-test/cert目录中
docker run --name pxc-cert --rm -v ~/pxc-docker-test/cert:/cert percona/percona-xtradb-cluster:8.0 mysql_ssl_rsa_setup -d /cert
此时/root/pxc-docker-test/cert目录已经生成了证书。将/root/pxc-docker-test目录复制到所有node节点中。
开始创建pxc8.0集群
创建pxc-node1(又称为引导节点) 并加入pxc容器网络
docker run -d \
--net=pxc_cluster_network \
-e MYSQL_ROOT_PASSWORD=test1234# \
-e CLUSTER_NAME=pxc-cluster01 \
--name=pxc_node_1 \
-v pxc_cluster_node1:/var/lib/mysql \
-v ~/pxc-docker-test/cert:/cert \
-v ~/pxc-docker-test/config:/etc/percona-xtradb-cluster.conf.d \
# 端口映射出来
-p 3306:3306 -p 4567:4567 -p 4444:4444 -p 4568:4568 \
--privileged \
percona/percona-xtradb-cluster:8.0
环境变量解释
CLUSTER_NAME:pxc集群名称,每个节点的集群名称要完全一致!!!
注意事项:需要确保node1节点已经完全创建成功,才能连接其他节点,因为其余节点需要加入node1进行同步,对于node2启动时就要开始同步node1的数据了。如果node1没起来就会因为报找不到node1也起不来。(需要确保所有Node节点都在同一个网络)
创建pxc-node2,并加入node1
docker run -d \
--net=pxc_cluster_network \
-e MYSQL_ROOT_PASSWORD=test1234# \
#pxc集群名称,每个节点的集群名称要完全一致 \
-e CLUSTER_NAME=pxc-cluster01 \
# 表示加入上面那个第一个节点并开始同步node1节点的所有数据 \
-e CLUSTER_JOIN=pxc_node_1 \
--name=pxc_node_2 \
#将pxc的mysql数据文件挂载到数据卷v1 \
-v pxc_cluster_node2:/var/lib/mysql \
#将创建好的mysql证书挂载到pxc中 \
-v ~/pxc-docker-test/cert:/cert \
#挂载mysql配置文件 \
-v ~/pxc-docker-test/config:/etc/percona-xtradb-cluster.conf.d \
# 端口映射出来 \
-p 3307:3306 -p 5567:4567 -p 5444:4444 -p 5568:4568 \
--privileged \
percona/percona-xtradb-cluster:8.0
环境变量解释
CLUSTER_JOIN:表示加入上面那个第一个节点并开始同步node1节点的所有数据
创建pxc-node3,并加入node1
docker run -d \
--net=pxc_cluster_network \
-e MYSQL_ROOT_PASSWORD=test1234# \
#pxc集群名称,每个节点的集群名称要完全一致
-e CLUSTER_NAME=pxc-cluster01 \
# 表示加入上面那个第一个节点并开始同步node1节点的所有数据
-e CLUSTER_JOIN=pxc_node_1 \
--name=pxc_node_3 \
#将pxc的mysql数据文件挂载到数据卷v1
-v pxc_cluster_node3:/var/lib/mysql \
#将创建好的mysql证书挂载到pxc中
-v ~/pxc-docker-test/cert:/cert \
#挂载mysql配置文件
-v ~/pxc-docker-test/config:/etc/percona-xtradb-cluster.conf.d \
# 端口映射出来
-p 3308:3306 -p 5577:4567 -p 5544:4444 -p 5668:4568 \
--privileged \
percona/percona-xtradb-cluster:8.0
验证创建完毕的三节点数据
随便在一个节点新增数据库后,都会实时同步
模拟一个节点直接死机
手动杀死node2节点
去node1节点查询集群数量
可以发现cluster_size变成了两个
从node3节点新增一个表(模拟一个节点宕机后,其他节点正常访问的情况)
可以看到正常同步,需要注意pxc集群的存活数量需要大于总节点数量的一半才可以正常工作。
恢复pxc-node2节点,看看丢失的数据会不会回来,这里我们回想一下由于我们的node2节点的数据存放在数据卷:pxc_cluster_node2 中 所以重新创建node2节点并把以前的数据卷挂载进来。
docker run -d \
--net=pxc_cluster_network \
-e MYSQL_ROOT_PASSWORD=test1234# \
#pxc集群名称,每个节点的集群名称要完全一致
-e CLUSTER_NAME=pxc-cluster01 \
# 加入最新的节点名称
-e CLUSTER_JOIN=pxc_node_1 \
--name=pxc_node_222222222 \
#将以前pxc的mysql数据文件挂载到数据卷v1
-v pxc_cluster_node2:/var/lib/mysql \
#将创建好的mysql证书挂载到pxc中
-v ~/pxc-docker-test/cert:/cert \
#挂载mysql配置文件
-v ~/pxc-docker-test/config:/etc/percona-xtradb-cluster.conf.d \
# 端口映射出来
-p 3307:3306 -p 5567:4567 -p 5444:4444 -p 5568:4568 \
--privileged \
percona/percona-xtradb-cluster:8.0
这里注意恢复节点的CLUSTER_JOIN属性一定是最后挂掉的节点名称或当前在线上的节点名称任一,如果是原来的node1挂了,那这里就指定pxc_node_1或pxc_node_2加入,因为恢复的节点大概率与当前存活节点数据不一致,也就是数据算是旧版本的了,所以一启动就立马同步最新节点的全量数据。
容器启动不久后,可以看到恢复的node2节点也已经同步了宕机后所产生的新数据。
再次查询节点数量
可以看到已经恢复正常。
创建haproxy用于检测mysql心跳的用户
CREATE USER 'haproxy'@'%' IDENTIFIED BY '';
安装haproxy容器
docker pull haproxy:1.9.6
新增haproxy.cfg文件,并将以下内容写入文件。
global
#工作目录
chroot /usr/local/etc/haproxy
#日志文件,使用rsyslog服务中local5日志设备(/var/log/local5),等级info
log 127.0.0.1 local5 info
#守护进程运行
daemon
defaults
log global
mode http
#日志格式
option httplog
#日志中不记录负载均衡的心跳检测记录
option dontlognull
option redispatch #当serverId对应的服务器挂掉后,强制定向到其他健康的服务器
option abortonclose #当服务器负载很高的时候,自动结束掉当前队列处理比较久的链接
option dontlognull #日志中不记录负载均衡的心跳检测记录
#连接超时(毫秒)
timeout connect 5000
#客户端超时(毫秒)
timeout client 50000
#服务器超时(毫秒)
timeout server 50000
retries 2 #两次连接失败就认为是服务器不可用,也可以通过后面设置
#haproxy监控界面
listen admin_stats
#监控界面的访问的IP和端口
bind 0.0.0.0:7777
#访问协议
mode http
#URI相对地址
stats uri /dbs
#统计报告格式
stats realm Global\ statistics
#haproxy监控界面 登陆帐户信息
stats auth admin:admin123
#数据库负载均衡
listen proxy-mysql
#要提供给业务系统访问的IP和端口
bind 0.0.0.0:33060
#网络协议
mode tcp
#负载均衡算法(轮询算法)
#轮询算法:roundrobin
#权重算法:static-rr
#最少连接算法:leastconn
#请求源IP算法:source
balance roundrobin
#日志格式
option tcplog
#在MySQL中创建一个没有权限的haproxy用户,密码为空。Haproxy使用这个账户对MySQL数据库心跳检测
option mysql-check user haproxy
server MySQL_1 192.168.31.130:3306 check weight 1 maxconn 2000
server MySQL_2 192.168.31.130:3307 check weight 1 maxconn 2000
server MySQL_3 192.168.31.130:3308 check weight 1 maxconn 2000
#使用keepalive检测死链
option tcpka
运行haproxy容器
docker run -it -d -p 4001:7777 -p 4002:33060 \
-v /root/haproxy:/usr/local/etc/haproxy \
--name haproxy_test --privileged haproxy:1.9.6
访问haproxy页面即可看到监控情况
http://192.168.31.131:4001/dbs