Docker方式创建keepalived连接MGR集群
作者:小时候的阳光
前言
假设已经搭建了MySQL8的MGR集群方式(一主两从)。
MGR本身有故障转移重新选举新的主节点功能,但是上游的应用程序需要自己手动修改数据库连接地址重新指向主节点。
为了了能不用手动方式切换主节点需要中间代理访问程序,提供的方案有很多例如 nginx、keepalived、proxysql等,这里我们先选择使用keepalived,后期使用proxysql代理。
步骤
1. 安装环境
安装Docker和MGR 这里略过
2. 重新制作镜像
登录任意一个节点服务器,下载原始镜像
docker pull osixia/keepalived:2.0.20
创建临时容器
docker run --name keepalivedtest --cap-add=NET_ADMIN --cap-add=NET_BROADCAST --cap-add=NET_RAW -e KEEPALIVED_INTERFACE=enp6s0 --net=host -d osixia/keepalived:2.0.20
登录进临时容器
docker exec -it keepalivedtest /bin/bash
然后安装mysql客户端
apk add mysql mysql-client ...稍等片刻 ... 安装完成后 退出容器 exit
从零时容器生成一个新的镜像:mgr_keepalived
docker commit keepalivedtest mgr_keepalived:2.0.20
导出镜像文件,上传其他MGR节点服务器
docker save -o mgr_keepalived2.tar mgr_keepalived:2.0.20
3. 导入新镜像
在每一个MGR节点服务器上导入镜像
docker load -i mgr_keepalived2.tar
4. 创建容器
这里假设3台服务器环境如下:
| 服务器 | 文件路径 | 备注 | 
|---|---|---|
| 192.168.1.246 | /apps/keepalived/keepalived.conf /apps/keepalived/mysql_master_check.sh | 记得sh文件赋予可执行权限,当前MGR主节点 | 
| 192.168.1.247 | /apps/keepalived/keepalived.conf /apps/keepalived/mysql_master_check.sh | 从节点 | 
| 192.168.1.248 | /apps/keepalived/keepalived.conf /apps/keepalived/mysql_master_check.sh | 从节点 | 
各服务器文件路径都一致, mysql_master_check.sh 脚本文件内容如下:
#!/bin/bash
# 替换以下变量为你的实际MySQL用户、密码和端口
MYSQL_USER="rpl_user"
MYSQL_PASS="请填写账号密码"
MYSQL_PORT="请填写端口号"
MYSQL_HOST="请填写节点主机IP"
# 检查MySQL服务是否运行
if nc -z "$MYSQL_HOST" "$MYSQL_PORT"; then
    echo "MySQL 服务在 $MYSQL_HOST:$MYSQL_PORT 上正在运行"
else
    echo "MySQL 服务在 $MYSQL_HOST:$MYSQL_PORT 上未运行"
    exit 1
fi
# 检查当前节点是否为主节点
IS_READONLY=$(mysql -u"$MYSQL_USER" -p"$MYSQL_PASS" -P"$MYSQL_PORT" -h"$MYSQL_HOST" -e "SHOW GLOBAL VARIABLES LIKE 'read_only';" | grep -c "ON")
if [[ $IS_READONLY -ne 0 ]]; then
    echo "当前节点为只读状态,判定为从节点"
    exit 1
fi
# 获取当前主机名并存储在变量中
CURRENT_HOST=$(hostname)
IS_MASTER=$(mysql -u"$MYSQL_USER" -p"$MYSQL_PASS" -P"$MYSQL_PORT" -h"$MYSQL_HOST" -e "
SELECT COUNT(1)
FROM performance_schema.replication_group_members
WHERE MEMBER_HOST ='$CURRENT_HOST'
AND MEMBER_STATE = 'ONLINE'
AND MEMBER_ROLE='PRIMARY';" | tail -n 1)
if [[ $IS_MASTER -eq 0 ]]; then
    echo "当前节点是从节点"
    exit 1
else
    echo "当前节点是主节点"
    exit 0
fi
各个节点上的文件注意
MYSQL_USER=“rpl_user”
MYSQL_PASS=“请填写账号密码”
MYSQL_PORT=“请填写端口号”
MYSQL_HOST=“请填写节点主机IP”
这几个变量的修改!
另外用户 rpl_user是用于MGR复制用的,也可以填写其他的用户名,但是用户的密码认证方式必须是之前老式的 mysql_native_password ,因为镜像里面的mysql客户端暂不支持MySQL8默认的密码认证方式。
另外 MYSQL_USER 用户必须具有访问 performance_schema.replication_group_members 的权限,因为光靠"SHOW GLOBAL VARIABLES LIKE 'read_only';" 无法判定当前MySQL节点是否为主节点
keepalived.conf 文件内容大致如下:
vrrp_script chk_mysql {
    script "/usr/local/bin/mysql_master_check.sh"
    interval 2
    weight -5
    fall 2
    rise 1
}
vrrp_instance VI_1 {
    state MASTER
    interface enp6s0
    virtual_router_id 51
    priority 101
    advert_int 1  
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.1.110
    }
    track_script {
        chk_mysql
    }
}
主要是如下几个变量要注意:
interval 2 每隔2秒执行一次
weight -5 脚本结果导致的优先级变更,检测失败(
脚本返回非0)则优先级减5fall 2 #检测连续2次失败才算确定是真失败。会用weight减少优先级(1-255之间) 默认值为 3
rise 1 #检测1次成功就算成功。但不修改优先级 默认值为 2
interface 当前节点服务器的
网卡名称priority 优先级,
每一个节点上不一样virtual_ipaddress 虚拟ip
virtual_router_id
共享相同虚拟IP的节点上该参数值必须一样,
keepalived可以代理多个虚拟IP,每一个虚拟IP对应的virtual_router_id值不可一样。state 指定当前keepalived的初始状态,这个可用是 MASTER 或者 BACKUP ,如果是BACKUP 则作为从节点,但是这个值会根据监控脚本运行状态改变优先级从而导致状MASTER /BACKUP 态切换
3台节点服务器上创建容器如下:
docker run -d --name mgr8keepalived \ --cap-add=NET_ADMIN \ --cap-add=NET_BROADCAST \ --cap-add=NET_RAW \ --net=host \ -e KEEPALIVED_INTERFACE=enp6s0 \ -v /apps/keepalived/keepalived.conf:/container/service/keepalived/assets/keepalived.conf \ -v /apps/keepalived/mysql_master_check.sh:/usr/local/bin/mysql_master_check.sh \ mgr_keepalived:2.0.20 --loglevel debug --copy-service
变量 KEEPALIVED_INTERFACE 是指当前节点服务器的网卡名称,如果不想开启debug模式去掉--loglevel debug
查看docker日志一般会有如下信息:
... Wed Jan 31 09:32:53 2024: Reset ARP config counter 0 Wed Jan 31 09:32:53 2024: Original arp_ignore 0 Wed Jan 31 09:32:53 2024: Original arp_filter 0 Wed Jan 31 09:32:53 2024: Original promote_secondaries 1 Wed Jan 31 09:32:53 2024: Reset promote_secondaries counter 0 Wed Jan 31 09:32:53 2024: Tracking VRRP instances = 0 Wed Jan 31 09:32:53 2024: (VI_1) Entering BACKUP STATE (init) Wed Jan 31 09:32:53 2024: VRRP sockpool: [ifindex(2), family(IPv4), proto(112), unicast(0), fd(11,12)] Wed Jan 31 09:32:53 2024: VRRP_Script(chk_mysql) succeeded Wed Jan 31 09:32:53 2024: (VI_1) Changing effective priority from 101 to 103 Wed Jan 31 09:32:57 2024: (VI_1) Receive advertisement timeout Wed Jan 31 09:32:57 2024: (VI_1) Entering MASTER STATE Wed Jan 31 09:32:57 2024: (VI_1) setting VIPs. Wed Jan 31 09:32:57 2024: Sending gratuitous ARP on enp6s0 for 192.168.1.110 Wed Jan 31 09:32:57 2024: (VI_1) Sending/queueing gratuitous ARPs on enp6s0 for 192.168.1.110 Wed Jan 31 09:32:57 2024: Sending gratuitous ARP on enp6s0 for 192.168.1.110 Wed Jan 31 09:32:57 2024: Sending gratuitous ARP on enp6s0 for 192.168.1.110 ...
可以使用虚拟IP 192.168.1.110 连上看下是否可以操作数据库。
可以关闭一个MySQL实例看下keepalived的效果,是否还正常使用,虚拟IP此时是否浮动到新的主节点服务器上了。
注意:关闭一个MySQL实例后重新启动,可能它不会自动加入集群,需要手动执行 START GROUP_REPLICATION 重新加入集群。
到此这篇关于Docker方式创建keepalived连接MGR集群的文章就介绍到这了,更多相关docker mgr集群内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
