第三节:安装Keepalived 实现自动主备切换
网上没找到合适的图片,自己画一张简单的架构图吧
想单独讲一个keepalived是因为不止可以实现MYSQL主备的切换,包括nginx、proxysql等需要高可用架构的场景,都可以实现。
这是部署完成之后的架构图,服务器A会多一个虚拟IP地址。192.168.150.100
应用程序都会访问这个虚拟IP,
同时两台服务器上的keepalived软件会保持心跳,检测对方是否存在。
下面是当服务器A或MySQL 实例A挂跳之后的架构。可以看到,虚拟IP 192.168.150.100 已经飘移到了服务器B,这对应用侧是透明的,应用侧不需要修改数据库连接地址,还能正常访问到数据库
如果服务器A 或MySQL实例A修复好之后,虚拟IP还用飘移到服务器A吗,如果没有特殊需求,是不用的,毕竟MySQL实例A和MySQL实例B数据是一样的。
两台机器都要安装
下载地址:
https://www.keepalived.org/download.html
Keepalived for Linux - Version 2.0.20
wget https://www.keepalived.org/software/keepalived-2.0.20.tar.gz tar xvf keepalived-2.0.20.tar.gz cd keepalived-2.0.20/ yum install gcc openssl-devel libnl3-devel pcre-devel -y ./configure --prefix=/usr/local/keepalived make && make install mkdir /etc/keepalived/ cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/ cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/ cp /root/keepalived-2.0.20/keepalived/keepalived.service /etc/systemd/system/ ln -s /usr/local/keepalived/sbin/keepalived /usr/sbin/ ll /usr/sbin/k* cp /root/keepalived-2.0.20/keepalived/etc/init.d/keepalived /etc/init.d/ chmod 755 /etc/init.d/keepalived systemctl enable keepalived.service systemctl start keepalived.service [root@localhost ~]# ps -ef|grep keep gdm 8380 8099 0 06:45 ? 00:00:00 /usr/libexec/gsd-housekeeping root 13572 1 0 07:33 ? 00:00:00 /usr/local/keepalived/sbin/keepalived -D root 13573 13572 0 07:33 ? 00:00:00 /usr/local/keepalived/sbin/keepalived -D root 13574 13572 0 07:33 ? 00:00:00 /usr/local/keepalived/sbin/keepalived -D root 13593 8592 0 07:33 pts/0 00:00:00 grep --color=auto keep [root@localhost ~]# tail -f /var/log/messages May 18 07:33:35 localhost Keepalived_vrrp[13574]: Sending gratuitous ARP on eth0 for 192.168.200.18 May 18 07:33:36 localhost Keepalived_healthcheckers[13573]: HTTP_CHECK on service [192.168.201.100]:tcp:443 failed after 3 retry. May 18 07:33:36 localhost Keepalived_healthcheckers[13573]: Removing service [192.168.201.100]:tcp:443 to VS [192.168.200.100]:tcp:443 May 18 07:33:36 localhost Keepalived_healthcheckers[13573]: Lost quorum 1-0=1 > 0 for VS [192.168.200.100]:tcp:443 May 18 07:33:36 localhost Keepalived_healthcheckers[13573]: Remote SMTP server [192.168.200.1]:25 connected. May 18 07:34:00 localhost Keepalived_healthcheckers[13573]: Timeout reading data to remote SMTP server [192.168.200.1]:25. May 18 07:34:01 localhost Keepalived_healthcheckers[13573]: Timeout reading data to remote SMTP server [192.168.200.1]:25. May 18 07:34:03 localhost Keepalived_healthcheckers[13573]: Timeout reading data to remote SMTP server [192.168.200.1]:25. May 18 07:34:04 localhost Keepalived_healthcheckers[13573]: Timeout reading data to remote SMTP server [192.168.200.1]:25. May 18 07:34:06 localhost Keepalived_healthcheckers[13573]: Timeout reading data to remote SMTP server [192.168.200.1]:25. #Keepalived已经正常启动了,现在先停掉服务 [root@localhost ~]# systemctl stop keepalived.service
[root@localhost ~]# service mysql stop
继续在两台服务器做相同配置
mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak vi /etc/keepalived/keepalived.conf global_defs { router_id MySQL-HA #标识,只是一个名字 } vrrp_script check_run { script "/usr/local/mysql/mysql_check.sh" #检测脚本地址 interval 60 #健康检查周期 } vrrp_instance VI_1 { state BACKUP #状态为BACKUP interface eth0 #绑定的网卡 virtual_router_id 50 #主备服务器必须在一个id内, priority 100 #权重设置 advert_int 1 #心跳间隔 nopreempt #非抢占模式 authentication { auth_type PASS #用户名 主备要配置为一样 auth_pass 1234 #密码 主备要配置为一样 } track_script { check_run #执行的检测脚本 } virtual_ipaddress { 192.168.150.100 #虚拟IP } }
[root@localhost ~]# vi /usr/local/mysql/mysql_check.sh #! /bin/bash host=127.0.0.1 user=root passwd=123456 /usr/local/mysql/bin/mysql -uroot -p123456 -h127.0.0.1 -P 3306 -e "select 1" >/dev/null 2>/dev/nul if [ $? != 0 ] ; then systemctl stop keepalived.service fi [root@localhost ~]# chmod +x /usr/local/mysql/mysql_check.sh
配置完毕,
1、启动两个实例的mysql
[root@localhost ~]# service mysql start Redirecting to /bin/systemctl start mysql.service [root@localhost ~]#
2、启动两个实例的keepalived
[root@localhost ~]# service keepalived start
Starting keepalived (via systemctl): [ OK ]
[root@localhost ~]#
3、先启动keepalived的服务器会先拿到虚拟IP,服务器A先启动的,在服务器A看下
[root@localhost ~]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:cd:3f:f3 brd ff:ff:ff:ff:ff:ff inet 192.168.150.101/24 brd 192.168.150.255 scope global noprefixroute eth0 valid_lft forever preferred_lft forever inet 192.168.150.100/32 scope global eth0 ###可以看到已经有192.168.150.100这个IP了 valid_lft forever preferred_lft forever inet6 fe80::9aea:2ec6:c21c:9e85/64 scope link tentative noprefixroute dadfailed valid_lft forever preferred_lft forever inet6 fe80::6b3:ad64:3e31:9979/64 scope link noprefixroute valid_lft forever preferred_lft forever inet6 fe80::e204:ab19:4112:354e/64 scope link noprefixroute valid_lft forever preferred_lft forever 3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000 link/ether 52:54:00:4a:de:09 brd ff:ff:ff:ff:ff:ff inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0 valid_lft forever preferred_lft forever 4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000 link/ether 52:54:00:4a:de:09 brd ff:ff:ff:ff:ff:ff [root@localhost ~]#
模拟一下服务器A数据库宕机的场景,连接服务器A,执行
[root@host101 ~]# service mysql stop
Redirecting to /bin/systemctl stop mysql.service
keepalived的检测脚本会发现,mysql已经无法访问了,会触执行一条命令:
systemctl stop keepalived.service
也就是将机的keepalived程序停掉,
1、服务器A的keepalived程序停掉后,无法与服务器B的keepalived程序保持心跳状态,同时也会删掉本机的虚拟IP
2、服务器B与服务器A的心跳中断之后,会认为服务器A已经宕机了,所以虚拟IP需要由自己来接管。
3、在服务器B执行,ip a 会发现IP已经在服务器B上边了
[root@host102 ~]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:80:76:e0 brd ff:ff:ff:ff:ff:ff inet 192.168.150.102/24 brd 192.168.150.255 scope global noprefixroute eth0 valid_lft forever preferred_lft forever inet 192.168.150.100/32 scope global eth0 ###192.168.150.100已经在服务器B上了 valid_lft forever preferred_lft forever inet6 fe80::9aea:2ec6:c21c:9e85/64 scope link noprefixroute valid_lft forever preferred_lft forever 3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000 link/ether 52:54:00:4a:de:09 brd ff:ff:ff:ff:ff:ff inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0 valid_lft forever preferred_lft forever 4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000 link/ether 52:54:00:4a:de:09 brd ff:ff:ff:ff:ff:ff [root@host102 ~]#
如果此时在服务器A执行
service mysql start
service keepalived start
虚拟IP并不会再抢回来,根据之前keepalived.conf配置文件中,
state BACKUP
不会发生抢虚拟IP的行为,只有感知到另一方挂掉之后才会接管虚拟IP。
如果服务器B的mysql进程挂掉后,192.168.150.100会瓢移到服务器A上边来。