keepalived高可用架构
在使用keepalived(VIP)作为MySQL主从高可用时,通常架构如下:
在这里keepalived的作用就是负责VIP漂移,作为一个应用端和数据库端的一个桥梁或者代理,应用不直接访问物理主库的IP地址,而是访问一个虚拟IP,这个虚拟IP(VIP)可以在异常情况下漂移到备库中,使得应用代码可以对数据库进行透明访问(即使主库实例宕机,VIP可以漂移至备库,实现对应用的无感知切换)。
keepalived负责VIP的切换,负责对MySQL不可访问时及网络不可达时的监控,负责两个MySQL实例间有效沟通的一个检测和后续操作的触发器。
keepalived介绍:
相信大家从软件的名字上就可以猜到他的含义:keep-alived 保持存活,也可以理解为保持在线 也就是所谓的高可用或者热备,在集群管理中的一个轻量级的保障集群高可用的一个软件。
说到keepalived就不得不说vrrp协议,VRRP全称Virtual Router Redundancy Protocol,即虚拟路由冗余协议,目的是解决静态路由的单点故障,可以说vrrp就是keepalived实现的基础。
MySQL高可用配置keepalived的一些建议
1. 采用单播
单播:在同一局域网内,两个设备点对点的通信就是单播通信。
组播:在同一网络可达范围内,一个网络设备与关心其数据的部分设备进行通信就是组播。
广播:在同一网络可达范围内,一个网络设备向本网络内所有设备进行通信就是广播。
简单地说,单播->组播->广播,是通信数量不断增加的通信方式。当然,通信数量的增多,带来的是通信设备的资源消耗更大,整体网络环境的复杂度更高。
keepalived中如果不进行额外的配置,默认是组播,在组播模式下所有的信息都会向224.0.0.18的组播地址发送,产生众多的无用信息,并且会产生干扰和冲突,所以需要将其组播的模式改为单播。这是一种安全的方法,避免局域网内有大量的keepalived造成虚拟路由id的冲突,导致keepalived异常。
单播模式需要关闭vrrp_strict这个选项。
单播需要在VIP实例配置段加入单播的源地址和目标地址
下面给出单播的配置详情,请参考如下:
[root@mysql-01 ~]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
smtp_connect_timeout 30
router_id MySQL_Master_214
vrrp_skip_check_adv_addr
# vrrp_strict # vrrp_strict严格执行VRRP协议,这会导致:禁止0 VIPs的情形,禁止单播对等点,禁止在IPv6中设置vrrp_version为2。如果上游交换机禁用了组播功能,则Master只能采用单播方式向Backup发送VRRP广告包。设置vrrp_strict会导致无法单播。
}
vrrp_script check_mysql_stat {
script "/etc/keepalived/checkMySQL.sh 3307"
interval 3 # 检测间隔时间,即3秒检测一次
fall 3 # 检测失败的最大次数,超过3次认为节点资源发生故障
rise 1 # 检测成功的次数,有1次成功就认为节点恢复正常
}
vrrp_instance VI_1 {
state BACKUP # 初始状态 MASTER|BACKUP 当其他VRRP实例的priority更高时,会发起选举,具有最高priority的VRRP实例将会成为MASTER。
interface ens192 # 网卡名称
virtual_router_id 51 # 虚拟路由id号
priority 100 # 优先级
unicast_src_ip 10.211.7.214 # 指定单播VRRP包源IP地址,
unicast_peer { # 通过单播方式向以下IP地址(可以是IPV4 和IPV6)发送VRRP包
10.211.7.215 # 配置单播的目标地址,即对方备节点地址,备有多台就配置多个地址
}
advert_int 1 # 心跳检测频率1秒
nopreempt # 非抢占模式,# 当一个具有更高priority的VRRP实例上线后,通常会抢占低priority的Master身份。nopreempt允许在具有更高priority的VRRP实例上线的情形下,仍由低priority的VRRP实例继续维持Master角色。注意:如果采用此选项,则初始状态state选项必须设为BACKUP。
authentication {
auth_type PASS # 可选值:PASS(简单密码,建议)
auth_pass 1111 # VRRP密码,在互为主备的主机上应该是相同的。只会使用前8个字符。
}
virtual_ipaddress { # 必选 设置VIP。VIP只会绑定在Master上,主备切换时,VIP会随之绑定到新的Master上。dev指定VIP绑定的网口,默认为eth0。
10.211.7.11 dev ens192 label ens192:1 # VIP地址
}
track_script { # 使用脚本进行监控(check_mysql_stat是vrrp_script配置项的名称)
check_mysql_stat
}
}
2. 设置非抢占模式
简单点说抢占模式就是,当master宕机后,backup 接管服务。后续当master恢复后,vip漂移到master上,master重新接管服务,多了一次多余的vip切换,而在实际生产中尽多数是不需要这样(这样对业务频繁的切换是不能容忍的,因此我们希望Master起来后成为Backup,所以要设置不抢占。)。实际生产中是,当 原先的master恢复后,状态变为backup,不接管服务,这是非抢占模式。
设置非抢占模式:在配置文件vrrp_instance段中加入关键字:nopreempt
非抢占模式下,注意点如下:
- 主设备、 从设备中的 state 都设置为 BACKUP
- 默认主设备(priority 值大的 Keepalived 节点) 配置一定要加上 nopreempt,否则非抢占不起作用
- 默认组播时,防火墙需要配置允许组播(主、备两台设备上都需要配置, keepalived 使用 224.0.0.18 作为 Master 和Backup 健康检查的通信 IP),否则主备两节点间的心跳检测会异常。
- 如果使用 非抢占模式,就不能通过优先级 priority 来判断谁应该是MASTER或者SLAVE,而应该根据检测脚本的返回值。
附:单播组播的一些tcp抓包信息
#主节点确实使用了组播向224.0.0.18地址发送心跳包
[root@nginx keepalived]# /usr/sbin/tcpdump -i ens33 -nn -p vrrp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
21:17:57.446287 IP 192.168.9.101 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
21:17:58.446695 IP 192.168.9.101 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
21:17:59.447752 IP 192.168.9.101 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
#现在就变成单播模式了,主节点只对备节点发送心跳包
[root@master keepalived]# tcpdump -i ens33 -nn -p vrrp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
21:29:13.033272 IP 192.168.9.101 > 192.168.9.102: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
21:29:14.034674 IP 192.168.9.101 > 192.168.9.102: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
21:29:15.034943 IP 192.168.9.101 > 192.168.9.102: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 1s, length 20
3. 设置keepalived的日志位置
修改 /etc/sysconfig/keepalived 文件,将KEEPALIVED_OPTIONS="-D -d -S 0" 将入文件内容中:
[root@mysql-01 ~]# cat /etc/sysconfig/keepalived
# Options for keepalived. See `keepalived --help' output and keepalived(8) and
# keepalived.conf(5) man pages for a list of all options. Here are the most
# common ones :
#
# --vrrp -P Only run with VRRP subsystem.
# --check -C Only run with Health-checker subsystem.
# --dont-release-vrrp -V Dont remove VRRP VIPs & VROUTEs on daemon stop.
# --dont-release-ipvs -I Dont remove IPVS topology on daemon stop.
# --dump-conf -d Dump the configuration data.
# --log-detail -D Detailed log messages.
# --log-facility -S 0-7 Set local syslog facility (default=LOG_DAEMON)
#
#KEEPALIVED_OPTIONS="-D"
KEEPALIVED_OPTIONS="-D -d -S 0"
修改/etc/rsyslog.conf,添加local0.* 指定keepalived日志路径为/var/log/keepalived.log
[root@c1 ~]# cat /etc/rsyslog.conf|grep -v '^#'|grep -v '^$'
$ModLoad imuxsock # provides support for local system logging (e.g. via logger command)
$ModLoad imjournal # provides access to the systemd journal
$WorkDirectory /var/lib/rsyslog
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
$IncludeConfig /etc/rsyslog.d/*.conf
$OmitLocalLogging on
$IMJournalStateFile imjournal.state
*.info;mail.none;authpriv.none;cron.none /var/log/messages
authpriv.* /var/log/secure
mail.* -/var/log/maillog
cron.* /var/log/cron
*.emerg :omusrmsg:*
uucp,news.crit /var/log/spooler
local7.* /var/log/boot.log
local0.* /var/log/keepalived.log
重启生效:
systemctl restart rsyslog
systemctl start keepalived
4. 编译安装常见错误
Tips1: 安装过程中提示: WARNING – this build will not support IPVS with IPv6. Please install libnl/libnl-3 dev libraries to support IPv6 with IPVS.
解决方式: yum install libnl-dev
Tips2: 安装过程中提示:
check/libcheck.a(check_ssl.o): In function `build_ssl_ctx':
/usr/local/nginx/keepalived-2.0.0/keepalived/check/check_ssl.c:72: undefined reference to `OPENSSL_init_ssl'
/usr/local/nginx/keepalived-2.0.0/keepalived/check/check_ssl.c:73: undefined reference to `OPENSSL_init_ssl'
/usr/local/nginx/keepalived-2.0.0/keepalived/check/check_ssl.c:82: undefined reference to `TLS_method'
collect2: error: ld returned 1 exit status
make[2]: *** [keepalived] Error 1
make[2]: Leaving directory `/usr/local/nginx/keepalived-2.0.0/keepalived'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/usr/local/nginx/keepalived-2.0.0/keepalived'
make: *** [all-recursive] Error 1
解决方式: 指定LDFLAGS
cd /mysqlsoft/keepalived-2.0.20
LDFLAGS="$LDFAGS -L /usr/local/openssl/lib/" ./configure --prefix=/usr/local/keepalived --sysconf=/etc
make
make install
Tips3: 安装过程中提示OpenSSL is not properly installed on your system. !!!
解决方式: yum -y install openssl-devel
Tips4: 安装过程中提示 fatal error zlib.h: No such file or directory # include <zlib.h>
解决方式: yum -y install zlib-devel
参考文档
https://www.keepalived.org/documentation.html#