Keepalived是lvs的扩展项目,因此它们之间具备良好的兼容性。
通过对服务器池对象的健康检查,实现对失效机器/服务的故障隔离;
负载均衡器之间的失败切换failover,通过VRRPv2 stack实现;
LVS结合keepalived,实现了3层、4层、5/7层交换的功能;
Keepalived是VRRP协议的软件实现,原生设计目的为了高可用ipvs服务;
- 完成地址流动;
- 为vip地址所在的节点生成ipvs规则(定义在配置文件中);
- 并能够对各RS的健康状态进行检测;
- 基于脚本调用接口,通过执行脚本完成脚本中定义的功能;
Keepalived大致分两层结构:用户空间user space 和内核空间kernel space;
- NETLINK提供高级路由及其他相关的网络功能,如果我们在负载均衡器上启用netfilter/iptable,将会直接影响它的性能;
- WatchDog 负责监控checkers和VRRP进程的状况。
- Checkers 负责真实服务器的健康检查healthchecking,是keepalived最主要的功能 。换句话说—可以没有VRRP Stack,但健康检查healthchecking是一定要有的。
- VRRP Stack 负责负载均衡器之间的失败切换FailOver;不是必须的。
- IPVS wrapper 用来发送设定的规则到内核ipvs代码;
- Netlink Reflector 用来设定 vrrp 的vip地址等;
VRRP协议:Virtual Router Redundancy Protocol ,虚拟路由器冗余协议;
VRRP是一种容错协议,它保证当主机的下一跳路由器出现故障时,由另一台路由器来代替出现故障的路由器进行工作,从而保持网络通信的连续性和可靠性。
VRRP将局域网内的一组路由器划分在一起,形成一个VRRP备份组,它在功能上相当于一台虚拟路由器,使用虚拟路由器号进行标识。
虚拟路由器有自己的虚拟IP地址和虚拟MAC地址,它的外在表现形式和实际的物理路由器完全一样。局域网内的主机将虚拟路由器的IP地址设置为默认网关,通过虚拟路由器与外部网络进行通信。
虚拟路由器是工作在实际的物理路由器之上的。它由多个实际的路由器组成,包括一个Master路由器和多个Backup路由器。Master路由器正常工作时,局域网内的主机通过Master与外界通信。
当Master路由器出现故障时,Backup路由器中的一台设备将成为新的Master路由器,接替转发报文的工作。
VRRP的优点:
- 简化网络管理。在具有多播或广播能力的局域网(如以太网)中,借助VRRP能在某台设备出现故障时仍然提供高可靠的缺省链路;有效避免单一链路发生故障后网络中断的问题,而无需修改动态路由协议、路由发现协议等配置信息,也无需修改主机的默认网关配置。
- 适应性强。VRRP报文封装在IP报文中,支持各种上层协议。
- 网络开销小。VRRP只定义了一种报文——VRRP通告报文,并且只有处于Master状态的路由器可以发送VRRP报文。
相关术语:
- 虚拟路由器:由一个 Master路由器和多个Backup路由器组成。主机将虚拟路由器当作默认网关。
- VRID:虚拟路由器的标识。有相同VRID的一组路由器构成一个虚拟路由器。(0-255)
- Master路由器:虚拟路由器中承担报文转发任务的路由器。
- Backup路由器:Master路由器出现故障时,能够代替Master路由器工作的路由器。
- 虚拟IP地址:虚拟路由器的IP地址。一个虚拟路由器可以拥有一个或多个IP地址。
- IP地址拥有者:接口IP地址与虚拟IP地址相同的路由器被称为IP地址拥有者。
- 虚拟MAC地址:一个虚拟路由器拥有一个虚拟MAC地址。虚拟MAC地址的格式为00-00-5E-00-01-{VRID}。通常情况下,虚拟路由器回应ARP请求使用的是虚拟MAC地址,只有虚拟路由器做特殊配置的时候,才回应接口的真实MAC地址。
- 优先级:VRRP根据优先级来确定虚拟路由器中每台路由器的地位。
- 非抢占方式:如果Backup路由器工作在非抢占方式下,则只要Master路由器没有出现故障,Backup路由器即使随后被配置了更高的优先级也不会成为Master路由器。
- 抢占方式:如果Backup路由器工作在抢占方式下,当它收到VRRP报文后,会将自己的优先级与通告报文中的优先级进行比较。如果自己的优先级比当前的Master路由器的优先级高,就会主动抢占成为Master路由器;否则,将保持Backup状态。
VRRP的工作过程:
- 虚拟路由器中的路由器根据优先级选举出Master。Master路由器通过发送免费的ARP报文,将自己的虚拟MAC地址通知给与它连接的设备或者主机,从而承担报文转发任务;
- Master路由器周期性发送VRRP报文,以公布其配置信息(优先级等)和工作状况;
- 如果Master路由器出现故障,虚拟路由器中的Backup路由器将根据优先级重新选举新的Master;
- 虚拟路由器状态切换时,Maste路由器由一台设备切换为另外一台设备,新的Master路由器只是简单地发送一个携带虚拟路由器的MAC地址和虚拟IP地址信息的免费ARP报文;这样就可以更新与它连接的主机或设备中的ARP相关信息。网络中的主机感知不到Master路由器已经切换为另外一台设备。
- Backup路由器的优先级高于Master路由器时,由Backup路由器的工作方式(抢占方式和非抢占方式)决定是否重新选举Master。
VRRP优先级的取值范围为0到255(数值越大表明优先级越高),可配置的范围是1到254,优先级0为系统保留给路由器放弃Master位置时候使用,255则是系统保留给IP地址拥有者使用。
当路由器为IP地址拥有者时,其优先级始终为255。因此,当虚拟路由器中存在IP地址拥有者时,只要其工作正常,则为Master路由器。
Master路由器主动放弃Master地位(如Master路由器退出虚拟路由器)时,会发送优先级为0的VRRP报文,致使Backup路由器快速切换变成Master路由器。
这个切换的时间称为Skew time,计算方式为:(256-Backup路由器的优先级)/256,单位为秒。
为了提高安全性,VRRP还提供了认证功能,VRRP提供了三种认证方式:
- 无认证:不进行任何VRRP报文的合法性认证,不提供安全性保障。
- 简单字符认证:在一个有可能受到安全威胁的网络中,可以将认证方式设置为简单字符认证。发送VRRP报文的路由器将认证字填入到VRRP报文中;
而收到VRRP报文的路由器会将收到的VRRP报文中的认证字和本地配置的认证字进行比较。如果认证字相同,则认为接收到的报文是合法的VRRP报文;否则认为接收到的报文是一个非法报文。 - MD5认证:在一个非常不安全的网络中,可以将认证方式设置为MD5认证。发送VRRP报文的路由器利用认证字和MD5算法对VRRP报文进行加密,加密后的报文保存在Authentication Header(认证头)中。
收到VRRP报文的路由器会利用认证字解密报文,检查该报文的合法性。
负载分担模型
在路由器的一个接口上可以创建多个虚拟路由器,使得该路由器可以在一个虚拟路由器中作为Master路由器,同时在其他的虚拟路由器中作为Backup路由器。
负载分担方式是指多台路由器同时承担业务,因此负载分担方式需要两个或者两个以上的虚拟路由器,每个虚拟路由器都包括一个Master路由器和若干个Backup路由器,各虚拟路由器的Master路由器可以各不相同。
在上图中,有三个虚拟路由器:
- 虚拟路由器 1:Device A 作为Master 路由器,Device B 和Device C 作为Backup 路由器。
- 虚拟路由器 2:Device B 作为Master 路由器,Device A 和Device C 作为Backup 路由器。
- 虚拟路由器 3:Device C 作为Master 路由器,Device A 和Device B 作为Backup 路由器。
在配置优先级时,需要确保三个虚拟路由器中各路由器的VRRP优先级形成一定的交叉,使得一台路由器尽可能不同时充当2个Master路由器。
安装keepalived
# yum install -y keepalived
# rpm -ql keepalived
/etc/keepalived
/etc/keepalived/keepalived.conf
/etc/sysconfig/keepalived
/usr/bin/genhash
/usr/lib/systemd/system/keepalived.service
/usr/libexec/keepalived
/usr/sbin/keepalived
/usr/share/doc/keepalived-1.2.13/keepalived.conf.SYNOPSIS #详细配置参数说明可以查看这里;
/usr/share/doc/keepalived-1.2.13/samples/keepalived.conf.sample
/usr/share/doc/keepalived-1.2.13/samples/keepalived.conf.vrrp.lvs_syncd
/usr/share/doc/keepalived-1.2.13/samples/keepalived.conf.misc_check_arg
启动服务
# systemctl start keepalived
# systemctl enable keepalived
keepalived的进程树:
PID
111 Keepalived <-- Parent process monitoring children
112 \_ Keepalived <-- VRRP child
113 \_ Keepalived <-- Healthchecking child
配置keepalived
一个功能完整的keepalived配置文件包含三块:全局定义块、VRRP实例定义块及虚拟服务器定义块。
如果在只有一个负载均衡器的场合,就不须VRRP实例定义块。
# man keepalived
# man keepalived.conf
GLOBAL CONFIGURATION
contains subblocks of Global definitions and Static routes;
Global definitions
Static routes/addresses
VRRPD CONFIGURATION
contains subblocks of VRRP synchronization group(s) and VRRP instance(s);
VRRP synchronization group(s)
VRRP instance(s)
describes the moveable IP for each instance of a group in vrrp_sync_group.
LVS CONFIGURATION
contains subblocks of Virtual server group(s) and Virtual server(s);
Virtual server group(s)
Virtual server(s)
A virtual_server can be a declaration of one of:
vip vport (IPADDR PORT pair)
fwmark <INT>
virtual_server IP port | #定义一个虚拟服务;
virtual_server fwmark int |
delay_loop <INT> #定义服务检测的时间间隔;
lb_algo rr|wrr|lc|wlc|lblc|sh|dh #LVS scheduler.
lb_kind NAT|DR|TUN #LVS的类型;
interface <STRING> #VIP绑定的网卡
lvs_sync_daemon_interface <STRING> #实时同步主的会话到备节点
persistence_timeout <INT> #持久连接时长;单位为秒;
protocol TCP #协议类型;
sorry_server <IPADDR> <PORT> #RS to add when all realservers are down.
real_server <IPADDR> <PORT> { #定义real server;每个rs由一个单独的上下文定义;
weight <INT> #权重;默认为1;
notify_up <STRING>|<QUOTED-STRING> #节点上线时的通知脚本;
notify_down <STRING>|<QUOTED-STRING> #节点离线时的通知脚本;
# HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHECK #pick one healthchecker;健康状态检测方式;
HTTP_GET|SSL_GET {
url {
path <STRING> #健康状态检测时请求的资源的URL;
digest <STRING> #基于获取的内容的摘要进行健康状态判定;
status_code <INT>
}
nb_get_retry <INT> #尝试的次数;
delay_before_retry <INT> #两次尝试之间的时间间隔;
connect_ip <IP ADDRESS> #健康状态检测时连接的IP地址;默认是rs的地址;
connect_port <PORT> #健康状态检测时连接的端口;默认是rs的端口;
bindto <IP ADDRESS> #发出健康状态检测时使用的源地址;
bind_port <PORT> #源端口;
connect_timeout <INTEGER> #连接的超时时长;默认为5秒;
}
TCP_CHECK {
nb_get_retry <INT>
delay_before_retry <INT>
connect_ip <IP ADDRESS>
connect_port <PORT>
bindto <IP ADDRESS>
bind_port <PORT>
connect_timeout <INTEGER>
}
通过调用脚本高可用其它服务
vrrp_script:自定义一个资源监控脚本;可被多个实例调用,因此,定义在vrrp实例之外;
track_script:调用vrrp_script定义的脚本去监控资源;定义在vrrp实例之内,调用事先定义好的vrrp_script;
示例:如果httpd进程检测失败,可以通过notify.sh脚本重启httpd;
定义一个检测脚本:
# vim /etc/keepalived/notify.sh
#!/bin/bash
#
contact='root@localhost'
notify() {
mailsubject="$(hostname) to be $1: vip floating"
mailbody="$(date +'%F %T'): vrrp transition, $(hostname) changed to be $1"
echo $mailbody | mail -s "$mailsubject" $contact
}
case $1 in
master)
notify master
;;
backup)
notify backup
systemctl restart httpd #变为backup后,自动重启httpd;
;;
fault)
notify fault
systemctl restart httpd
;;
*)
echo "Usage: $(basename $0) {master|backup|fault}"
exit 1
;;
esac
调用脚本:
vrrp_script chk_httpd {
script "killall -0 httpd && exit 0 || exit 1" #这里不是kill进程,而是判断进程是否存在;
interval 2 #check every 2 seconds
weight -5 #if failed, decrease 5 of the priority
}
vrrp_instance VI_1 {
...
track_script {
chk_httpd
}
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}
在master上,手动关闭httpd服务,如果在httpd自动重启后,不想让其一直是master,可以设定工作模式为非抢占模式;