1. Keepalived高可用服务单实例实战
1.1 配置Keepalived实现单实例单IP自动漂移接管
事实上,网络服务的高可用功能基本原理都很简单,就是把手动的操作自动化运行而已。当没有配置高可用服务时,如果服务器宕机了怎么解决呢?无非就是找一个新服务器,配好域名解析的那原IP,然后搭好相应的网络服务罢了,只不过手动去实现这个过程会比较漫长,相比而言,自动化切换效率更高、效果更好,而且还可以有更多的功能。例如:发送ARP广播、触发执行相关脚本功能等。
实际上也可以将高可用对的两台机器应用服务同时开启,但是只让有VIP一端的服务器提供服务,若主的服务器宕机,VIP会自动漂移到备用服务器上,此时用户的请求直接发送到备用服务器上,而无须临时启动对应服务(事先开启应用服务)。下面来讲解VIP自动漂移的实战案例。
1.1.1 配置Keepalived主服务器lb01 MASTER实战
首先,配置lb01 MASTER的keepalived.conf配置文件,操作步骤如下:
[root@lb01 ~]# cd /etc/keepalived/
[root@lb01 keepalived]# cp keepalived.conf{,.ori}
[root@lb01 keepalived]# >keepalived.conf
[root@lb01 keepalived]# vi keepalived.conf
删掉已有的所有默认配置,加入修改好的如下配置:
global_defs {
router_id lb01 ---ID为lb01,不同的keepalived.conf此ID要唯一
}
vrrp_instance VI_1 { ---实例名字为VI_1,相同实例的备节点名字要和这个相同
state MASTER ---状态为MASTER,备节点状态需要为BACKUP
interface eth0 ---通信接口为eth0(根据实际而定),对于此参数,备节点设置和主节点相同
virtual_router_id 51 ---实例ID为51,keepalived.conf里唯一
priority 150 ---优先级为150,备节点的优先级必须比此数字低
advert_int 1 ---通信检查间隔时间1秒
authentication {
auth_type PASS ---PASS认证类型,对于此参数,备节点设置和主节点相同
auth_pass 1111 ---密码是1111,对于此参数,备节点设置和主节点相同
}
virtual_ipaddress {
192.168.9.210/24 dev eth0 label eth0:vip
---虚拟IP,即VIP,子网掩码为24位,绑定接口为eth0(根据实际而定),别名为eth0:vip,对于此参数,备节点设置和主节点相同
}
}
提示:此处设置的虚拟IP为192.168.9.30,即网站域名绑定的IP(以后访问都是访问这个IP)。
配置完毕后启动Keepalived服务,如下:
[root@lb01 keepalived]# ps -ef|grep keep|grep -v grep
[root@lb01 keepalived]# systemctl start keepalived
[root@lb01 keepalived]# ps -ef|grep keep|grep -v grep
root 7359 1 0 10:32 ? 00:00:00 /usr/sbin/keepalived -D
root 7360 7359 0 10:32 ? 00:00:00 /usr/sbin/keepalived -D
root 7361 7359 0 10:32 ? 00:00:00 /usr/sbin/keepalived -D
然后检查配置结果,查看是否有虚拟IP192.168.9.210,注意:此处默认检查VIP用ifconfig命令查看可能看不见,因为Keepalived服务是采用辅助IP(IP)的形式配置的VIP,这里采用了别名的标签方式配置的VIP,因此,ifconfig也可以查看VIP情况。
[root@lb01 keepalived]# ip addr|grep 192.168.9.210
inet 192.168.9.210/24 scope global secondary eth0:vip
出现上述带有vip:192.168.9.210行的结果表示lb01的Keepalived服务单实例配置成功。
1.1.2 配置Keepalived备服务器lb02BACKUP实战
首先,配置lb02BACKUP的keepalived.conf配置文件,操作步骤如下:
[root@lb02 ~]# cd /etc/keepalived/
[root@lb02 keepalived]# cp keepalived.conf{,.ori}
[root@lb02 keepalived]# >keepalived.conf
[root@lb02 keepalived]# vim keepalived.conf
删掉已有的默认配置,加入修改好的如下配置(注意和lb01的不同):
global_defs {
router_id lb02
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.9.210/24 dev eth0 label eth0:vip
}
}
配置完毕后,启动Keepalived服务:
[root@lb02 keepalived]# systemctl start keepalived
[root@lb02 keepalived]# ps -ef|grep keep|grep -v grep
root 17614 1 0 11:07 ? 00:00:00 /usr/sbin/keepalived -D
root 17615 17614 0 11:07 ? 00:00:00 /usr/sbin/keepalived -D
root 17616 17614 0 11:07 ? 00:00:00 /usr/sbin/keepalived -D
然后检查配置结果,查看是否有虚拟IP192.168.9.210。
[root@lb02 keepalived]# ip addr|grep 192.168.9.210
---这里没有返回任何结果就对了,因为lb02为BACKUP,当主节点活着的时候,它不会接管VIP192.168.9.210。
出现上述无任何结果的现象,表示lb02的Keepalived服务单实例配置成功。如果配置到这里过滤后有192.168.9.210的IP,则表示Keepalived运行不正常,同一个IP地址同一时刻应该只能出现一台服务器。
如果查看BACKUP备节点VIP有如下信息,说明高可用集群裂脑了,裂脑是两台服务器争抢同一资源导致的。例如:两边都配置了同一个VIP地址。
出现两台服务器争抢同一IP资源的问题,一般要先考虑排查两个方面:
- 主备两台服务器之间是否通信正常,如果不正常是否有Iptables/firewalld防火墙阻挡?
- 主备两台服务器对应的keepalived.conf配置文件是否有错误。例如,是否同一实例的virtual_router_id配置不一致?
1.1.3 进行高可用主备服务器切换实验
停掉主服务器上的Keepalived服务或干脆关闭主服务器,操作及检查步骤如下:
[root@lb01 keepalived]# ip addr|grep 192.168.9.210
inet 192.168.9.210/24 scope global secondary eth0:vip
[root@lb01 keepalived]# systemctl stop keepalived
[root@lb01 keepalived]# ip addr|grep 192.168.9.210 ---查看VIP消失了
可以看到VIP 192.168.9.210消失了,此时查看BACKUP备服务器,看是否会有VIP 192.168.9.210出现,操作及检查步骤如下:
[root@lb02 keepalived]# ip addr|grep 192.168.9.210
inet 192.168.9.210/24 scope global secondary eth0:vip
可以看到备节点lb02已经接管绑定了 192.168.9.210这个VIP,这期间备节点还会主动发送ARP广播,让局域网内所有的客户端更新本地ARP缓存表,以便访问新接管VIP服务的节点。
此时如果再启动主服务器的Keepalived服务,主服务器就会重新接管VIP 192.168.9.210,启动后可以观察下主备的IP漂移情况,备服务器是否释放了IP?主服务器是否又接管了IP?
主节点启动Keepalived服务后,很快就又接管了VIP 192.168.9.210,操作及检查步骤如下:
[root@lb01 keepalived]# systemctl start keepalived
[root@lb01 keepalived]# ip addr|grep 192.168.9.210
inet 192.168.9.210/24 scope global secondary eth0:vip
与此同时,备节点上的VIP 192.168.9.210则被释放了:
[root@lb02 keepalived]# ip addr|grep 192.168.9.210
这样就实现了单实例Keepalived服务IP自动漂移接管了,VIP漂移到了新机器上,用户的访问请求自然就会找新机器新服务了。
说明:这里仅实现了VIP的自动漂移切换,因此,仅适合两台服务器提供的服务均保持开启的应用场景,这也是工作中常用的高可用解决方案。
1.2 单实例主备模式Keepalived配置文件对比
下表为单实例主备模式Keepalived配置文件内容的对比,从表中可以看到主备配置的细微差别。
2. Keepalived高可用服务器对的“裂脑”问题
2.1 什么是裂脑?
由于某些原因,导致两台高可用服务器对在指定时间内容无法检测到对方的心跳消息,各自取得资源及服务的所有权,而此时的两台高可用服务器对都还活着并在正常运行,这样会导致同一个IP或服务在两端同时存在而发生冲突,最严重的是两台主机占用同一个VIP地址,当用户写入数据时可能会分别写入到两端,这可能会导致服务器两端的数据不一致或造成数据丢失,这种情况被称为裂脑。
2.2 导致裂脑发生的原因
一般来说,导致裂脑发生的原因有以下几种。
(1)高可用服务器对之间心跳线链路故障,导致无法正常通信。
- 心跳线坏了(包括断了、老化)。
- 网卡及相关驱动坏了,IP配置及冲突问题(网卡直连)。
- 心跳线间连接的设备故障(网卡及交换机)。
- 仲裁的机器出问题(采用仲裁的方案)。
(2)高可用服务器对上开启了Iptables防火墙阻挡了心跳消息传输。
(3)高可用服务器对上心跳网卡地址等信息配置不正确,导致发送心跳失败。
(4)其他服务器配置不当等原因,如心跳方式不同、心跳广播冲突、软件BUG等。
提示:Keepalived配置里同一VRRP实例如果virtual_router_id参数两端配置不一致,也会导致裂脑问题产生。
2.3 解决裂脑的常见方案
1)同时使用串行线缆和以太网线缆连接,同时用两条心跳线路,这样一条线路坏了另一个还是好的,依然能传送心跳消息。
2)当检测到裂脑时强行关闭一个心跳节点(这个功能需特殊设备支持,如Stonith、fence)。相当于备节点接收不到心跳消息,发送关机命令通过单独的线路关闭主节点的电源。
3)做好对裂脑的监控报警(如邮件及手机短信等或值班),在问题发生时认为第一时间介入仲裁,降低损失。例如,百度的监控报警短信就有上行和下行的区别。报警信息报到管理员手机上,管理员可以通过手机回复对应数字或简单的字符串操作返回给服务器,让服务器根据指令自动处理相应故障,这样解决故障的时间更短。
当然,在实施高可用方案时,要根据业务实际需求确定是否能容忍这样的损失。对于一般的网站常规业务,这个损失是可容忍的。
2.4 常见的解决Keepalived裂脑的方案
作为互联网应用服务器的高可用,特别是前端Web负载均衡的高可用,裂脑的问题对普通业务的影响是可以忍受的,如果是数据库或者存储的业务,一旦出现裂脑问题就非常严重了。因此,可以通过增加冗余心跳线路来避免裂脑问题的产生,同时加强对系统的监控,以便裂脑发生时人为快速介入解决问题。
- 如果开启防火墙,一定要让心跳消息通过,一般通过允许IP段的形式解决。
- 可以拉一条以太网网线或者串口线作为主备节点心跳线路的冗余。
- 开发监测程序通过监控软件(如Nagios)监测裂脑。
下面是生产场景下检测裂脑故障的一些思路:
(1)简单判断的思路:只要备节点出现VIP就报警,这个报警有两种情况:一是主机宕机了备节点接管了;二是主机没宕,裂脑了。不管属于哪个情况都进行报警,然后由人工查看判断及解决。
(2)比较严谨的判断:备节点出现对应VIP,并且主节点及对应服务(如果能远程连接主节点查看是否有VIP就更好了)还活着,就说明发生裂脑了。
3. Keepalived双实例双主模式配置实战
3.1 keepalived双实例双主模式配置
前面给出的是Keepalived单实例主备模式的高可用演示,Keepalived还支持多实例多业务双向主备模式,即A业务在lb01上是主模式,在lb02是备模式,而B业务在lb01上是备模式,在lb02上是主模式,下面就以双实例为例讲解不同业务实现双主的配置。下表为Keepalived双实例双主模式IP及VIP规划表。
首先,配置lb01 192.168.9.81的keepalived.conf,在单实例的基础上增加一个vrrp_instance VI_2实例,步骤及内容如下:
[root@lb01 keepalived]# cat keepalived.conf
global_defs {
router_id lb01
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 150
advert_int 1
authenticatin {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.9.210/24 dev eth0 label eth0:3
}
}
vrrp_instance VI_2 {
state BACKUP
interface eth0
virtual_router_id 52
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.9.211/24 dev eth0 label eth0:4
}
}
提示:以vrrp_instance VI_1在lb01 192.168.9.81服务器上的角色为主,vrrp_instance VI_2在lb01 192.168.9.81服务器上的角色为备,vrrp_instance VI_2的部分为增加的配置。
然后配置lb02 192.168.9.82的keepalived.conf,在单实例的基础上增加vrrp_instance VI_2实例,步骤及内容如下:
[root@lb02 keepalived]# cat keepalived.conf
global_defs {
router_id lb02
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.9.210/24 dev eth0 label eth0:3
}
}
vrrp_instance VI_2 {
state MASTER
interface eth0
virtual_router_id 52
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.9.211/24 dev eth0 label eth0:4
}
}
提示:以vrrp_instance VI_1在lb02 192.168.9.82服务器上的角色为备,vrrp_instance VI_2在lb02 192.168.9.82服务器上的角色为主,vrrp_instance VI_2后面的部分为增加的配置。
接着,在lb01、lb02上分别重启Keepalived服务,观察初始VIP设置情况。lb01操作的结果如下:
[root@lb01 keepalived]# systemctl restart keepalived
[root@lb01 keepalived]# ip addr|egrep "192.168.9.210|192.168.9.211"
inet 192.168.9.210/24 scope global secondary eth0:3
提示:启动lb01后,初始状态已经启动了192.168.9.210 VIP,即lb01由VI_1实例配置的VIP对外提供服务。例如,可以把www.etiantian.org解析到192.168.9.210上。
lb02操作的结果如下:
[root@lb02 keepalived]# systemctl restart keepalived
[root@lb02 keepalived]# ip addr|egrep "192.168.9.210|192.168.9.211"
inet 192.168.9.211/24 scope global secondary eth0:4
提示:启动lb02后,初始状态已经启动了192.168.9.211 VIP,即lb02由VI_2实例配置的VIP对外提供服务。例如,可以把bbs.etiantian.org解析到192.168.9.211上。
下面停掉任意一端服务器或者Keepalived服务,查看VIP是不是会漂移到另一端。
停止lb01的Keepalived服务:
[root@lb01 keepalived]# systemctl stop keepalived
[root@lb01 keepalived]# ip addr|egrep "192.168.9.210|192.168.9.211"
---此处无显示信息
可以看到,停掉lb01的Keepalived服务后,VIP 192.168.9.210即被释放。
现在,检查lb02服务器上IP的接管情况:
[root@lb02 keepalived]# ip addr|egrep "192.168.9.210|192.168.9.211"
inet 192.168.9.211/24 scope global secondary eth0:4
inet 192.168.9.210/24 scope global secondary eth0:3
可以看到,已经接管了lb01的VIP 192.168.9.210。再次启动lb01的Keepalived服务:
[root@lb01 keepalived]# systemctl start keepalived
[root@lb01 keepalived]# ip addr|egrep "192.168.9.210|192.168.9.211"
inet 192.168.9.210/24 scope global secondary eth0:3
在lb01上启动Keepalived服务后,很快它就接管回了自己的VIP。此时,检查lb02服务器上此时IP的设置情况:
[root@lb02 keepalived]# ip addr|egrep "192.168.9.210|192.168.9.211"
inet 192.168.9.211/24 scope global secondary eth0:4
可以看到,已经释放了lb01的VIP。若是停止lb02的Keepalived服务,VIP 192.168.9.211也立即被释放。
[root@lb02 keepalived]# systemctl stop keepalived.service
[root@lb02 keepalived]# ip addr|egrep "192.168.9.210|192.168.9.211"
---此处无显示信息
然后检查lb01服务器上IP的接管情况:
[root@lb01 keepalived]# ip addr|egrep "192.168.9.210|192.168.9.211"
inet 192.168.9.210/24 scope global secondary eth0:3
inet 192.168.9.211/24 scope global secondary eth0:4
可以看到,它也接管了lb02的VIP 192.168.9.211。
[root@lb02 keepalived]# systemctl start keepalived
[root@lb02 keepalived]# ip addr|egrep "192.168.9.210|192.168.9.211"
inet 192.168.9.211/24 scope global secondary eth0:4
至此,我们发现lb01、lb02主备节点已经实现了初始状态各自服务器设置了初始的VIP提供服务,当任意一端宕机,VIP可以实现互相切换切换接管。在实际工作中,可以把www.etiantian.org解析到VIP 192.168.9.210上提供服务,把bbs.etiantian.org解析到VIP192.168.9.211上提供服务,当然了,lb01、lb02也要配置相应服务。例如:Nginx反向代理服务等。
3.2 双实例双主模式的配置文件对比
Keepalived双实例双主模式在企业工作场景也是比较常用的,下表展示了这种情况下主备配置文件的差别。
可以看到主备节点在增加的实例方面就两项区别:
- state(状态)。
- priority(竞选优先级)。
其中,优先级决定VIP在哪个机器上初始运行。