mysql 双主+keepalived模式搭建
两台 机器 构建双主 模式 主要 是 双主 数据一致性
192.168.0.176 (主)
192.168.0.179 (主)
两台 宿主机器 都需要创建文件夹 用于挂载
mkdir mysql
cd mysql
mkdir config
chmod -R +777 /home/admin1/yyx/mysql/

两台机器 同时 拉取镜像 docker pull mysql

192.168.0.176 机器 容器启动
docker run -d --name m1 -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=123456 -e TZ="Asia/Shanghai" \ -v /home/admin1/yyx/mysql/config:/etc/mysql/conf.d mysql \ --authentication_policy=mysql_native_password

启动后进入 容器内部
docker exec -it m1 mysql -uroot -p123456

需要注意的是每台上要重置一下server_uuid,否则后面的主从复制会出错,直接删掉auto.cnf让MySQL自动生成即可
rm -rf /var/lib/mysql/auto.cnf;
查看 偏移量
show master status;
执行完毕后登陆MySQL创建同步用户
DROP USER 'repl'@'%' ; CREATE USER 'repl'@'%' IDENTIFIED BY 'repl'; GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%'; flush privileges;

查看 插件 show plugins;


可以看到插件不包含
rpl_semi_sync_source_enabled=1
rpl_semi_sync_replica_enabled=1
两个插件
此时退出 mysql
exit
在宿主机上 config 文件夹 创建 my.cnf文件

文件内容如下
[mysqld] user=mysql character-set-server=utf8mb4 collation-server=utf8mb4_general_ci log-bin=mysql-bin-master server_id=1 log_replica_updates=1 plugin-load="rpl_semi_sync_source=semisync_source.so;rpl_semi_sync_replica=semisync_replica.so" rpl_semi_sync_source_enabled=1 rpl_semi_sync_replica_enabled=1 [client] default-character-set=utf8mb4
server_id=1 这个配置 每台机器不一样的
og-slave-updates=1:这个参数需要注意下,互为主从的时候两台都需要写入自己从对方取到的数据到binlog里面
plugin-load=“rpl_semi_sync_source=semisync_source.so;rpl_semi_sync_replica=semisync_replica.so” rrpl_semi_sync_source_enabled=1
rpl_semi_sync_replica_enabled=1
主从半同步都需开启,因为是互为主

重启 容器 m1

进入 容器内部
docker exec -it m1 mysql -uroot -p123456
查看插件
show plugins;


发现个插件 已经安装上了
192.168.0.179 机器
其实步骤 与上面 一样的
不同的是my.cnf 文件内容
[mysqld] user=mysql character-set-server=utf8mb4 collation-server=utf8mb4_general_ci log-bin=mysql-bin-master server_id=2 log_replica_updates=1 plugin-load="rpl_semi_sync_source=semisync_source.so;rpl_semi_sync_replica=semisync_replica.so" rpl_semi_sync_source_enabled=1 rpl_semi_sync_replica_enabled=1 [client] default-character-set=utf8mb4
server_id=2 这个配置不能一样的

===================================================分割=====================
下面来配置 互为 主从复制的 配置
192.168.0.176 (主)
进入 容器 中
查看状态 记录偏移量


将 上面的 两个值记录下下来
执行 下面
STOP SLAVE; RESET SLAVE; CHANGE MASTER TO MASTER_HOST='192.168.0.179', MASTER_USER='repl', MASTER_PASSWORD='repl', MASTER_LOG_FILE='mysql-bin-master.000001', MASTER_LOG_POS=157; START SLAVE; SHOW SLAVE STATUS\G;
上面 文件的 内容 就是 176 为179的 从节点 日志文件 是 MASTER_LOG_FILE='mysql-bin-master.000001', 位置是 MASTER_LOG_POS=157;
查看 是否 挂载成功 SHOW SLAVE STATUS\G;

再分别看下半同步是否开启
show variables like 'rpl_semi_sync_source_enabled';
show variables like 'rpl_semi_sync_replica_enabled';

接下来 是 192.168.0.179 节点
步骤与上面一样
配置文件 有所不同
STOP SLAVE; RESET SLAVE; CHANGE MASTER TO MASTER_HOST='192.168.0.176', MASTER_USER='repl', MASTER_PASSWORD='repl', MASTER_LOG_FILE='mysql-bin-master.000001', MASTER_LOG_POS=157; START SLAVE; SHOW SLAVE STATUS\G;
上面 文件的 内容 就是 179 为176的 从节点 日志文件 是 MASTER_LOG_FILE='mysql-bin-master.000001', 位置是 MASTER_LOG_POS=157;
查看 是否 挂载成功 SHOW SLAVE STATUS\G;

show variables like 'rpl_semi_sync_source_enabled';show variables like 'rpl_semi_sync_replica_enabled';

可以看到 两台 机器全部开启了
最后在自行测试下载Master主机上面写数据Master备机能否同步,反过来再测试下
在某一台宕机后另外一台第一次插入会等10s左右,说明半同步复制也是开启的,第二次插入就会退化了异步复制了,并且在宕机机器恢复后会自动同步缺失的数据。
show variables like 'server_id';
然后退出 exit
================================================分割==================================
接下来 是配置 keepalived
安装
注意Keepalived就安装在Docker运行的宿主机上面,安装在docker里面IP无法绑定(亲测)
两台 机器都需要安装
yum install -y keepalived

我们 需要 在 docker 容器外 连接 docker 容器 中的 mysql 所以 需要 安装 mysql 客户端
安装MySQL客户端
主要目的 是 需要 在容器外访问 容器内的 mysql
wget https://dev.mysql.com/get/mysql80-community-release-el7-5.noarch.rpm
rpm -ivh mysql80-community-release-el7-5.noarch.rpm
yum install mysql-community-client
安装的时候 报错了

意思就是 已经 安装了 community-release-el7-10 我们安装的 (community-release-el7-5 版本低 好吧 把我们安装的 删除掉 删除命令 yum remove community-release-el7-5.noarch 因为安装报错7-5没安装上 所以不用删除)
此时修改 我这里 为了记录 修改 下载命令 为 7-10版本
wget https://dev.mysql.com/get/mysql80-community-release-el7-10.noarch.rpm
rpm -ivh mysql80-community-release-el7-10.noarch.rpm
yum install mysql-community-client
好吧 安装 以上的 命令 再 安装 一次 (其实我这里 安装 了7-10 不用再安装了 为了记录 再弄一次)



执行 这个 命令 再次报错 yum install mysql-community-client

参考解决 麒麟操作系统安装MySQL报错信息_阿干tkl的博客-CSDN博客
解决 :
执行
wget http://mirror.centos.org/centos/8-stream/AppStream/x86_64/os/Packages/compat-openssl10-1.0.2o-4.el8.x86_64.rpm

执行
rpm -ivh compat-openssl10-1.0.2o-4.el8.x86_64.rpm --nodeps

再次执行 安装 命令 yum install mysql-community-client 又报错了

解决
安装 sudo yum install epel-release

安装 sudo yum install openssl10

再次 安装 yum install mysql-community-client
终于可以 了 哈哈 好艰难

尝试登录 看看
mysql -uroot -p123456 -h192.168.0.179

登录 成功了 哈哈哈
我的 192.168.0.176 也出现同样的错误 了 解决方式 与上面一样 这样 就开始部署 keepalived
keepalived原始配置文件
! Configuration File for keepalived global_defs { notification_email { acassen@firewall.loc failover@firewall.loc sysadmin@firewall.loc } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 192.168.200.1 smtp_connect_timeout 30 router_id LVS_DEVEL vrrp_skip_check_adv_addr vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.200.16 192.168.200.17 192.168.200.18 } } virtual_server 192.168.200.100 443 { delay_loop 6 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP real_server 192.168.201.100 443 { weight 1 SSL_GET { url { path / digest ff20ad2481f97b1754ef3e12ecd3a9cc } url { path /mrtg/ digest 9b3a0c85a887a256d6939da88aabd8cd } connect_timeout 3 retry 3 delay_before_retry 3 } } } virtual_server 10.10.10.2 1358 { delay_loop 6 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP sorry_server 192.168.200.200 1358 real_server 192.168.200.2 1358 { weight 1 HTTP_GET { url { path /testurl/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } url { path /testurl2/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } url { path /testurl3/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } connect_timeout 3 retry 3 delay_before_retry 3 } } real_server 192.168.200.3 1358 { weight 1 HTTP_GET { url { path /testurl/test.jsp digest 640205b7b0fc66c1ea91c463fac6334c } url { path /testurl2/test.jsp digest 640205b7b0fc66c1ea91c463fac6334c } connect_timeout 3 retry 3 delay_before_retry 3 } } } virtual_server 10.10.10.3 1358 { delay_loop 3 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP real_server 192.168.200.4 1358 { weight 1 HTTP_GET { url { path /testurl/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } url { path /testurl2/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } url { path /testurl3/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } connect_timeout 3 retry 3 delay_before_retry 3 } } real_server 192.168.200.5 1358 { weight 1 HTTP_GET { url { path /testurl/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } url { path /testurl2/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } url { path /testurl3/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } connect_timeout 3 retry 3 delay_before_retry 3 } } }
- router_id:标识,两台需不一样
- state MASTER:表明这台是Master角色
- priority:优先级,MASTER角色比BACKUP高!
- virtual_router_id:虚拟路由编号,两台需要一致
- 192.168.0.100 dev ens33 label ens33:vip:这就是我们配置的VIP:192.168.0.100
- script /etc/keepalived/chk_mysql.sh:MySQL的检测脚本,定时去检测MySQL进程是否挂掉,如果挂掉,在脚本里面重启之,定时通过interval配置,上面配置的是2s检测一次
- notify /etc/keepalived/kpad_notify.sh:当Keepalived状态发生变化时,会调用该脚本,这也是我们实现Slave(m3)自动挂载Master的关键!!
当Keepalived从BACKUP提升为MASTER时,那么VIP就会漂移到自己身上,这个时候我们只需要将Slave挂载在自己身上即可
Slave的自动挂载Master,我们只需要实现上面这句话的逻辑即可!
好了 不啰嗦了 刚才 已经 安装了 keepalived了 下面修改 配置文件了
cd /etc/keepalived/

192.168.0.176 上的 keepalived.conf 配置文件修改为

我的 网卡 是 en33
keepalived.conf 内容
! Configuration File for keepalived
global_defs {
router_id HA-M1
}
vrrp_script chk_mysql {
script /etc/keepalived/chk_mysql.sh
interval 3
fall 3
rise 2
}
vrrp_instance VI_MYSQL {
state MASTER
interface ens33
virtual_router_id 100
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.0.100 dev ens33 label ens33:vip
}
track_script {
chk_mysql
}
}

chk_mysql.sh 内容
#!/bin/bash MYSQL=/usr/bin/mysql MYSQL_HOST=192.168.0.176 MYSQL_USER=root MYSQL_PASSWORD=123456 CHECK_TIME=3 #mysql is working MYSQL_OK is 1 , mysql down MYSQL_OK is 0 MYSQL_OK=1 function check_mysql_helth (){ $MYSQL -h $MYSQL_HOST -u$MYSQL_USER -p${MYSQL_PASSWORD} -e "show status;" >/dev/null 2>&1 if [ $? = 0 ] ;then MYSQL_OK=1 else MYSQL_OK=0 fi return $MYSQL_OK } while [ $CHECK_TIME -ne 0 ] do let "CHECK_TIME -= 1" check_mysql_helth if [ $MYSQL_OK = 1 ] ; then CHECK_TIME=0 exit 0 fi if [ $MYSQL_OK -eq 0 ] && [ $CHECK_TIME -eq 0 ] then systemctl stop keepalived exit 1 fi sleep 1 done

176 机器配置完毕
测试一下 执行 systemctl start keepalived
又报错了


执行 chmod 644 /etc/keepalived/keepalived.conf
再次 执行启动 systemctl start keepalived

176机器终于成功了 艰难坎坷
==================================配置179
开始配置179
yum install -y keepalived
cd /etc/keepalived/

配置 这俩文件
179 是 备份机器
keepalived.conf 内容
! Configuration File for keepalived
global_defs {
router_id HA-M2
enable_script_security
script_user admin1
}
vrrp_script chk_mysql {
script "/etc/keepalived/chk_mysql.sh"
interval 3
fall 3
rise 2
}
vrrp_instance VI_MYSQL {
state BACKUP
interface ens33
virtual_router_id 100
nopreempt
priority 50
advert_int 1
mcast_src_ip 192.168.0.179
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.0.100 dev ens33 label ens33:vip
}
track_script {
chk_mysql
}
}
priority 50 优先级 低于 176的

chk_mysql.sh 内容
#!/bin/bash
MYSQL=/usr/bin/mysql
MYSQL_HOST=192.168.0.179
MYSQL_USER=root
MYSQL_PASSWORD=123456
CHECK_TIME=3
#mysql is working MYSQL_OK is 1 , mysql down MYSQL_OK is 0
MYSQL_OK=1
function check_mysql_helth (){
$MYSQL -h $MYSQL_HOST -u$MYSQL_USER -p${MYSQL_PASSWORD} -e "show status;" >/dev/null 2>&1
if [ $? = 0 ] ;then
MYSQL_OK=1
else
MYSQL_OK=0
fi
return $MYSQL_OK
}
while [ $CHECK_TIME -ne 0 ]
do
let "CHECK_TIME -= 1"
check_mysql_helth
if [ $MYSQL_OK = 1 ] ; then
CHECK_TIME=0
exit 0
fi
if [ $MYSQL_OK -eq 0 ] && [ $CHECK_TIME -eq 0 ]
then
systemctl stop keepalived
exit 1
fi
sleep 1
done

加权限
chmod -R 644 /etc/keepalived/
chmod 644 /etc/keepalived/chk_mysql.sh
chmod 644 /etc/keepalived/keepalived.conf
然后 启动
systemctl start keepalived
查看状态
systemctl status keepalived.service

报错 健康检查脚本忘了保存了妹的
加上再次启动 systemctl start keepalived
查看状态
systemctl status keepalived.service

终于成功了
到此 176 179 mysql 客户端 和 keepalived 全部部署成功 接下来测试
杀掉Master主机上的Keepalived和mysql:
- VIP会漂移到Master备机上,ifconfig能看到VIP信息
- 通过/tmp/keepalived-state和日志kpad_notify.log观察Keepalived是从BACKUP状态转换为了MASTER状态
- Master备机上做写操作,第一次写会发生半同步等待(10s左右),第二次写会退化成异步复制
启动Master上的Keepalived和mysql:
- ifconfig看下VIP会漂移回来,并且Master备机上的VIP会消失
- 刚才在Master备机上写入的数据同步过来了
- Keepalived的状态是从FAULT转变为BACKUP,最后变成MASTER
新开一个窗口 176窗口
-----执行 命令 tail -f /var/log/messages
妹的 用 navicat 开三个 mysql 连接测试一下 就行 麻烦
三个连接 100 是keepalived 的 虚拟ip 的连接 成功 ,176 179 分别是 docker 容器中的 mysql 连接

测试 我在 100 中新建数据库 和表 176,179 查看 是否也新建了

可以看到 数据库 test1 表 testtable 三台创建没有问题, 176,179 自动同步数据
100上 新增行数据

三台 同步 数据成功
我在 100 上删除数据

测试 没有问题
接下来测试 我把176 docker mysql 容器停止 看看 keepalived 是否 能 漂移


navicat 已经连接不上 176了
100 可以 连接 100 其实 连接的 179 说明keepalived 漂移到179 了 哈哈哈

查看 179 很正常

此时 我将 176 机器的 docker 启动 mysql 容器 查看 数据是否 能 同步

176 哈哈 数据 同步成功

到此 为止 mysql 双主 +keepalived 部署和测试成功了
报错 解决 参考
如何启用:script_security? ·问题 #901 ·阿卡森/阿卡森 (github.com)
keepalived常见错误汇总 - Granding - 博客园 (cnblogs.com)
关闭selinux的命令是什么 - 问答 - 亿速云 (yisu.com)

这种警告 是没事的

浙公网安备 33010602011771号