利用Docker部署PXC和Redis集群实战

89 阅读2分钟

PXC集群

systemctl stop firewalld.service

vi /etc/selinux/config

找到SELINUX=disabled,按i进入编辑模式,通过修改该参数关闭SELinux

docker pull percona/percona-xtradb-cluster:5.7.21

docker tag percona/percona-xtradb-cluster:5.7.21 pxc

docker network create -d bridge mysql_net1

docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=eszEDCrdx@#! -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=eszEDCrdx@#! -v /home/docker_pro/pxc_mysql_cluster/v1:/var/lib/mysql -v /home/docker_pro/pxc_mysql_cluster/backup:/data --privileged --name=node1 --network=mysql_net1 pxc

docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=eszEDCrdx@#! -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=eszEDCr!dx@# -v /home/docker_pro/pxc_mysql_cluster/v2:/var/lib/mysql -v /home/docker_pro/pxc_mysql_cluster/backup:/data --privileged --name=node2 --network=mysql_net1 pxc

docker run -d -p 3308:3306 -e MYSQL_ROOT_PASSWORD=eszEDCrdx@#! -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=eszEDCrdx@#! -v /home/docker_pro/pxc_mysql_cluster/v3:/var/lib/mysql -v /home/docker_pro/pxc_mysql_cluster/backup:/data --privileged --name=node3 --network=mysql_net1 pxc

docker run -d -p 3309:3306 -e MYSQL_ROOT_PASSWORD=eszEDCrdx@#! -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=eszEDCrdx@#! -v /home/docker_pro/pxc_mysql_cluster/v4:/var/lib/mysql -v /home/docker_pro/pxc_mysql_cluster/backup:/data --privileged --name=node4 --network=mysql_net1 pxc

docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=eszEDCrdx@#! -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=eszEDCrdx@#! -v /home/docker_pro/pxc_mysql_cluster/v5:/var/lib/mysql -v /home/docker_pro/pxc_mysql_cluster/backup:/data --privileged --name=node5 --network=mysql_net1 pxc

# 连接主MYSQL 创建用户,每个节点都需要创建

CREATE USER 'haproxy'@'%' IDENTIFIED BY '';

docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)

mkdir /home/docker_pro/pxc_mysql_cluster/haproxy && vim /home/docker_pro/pxc_mysql_cluster/haproxy/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

#连接超时(毫秒)

timeout connect 5000

#客户端超时(毫秒)

timeout client 50000

#服务器超时(毫秒)

timeout server 50000

#监控界面

listen admin_stats

#监控界面的访问的IP和端口

bind 0.0.0.0:8888

#访问协议

mode http

#URI相对地址

stats uri /dbs

#统计报告格式

stats realm Global\ statistics

#登陆帐户信息(监控软件)

stats auth admin:abc123456

#数据库负载均衡

listen proxy-mysql

#访问的IP和端口

bind 0.0.0.0:3306

#网络协议

mode tcp

#负载均衡算法(轮询算法)

#轮询算法:roundrobin

#权重算法:static-rr

#最少连接算法:leastconn

#请求源IP算法:source

balance roundrobin

#日志格式

option tcplog

#在MySQL中创建一个没有权限的haproxy用户,密码为空。Haproxy使用这个账户对MySQL数据库心跳检测

option mysql-check user haproxy

server MySQL_1 172.19.0.2:3306 check weight 1 maxconn 2000

server MySQL_2 172.19.0.3:3306 check weight 1 maxconn 2000

server MySQL_3 172.19.0.4:3306 check weight 1 maxconn 2000

server MySQL_4 172.19.0.5:3306 check weight 1 maxconn 2000

server MySQL_5 172.19.0.6:3306 check weight 1 maxconn 2000

#使用keepalive检测死链

option tcpka

docker pull haproxy:2.1

docker run -it -d --rm -p 4001:8888 -p 4002:3306 -v /home/docker_pro/pxc_mysql_cluster/haproxy:/usr/local/etc/haproxy --name h1 --privileged --network=mysql_net1 haproxy:2.1

docker exec -it h1 bash

haproxy -f /usr/local/etc/haproxy/haproxy.cfg

docker run -it -d --rm -p 4003:8888 -p 4004:3306 -v /home/docker_pro/pxc_mysql_cluster/haproxy:/usr/local/etc/haproxy --name h2 --privileged --network=mysql_net1 haproxy:2.1

docker exec -it h2 bash

haproxy -f /usr/local/etc/haproxy/haproxy.cfg

docker exec -it h1 bash

apt-get -y update && apt-get install -y vim && apt-get install -y keepalived

vim /etc/keepalived/keepalived.conf

# IP 需要和MYSQL集群一致,自定义一个同网段不可用到的IP

vrrp_instance VI_1 {

state MASTER

interface eth0

virtual_router_id 51

priority 100

advert_int 1

authentication {

auth_type PASS

auth_pass 123456

}

virtual_ipaddress {

172.19.0.201

}

}

service keepalived start

docker exec -it h2 bash

apt-get -y update && apt-get -y install vim && apt-get install -y keepalived

vim /etc/keepalived/keepalived.conf

# IP 需要和MYSQL集群一致,自定义一个同网段不可用到的IP

vrrp_instance VI_1 {

state MASTER

interface eth0

virtual_router_id 51

priority 100

advert_int 1

authentication {

auth_type PASS

auth_pass 123456

}

virtual_ipaddress {

172.19.0.201

}

}

service keepalived start

#宿主机执行ping命令

ping 172.19.0.201

#退出容器 宿主机执行命令

yum -y install keepalived

vim /etc/keepalived/keepalived.conf

vrrp_instance VI_1 {

state MASTER

interface em1 # ifconfig 网卡名称

virtual_router_id 51

priority 100

advert_int 1

authentication {

auth_type PASS

auth_pass 1111

}

virtual_ipaddress {

172.18.116.150 # 创建与主机网段一致的IP

}

}

virtual_server 172.18.116.150 8888 {

delay_loop 3

lb_algo rr

lb_kind NAT

persistence_timeout 50

protocol TCP

real_server 172.19.0.201 8888 { # 转发docker虚拟IP 容器端口

weight 1

}

}

virtual_server 172.18.116.150 3306 { # 接收转发访问主机虚拟IP转发docker IP

delay_loop 3

lb_algo rr

lb_kind NAT

persistence_timeout 50

protocol TCP

real_server 172.19.0.201 3306 { # docker keep 地址

weight 1

}

}

service keepalived start

ping 172.18.116.150

连接 mysql 172.18.116.150 root 测试是否正常连接

第一次备份 需要全量备份 后续每天进行增量备份

#进入node1容器

docker exec -it node1 bash

#更新软件包

apt-get update

#安装热备工具

apt-get install percona-xtrabackup-24

#全量热备

innobackupex --user=root --password=eszEDCrdx@#! /data/backup/full

#冷还原

冷还原数据 停止其余4个节点,并删除节点

docker stop node2

docker stop node3

docker stop node4

docker stop node5

docker rm node2

docker rm node3

docker rm node4

docker rm node5

node1容器中删除MySQL的数据

#删除数据

rm -rf /var/lib/mysql/*

#清空事务

innobackupex --user=root --password=eszEDCrdx@#! --apply-back /data/backup/full/2018-04-15_05-09-07/

#还原数据

innobackupex --user=root --password=eszEDCrdx@#! --copy-back /data/backup/full/2018-04-15_05-09-07/

# 删掉一个容器,重新启动时,需要指定加入哪个集群CLUSTER_JOIN=任意一个节点名称

docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -v /home/docker_pro/pxc_mysql_cluster/v1:/var/lib/mysql -v /home/docker_pro/pxc_mysql_cluster/backup:/data --privileged -e CLUSTER_JOIN=node2 --name=node1 --network=mysql_net1 pxc

# PXC集群在运行的状态下,在宿主机上直接关机,或者停止Docker服务

找到映射文件查看grastate.dat safe_to_bootstrap: 1 的节点,先启动。如果都是0 挑选其中一个节点修改为1 进行启动

Redis集群

docker如果使用bridge模式网络,即容器和宿主机有各自独立的网段,宿主机是192.168.0.1的网段,而虚拟机则是172.17.0.1的网段;由于所有的集群容器都是在一台宿主机上,使用的同一个网卡,因此,在宿主机下访问这个集群是没有任何问题的;但是(这里要翻车了),如果我们使用其他局域网的ip(如192.168.1.100)访问,就会出现连接不上的情况;为什么会出现这样的情况呢,简单说明一下,上面我们添加集群节点的时候,是使用172.17.0.4 —172.17.0.9这个容器的ip加入的,虽然启动容器的时候,容器和宿主机是有做端口映射的,但实际在redis内部切换集群节点的时候是访问的172.17.0.1这个网段的ip,因此就会出现比如192.168.1.100这台访问集群的时候,其实连接的是172.17.0.4—172.17.0.9这个之间的ip,如果使用 redis集群 的项目跟集群不在一台服务器上,那么项目是没法使用集群的,因为是访问不通的。这样的方式搭建集群,其实一点作用都没有,既没有解决高可用,也没有解决负载的问题,肯定是使用不同的几台机器

image.png

一种解决方案是让Docker使用 host模式 的网络连接类型,Docker在使用host模式下创建的容器是没有自己独立的网络命名空间的,是跟物理机共享一个网络空间,进而可以共享物理机的所有端口与IP,这样就可以让公共网络直接访问容器了,尽管这种方式有安全隐患,但目前来说还没找到其他可行性模式。

每个 Redis 集群节点都需要打开两个 TCP 连接。一个用于为客户端提供服务的正常 Redis TCP 端口,例如 6379。还有一个基于 6379 端口加 10000 的端口,比如 16379。

第二个端口用于集群总线,这是一个使用二进制协议的节点到节点通信通道。节点使用集群总线进行故障检测、配置更新、故障转移授权等等。客户端永远不要尝试与集群总线端口通信,与正常的 Redis 命令端口通信即可,但是请确保防火墙中的这两个端口都已经打开,否则 Redis 集群节点将无法通信。或关闭防火墙

# 单机环境下创建3主3从

mkdir -p /home/docker_pro/redis_cluster

cd /home/docker_pro/redis_cluster

docker network create -d bridge redis_net1

vi redis-cluster.tmpl

#需要剔除注释,方便下边脚本使用

port ${PORT}

requirepass eszEDCrdx342

masterauth eszEDCrdx342

protected-mode no

daemonize no

appendonly yes

cluster-enabled yes

cluster-config-file nodes.conf

cluster-node-timeout 15000

cluster-announce-ip 172.18.116.25

cluster-announce-port ${PORT}

cluster-announce-bus-port 1${PORT}

------------------以下解释----------------------------------

port ${PORT} # 端口

requirepass eszEDCrdx342 # redis密码

masterauth eszEDCrdx342 # redis从去连接redis主使用的requirepass参数密码

protected-mode no # no外部网络可以直接访问,默认是yes,禁止公网访问redis cache( 没有bind IP\没有设置访问密码)

daemonize no # yes:以后台进程运行,no前台

appendonly yes # 开启AOF模式

cluster-enabled yes # 开启集群

cluster-config-file nodes.conf # 集群配置文件

cluster-node-timeout 15000 # 超时时间

cluster-announce-ip 172.18.116.25 # 集群节点 IP,这里需要特别注意一下,如果要对外提供访问功能,需要填写宿主机的 IP,如果填写 Docker 分配的 IP(172.x.x.x),可能会导致外部无法正常访问集群;

cluster-announce-port ${PORT} # 集群节点映射端口

cluster-announce-bus-port 1${PORT} # 集群节点总线端口

---------------------------------------------------------------------

# 每个 Redis 集群节点都需要打开两个 TCP 连接。一个用于为客户端提供服务的正常 Redis TCP 端口,例如 6379。还有一个基于 6379 端口加 10000 的端口,比如 16379。

# 第二个端口用于集群总线,这是一个使用二进制协议的节点到节点通信通道。节点使用集群总线进行故障检测、配置更新、故障转移授权等等。客户端永远不要尝试与集群总线端口通信,与正常的 Redis 命令端口通信即可,但是请确保防火墙中的这两个端口都已经打开,否则 Redis 集群节点将无法通信。

# 创建shell脚本

vim crete_conf.sh

for port in `seq 6381 6386`; do \

mkdir -p ${port}/conf \

&& PORT=${port} envsubst < redis-cluster.tmpl > ${port}/conf/redis.conf \

&& mkdir -p ${port}/data;\

done

sh crete_conf.sh

# 创建redis容器 `--restart=always`当 Docker 重启时,容器自动启动

vim docker_create_redis.sh

for port in $(seq 6381 6386); do \

docker run -it -d -p ${port}:${port} -p 1${port}:1${port} \

--restart always --name redis-${port} --net redis_net1 --privileged=true\

-v /home/docker_pro/redis_cluster/${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf \

-v /home/docker_pro/redis_cluster/${port}/data:/data \

redis:6.0.8 redis-server /usr/local/etc/redis/redis.conf; \

done

sh docker_create_redis.sh

# 查看每个docker redis IP

docker network inspect redis_net1 | grep -i -E "name|ipv4address"

# 创建 Redis Cluster 集群

# 进入容器

docker exec -it redis-6381 bash

# 切换至指定目录

cd /usr/local/bin

# --cluster-replicas 1 表示为每个master创建一个slave节点,2创建2个slave

redis-cli -a 1234 --cluster create 172.18.0.2:6371 172.18.0.3:6372 172.18.0.4:6373 172.18.0.5:6374 172.18.0.6:6375 172.18.0.7:6376 --cluster-replicas 1

感谢你的观看,如果对你有些帮助的话,可以关注一下~嘿嘿