015.keepalived
KeepAlive
在单台负载节点的场景下,如果负载节点宕机,则造成整个业务系统的无法访问,所以此时需要多负载节点作为备用;在多负载节点的场景下,如果主负载节点宕机,如何将业务指向到备用负载节点?修改客户端网关IP可以实现,但在客户端数量较多的情况下工作量巨大,直接将备用负载节点IP修改为主节点的IP也无法实现,这与ARP缓存有关,所以此时需要多节点、自动切换的功能
高可用VRRP原理
高可用通常是指两台相互之间有探测通信的相同的业务系统,一台故障,另一台能自动接管业务。KeepAlive是一款基于VRRP协议实现高可用功能的软件,VRRP通过软件或硬件的形式在主备双节点之外,增加一个虚拟MAC(VMAC)与虚拟IP(VIP),客户端通过请求VIP的形式访问负载节点,无论是主节点或备节点处理客户请求,客户端都只会在ARP缓存表中记录VMAC和VIP的对应关系
高可用需要解决的问题
- 通过投票选举、设置优先级的方式,确定谁是主节点、谁是备节点
- 通过抢占式、非抢占式设置,决定主节点故障恢复后是否会抢夺备节点的VIP
- 解决两个节点都认为自身是主节点的问题(脑裂)
KeepAlive安装
- 实践环境
| 主机名 | IP | 角色 |
|---|---|---|
| lb01 | 10.0.0.5 | Master |
| lb02 | 10.0.0.6 | Backup |
| VIP | 10.0.0.2 |
- 在lb节点上安装keepalived
# lb01
[root@lb01 ~]# yum install -y keepalived
[root@lb01 ~]# rpm -qc keepalived # 查看配置文件存放路径
[root@lb01 ~]# cp /etc/keepalived/keepalived.conf{,.bak}
[root@lb01 ~]# vim /etc/keepalived/keepalived.conf
global_defs { # 全局配置
router_id lb01 # 表示身份名称
}
vrrp_instance VI_1 {
state MASTER # 仅作为角色的标识,真正的角色选择要看优先级
interface eth1 # 网卡绑定接口
virtual_router_id 50 # 虚拟路由id,一个网络环境下存在多个keepalived时,通过这个id号来区分keepalive分组
priority 150 # 优先级
advert_int 1 # 主备节点检测间隔时间
authentication { # 认证
auth_type PASS # 明文认证
auth_pass 1111 # 明文密码
}
virtual_ipaddress { # VIP地址,可以配置多个
10.0.0.2
}
}
# lb02
[root@lb02 ~]# vim /etc/keepalived/keepalived.conf
global_defs {
router_id lb02 # 备节点身份名称
}
vrrp_instance VI_1 {
state SLAVE # 备节点角色
interface eth1
virtual_router_id 50
priority 149 # 优先级需要比主节点低
advert_int 1
authentication {
auth_type PASS # 明文认证
auth_pass 1111 # 主备节点密码必须一致
}
virtual_ipaddress {
10.0.0.2
}
}
KeepAlived的日志默认写入/var/log/message,通过/etc/sysconfig/keepalived配置文件能够看到keepalived的默认选项是-D;监视lb02节点的message日志的同时启动keepalived,可以看到keepalived读取了配置文件,并因为没有找到优先级更高的角色而主动获取VIP,此时再启动lb01节点的keepalived,lb02日志因为检测到更高优先级的角色而让出VIP;由此可见KeepAlived默认使用抢占式VIP,抢占式在业务高峰期可能会出现客户端频繁切换网关的情况,影响使用体验
- 配置keepalived服务的放行
[root@lb02 ~]# echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
[root@lb02 ~]# sysctl -p
[root@lb02 ~]# firewall-cmd --permanent --add-protocol=vrrp
- 逐步启动lb02、lb01节点,查看keepalived变化
# 启动lb02备节点,持续查看备节点日志
[root@lb02 ~]# systemctl start keepalived
[root@lb02 ~]# tail -F /var/log/messages
# 启动lb01主节点后,查看备节点日志,备节点VIP已经移除
Mar 19 13:14:37 lb02 Keepalived_vrrp[2395]: VRRP_Instance(VI_1) Received advert with higher priority 150, ours 149
Mar 19 13:14:37 lb02 Keepalived_vrrp[2395]: VRRP_Instance(VI_1) Entering BACKUP STATE
Mar 19 13:14:37 lb02 Keepalived_vrrp[2395]: VRRP_Instance(VI_1) removing protocol VIPs.
KeepAlived抢占式与非抢占式
默认情况下,Master节点故障后Backup节点会自动接管Master节点的工作并成为Master,但Master节点恢复后它本身会抢占VIP,这在业务繁忙的时间段可能会造成一定的网络波动
# lb01
vrrp_instance VI_1 {
...
state BACKUP
nopreempt # 添加非抢占参数
priority 150
...
}
配置非抢占式KeepAlived建议具备3个条件
- 两个节点的state都必须是BACKUP
- 两个节点都需要添加nopreempt参数
- 其中一个节点的优先级必须要高于另一个节点
这三个建议中,实际只要将主节点的state角色改为BACKUP并添加nopreempt参数即可生效,但仍应尽量保持双节点的配置同步
KeepALived抓包分析
宿主机通过cmd查看本地ARP解析,同时启停一下lb01节点的keepalived服务,观察宿主机的ARP地址解析是否变化,有变化说明keepalived成功向客户端ARP广播过地址发生变化的信息
双节点keepalived服务都正常时,此时VIP在lb01节点上,查看宿主机arp
? (10.0.0.2) at 52:54:00:ba:88:4b [ether] on virbr0
关闭lb01节点的keepalived服务,再次观察宿主机的arp解析
? (10.0.0.2) at 52:54:00:64:23:2a [ether] on virbr0
VRRP包的基本信息,包含虚拟路由ID、优先级、发送频率、认证密码等

KeepAlived抢占式立即能够看到源IP的切换

双节点配置完全同步测试
在角色和优先级完全一样的情况下,先启动keepalived服务的节点会成为主节点,这样的配置也能够正常使用keepalived服务,但它会影响到要使用VIP的其他服务,例如wordpress站点,keepalived服务没有故障、VIP的ping测试也没有问题的情况下,使用VIP访问wordpress站点访问不到页面
# 同步配置文件
[root@lb01 ~]# scp /etc/keepalived/keepalived.conf lb02:/etc/keepalived/
# lb02节点先启动keepalived服务
[root@lb02 ~]# systemctl start keepalived.service
此时lb02节点就已经被认定为主节点,即便重启lb02节点的keepalived服务,VIP也会在漂移后重新回到lb02节点
KeepAlived与Nginx的关联
keepalived虚拟地址漂移与nginx服务进行关联,基本无需操作,因为nginx默认监听在所有IP地址上,这意味着当VIP落在某一个负载节点上时,nginx已经开始监听该VIP的80端口了,所以在实验环境下只需要修改一下本地的hosts解析,将站点域名解析到VIP上就能够直接访问了
KeepAlived脑裂
由于某些原因,导致两台keepalived节点在指定的时间内无法检测到对方的心跳,各自取得资源及服务的所有权,但此时两台keepalived节点又都还存活
服务器网线松动等网络故障
服务器硬件故障发生损坏现象而崩溃
主备都开启firewalld防火墙
Nginx服务崩溃
通过防火墙模拟脑裂,在keepalived脑裂情况下,VIP仍能通过ping测试和网站访问测试,但通过抓包测试可以看到keepalived两台主备节点不停在争抢VIP,这在某些服务和高并发的情况下是不被允许的
# 配置双节点的防火墙
[root@lb02 nginx]# firewall-cmd --remove-protocol=vrrp --permanent
[root@lb02 nginx]# firewall-reload

# 备节点脑裂探测脚本
[root@lb02 ~]# vim /opt/script/split_brain.sh
#!/bin/sh
LB_VIP=10.0.0.2
LB01_IP=10.0.0.5
VIRTUAL_IP=$(ip add | grep "^${LB_VIP}$" | wc -l)
while true; do
ping -c 2 -W 3 $LB01_IP &> /dev/null
if [ $? -eq 0 -a ${VIRTUAL_IP} -eq 1 ]; then # 既能ping通主节点、又能在自身匹配到VIP
echo "ha is split brain.warning." >> /opt/keeperr.log # 这个文件是为了检测脚本是否执行,也可以将此步骤换成邮箱
exit
else
echo "ha is ok" >> /opt/keepalived.log
exit
fi
sleep 1
done
[root@lb02 ~]# chmod 755 /opt/script/split_brain.sh
在这个脚本中exit非常重要,因为这个脚本使用的是while循环,判断条件是true,这意味着while会一直循环。在keepalived服务中调用的脚本,执行时间不可超过keepalived配置文件中,interval所定义的时间,否则keepalived将无法正常获取到VIP,从日志中可看到keepalived会一直杀死正在执行的脚本。因此每个判断下exit都是为了终止while循环,exit终止循环后,keepalived会主动重复执行脚本,等同于keepalived本身就是一个大的循环语法,脚本中实际上只需要编写测试语句
Mar 19 18:12:44 lb02 Keepalived_vrrp[23263]: /opt/script/split_brain.sh exited due to signal 15
Mar 19 18:12:49 lb02 Keepalived_vrrp[23263]: /opt/script/split_brain.sh exited due to signal 15
Mar 19 18:12:54 lb02 Keepalived_vrrp[23263]: /opt/script/split_brain.sh exited due to signal 15
出现脑裂问题时,必须随机下线某一个keepalived服务(不是下线主机)
KeepAlived保证Nginx服务可用
KeepAlived本身只做VIP地址漂移,它与nginx并没有直接关系,所以在某些情况下,主节点nginx服务崩溃,keepalived服务并不会收到影响,这就导致VIP会一直存在主节点上,用户请求站点失败;由于keepalived不会主动进行切换,所以需要编辑一个脚本检测nginx的存活状态,如果不存活则杀死nginx和keepalived,强制使VIP漂移到备节点
# 检测nginx存活脚本
[root@lb01 ~]# vim /opt/script/check_nginx.sh
#!/bin/sh
NGINXPID=$(ps -C nginx --no-header | wc -l) # 检测nginx进程
if [ $NGINXPID -eq 0 ]; then
systemctl start nginx # 检测不到nginx进程时,启动nginx
sleep 3
NGINXPID=$(ps -C nginx --no-header | wc -l) # 再次检测nginx进程
if [ $NGINXPID -eq 0 ]; then
systemctl stop keepalived # nginx启动失败,关闭keepalived服务
fi
fi
[root@lb01 ~]# chmod +x /opt/script/check_nginx.sh
主节点keepalived配置文件调用脚本
[root@lb01 ~]# vim /etc/keepalived/keepalived.conf
vrrp_script check_web { # 定义脚本
script "脚本绝对路径" # 要执行的脚本存放路径
interval 5 # 5秒检查一次
}
vrrp_instance VI_1{
...
track_script { # 调用脚本
check_web
}
}
keepalived配置文件中设置每5秒执行一次脚本,其脚本本身的执行时长必须要小于5秒,否则脚本还没执行完,keepalived会主动杀死当前脚本进程并重新执行一遍脚本;以上都是针对抢占式keepalived的场景,如果是非抢占式场景,那么两个节点都需要配置检测脚本
关于KeepAlived
公有云不支持keepalived,因为公有云不支持组播,它提供自带的高可用服务

浙公网安备 33010602011771号