keepalived 是一个类似于 layer3, 4 & 5 交换机制的软件,也就是我们平时说的第 3 层、第 4层和第 5 层交换。 Keepalived 的作用是检测 web 服务器的状态,如果有一台 web 服务器死机,或工作出现故障,Keepalived 将检测到,并将有故障的 web 服务器从系统中剔除,当 web 服务器工作正常后 Keepalived 自动将 web 服务器加入到服务器群中,这些工作全部自动完成,不需要人工干
涉,需要人工做的只是修复故障的 web 服务器。
Layer3,4&5 工作在 IP/TCP 协议栈的 IP 层, TCP 层,及应用层,。
Layer3: Keepalived 使用 Layer3 的方式工作式时, Keepalived 会定期向服务器群中的服务器发送一个 ICMP 的数据包(既我们平时用的 Ping 程序) , 如果发现某台服务的 IP 地址没有激活,Keepalived 便报告这台服务器失效,并将它从服务器群中剔除,这种情况的典型例子是某台服务器被非法关机。 Layer3 的方式是以服务器的 IP 地址是否有效作为服务器工作正常与否的标准。
Layer4: 主要以 TCP 端口的状态来决定服务器工作正常与否。如 web server 的服务端口一般是80,如果 Keepalived 检测到 80 端口没有启动,则 Keepalived 将把这台服务器从服务器群中删除。
Layer5: Layer5 就是工作在具体的应用层了,比 Layer3,Layer4 要复杂一点,在网络上占用的带宽也要大一些。 Keepalived 将根据用户的设定检查服务器程序的运行是否正常,如果与用户的设定不相符,则 Keepalived 将把服务器从服务器群中剔除。
拓展:VRRP/HSRP
虚拟路由冗余协议(Virtual Router Redundancy Protocol,简称 VRRP)是由 IETF 提出的解决局
域网中配置静态网关出现单点失效现象的路由协议。使用组播方式通信。
VRRP 是一种路由容错协议,也可以叫做备份路由协议。一个局域网络内的所有主机都设置缺省路由
(默认网关),当网内主机发出的目的地址不在本网段时,报文将被通过缺省路由发往外部路由器,从而
实现了主机与外部网络的通信。当缺省路由器 down 掉(即端口关闭)之后,内部主机将无法与外部通
信,如果路由器设置了 VRRP 时,那么这时,虚拟路由将启用备份路由器,从而实现全网通信。
工作流程图
HSRP:热备份路由器协议(HSRP)的设计目标是支持特定情况下 IP 流量失败转移不会引起混乱、并允许主机使用单路由器,以及即使在实际第一跳路由器使用失败的情形下仍能维护路由器间的连通性。换句话说,当源主机不能动态知道第一跳路由器的 IP 地址时,HSRP 协议能够保护第一跳路由器不出故障,是 CISCO 的私有协议!该协议中含有多台路由器,对应一个 HSRP 组。该组中只有一个路由器承担转发用户流量的职责,这就是活动路由器。当活动路由器失效后,备份路由器将承担该职责,成为新的活动路由器。这就是热备份的原理。
HSRP 和 VRRP 的区别:HSRP 是 cisco 的专有协议.在 Cisco 的 HSRP 之后,internet 工程任务小组(internet engineering task force,IETF)也制定一种路由冗余协议:虚拟路由冗余协议(VirtualRouter Redundancy Protocol,VRRP),目前包括 Csico 在内的主流厂商均在其产品中支持 VRRP 协议!VRRP 和 HSRP 也有很多不同。VRRP 和 HSRP 的一个主要的区别在安全方面:它允许参与 VRRP组的设备间建立认证机制 。另一个主要区别 :VRRP 中只有三种状态----初始状态(Initialize)、主状态(Master)、备份状态(Backup),而 HSRP 有六种状态。其余在报文类型 、报文格式和通过 TCP而非 UDP 发送的报文方面也有所不同
1.管理 VIP,VIP 会在 LVS 之间漂移
2.监控 LVS 分发器
运行在主分发的 Keepalived 会以组播的形式向网络中宣告自己,即主分发器还活着,备用节点能收到。当备用节点,在一个时间单位中收不到组播,备用节点会认为主 LVS 挂了,开始接手主分发器工作,把 VIP 配给自己。
3.管理 RS
Keepalived 会每隔一个时间段去做一次类似于访问的操作如:
探针: elinks http://192.168.0.80 –dump
经典高可用 web 架构: LVS+keepalived+nginx+apache+php+eaccelerator(+nfs 可选)
https://www.keepalived.org/download.html Keepalived官网
使用 Keepalived 构建 LVS-DR 模式的高可用集群,实验环境如下:
机器名称 | IP | 网关 | 机器作用 |
centos-60 | DIP 192.168.0.60/24 VIP 192.168.0.66/32 |
192.168.0.1 | 主LVS |
centos-70 | DIP 192.168.0.70/24 VIP 192.168.0.66/32 |
192.168.0.1 | 备LVS |
centos-80 | 192.168.0.80/24 | 192.168.0.1 | RS1 WEB1 |
centos-90 | 192.168.0.90/24 | 192.168.0.1 | RS2 WEB2 |
网络拓扑
yum install -y keepalived
rpm -ql keepalived
ip a
在这种模式下,虚拟 IP 在某时刻只能属于某一个节点,另一个节点作为备用节点存在。当主节点不可用时,备用节点接管虚拟 IP,提供正常服务。
配置参数: 节点 centos-60(主节点); 节点 centos-70(备用节点) ; 虚拟 IP 192.168.0.66 对外提供服务的 IP。 要求默认情况下由节点 centos-60提供服务,当节点 centos-60不可用时,由节点 centos-70提供服务(即虚拟 IP 漂移至节点 centos-70)。
cd /etc/keepalived/
cp keepalived.conf keepalived.conf.bak
vim keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
root@localhost
}
notification_email_from root@localhost
smtp_server localhost
smtp_connect_timeout 30
router_id centos-60
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.0.66
}
}
virtual_server 192.168.0.66 80 {
delay_loop 6
lb_algo rr
lb_kind DR
protocol TCP
real_server 192.168.0.80 80 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
real_server 192.168.0.90 80{
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}
! Configuration File for keepalived
global_defs {
notification_email {
root@localhost
}
notification_email_from root@localhost
smtp_server localhost
! Configuration File for keepalived
global_defs {
notification_email {
root@localhost #默认三个地址,修改成可用地址
}
notification_email_from root@localhost
smtp_server localhost
smtp_connect_timeout 30
router_id centos-60 #主机标识一般设置为主机名,发送邮件时会用到
}
vrrp_instance VI_1 { #定义一个实例,一个集群就是一个实例。默认VI_1可以随意改。
state MASTER #指定A节点为主节点 备用节点上设置为BACKUP 即可
interface ens33 #绑定虚拟IP的网络接口
virtual_router_id 51#VRRP组名,两个节点的设置必须一样,以指明各个节点属于同一VRRP组
priority 100 #主节点的优先级(1-254之间),备用节点必须比主节点优先级低
advert_int 1 #组播信息发送间隔,两个节点设置必须一样
authentication { #设置验证信息,两个节点必须一致
auth_type PASS
auth_pass 1111
}
virtual_ipaddress { #指定虚拟IP,两个节点设置必须一样
192.168.0.66
}
}
#类似添加一个服务 ipvsadm -A -t 192.168.0.66:80 -s rr
virtual_server 192.168.0.66 80 {#定义虚拟服务器,需指定虚拟 ip 和端口
delay_loop 6 #keepalived多少秒检测一次RS
lb_algo rr #分发算法
lb_kind DR #DR模式
nat_mask 255.255.255.0
persistence_timeout 50 # 长连接保持时间,50s内同一IP的请求会发送给同一RS
protocol TCP
#类似 ipvsadm -a -t 192.168.0.66:80 -r 192.168.0.80 -g
real_server 192.168.0.80 80 {#配置服务节点1,需要指定realserver的真实IP地址和端口,IP不同端口之间用空格隔开
weight 1 #配置服务节点的权值,权值大小用数字标识,数字越大权值越高
TCP_CHECK { #检查TCP的80端口,即layer4
connect_timeout 3 #RS 3秒无响应,则超时
nb_get_retry 3 #超时重试次数
delay_before_retry 3 #3秒重试一次,即重试间隔
connect_port 80 #检测端口
}
}
#类似 ipvsadm -a -t 192.168.0.66:80 -r 192.168.0.90 -g
real_server 192.168.0.90 80{
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
real_server 192.168.0.90 80{
weight 1 #指定权重
HTTP_GET { #设置检测后端 realserver 的方式为获取 http 协议报文
url {
path /
status_code 200 #状态码为 200 则证明后端服务器是在线的
}
connect_timeout 3 #设置超时时间
nb_get_retry 3 #设置超时时候重试几次
delay_before_retry 3 #在重试的时候的时间间隔
}
}
systemctl restart keepalived
systemctl enable keepalived
ipvsadm -Ln --stats
ipvsadm -Z
ipvsadm -C
systemctl restart keepalived
ipvsadm -Ln --stats
一个virtual_server
就是一个LVS集群,对应一个vrrp_instance实例,如果要在一台主机上配置多个LVS集群,那么就需要配置多个实例。
ip a | grep ens33
yum install -y keepalived
cd /etc/keepalived/
cp keepalived.conf keepalived.conf.bak
scp /etc/keepalived/keepalived.conf [email protected]:/etc/keepalived/
vim /etc/keepalived/keepalived.conf
systemctl restart keepalived
systemctl enable keepalived
ip a | grep ens33
ipvsadm -Ln --stats
ipvsadm -Z
ipvsadm -C
systemctl restart keepalived
ipvsadm -Ln --stats
centos-60主停止服务后,vip漂移到了备主机centos-70上
重启主LVS上的keepalived服务,可以看到VIP从从LVS漂移回到主LVS上。
可以通过从LVS的日志看到,在主LVS恢复后,从LVS的动作为先检查优先级,再切换到BACKUP模式,最后移除VIP。
vim /etc/init.d/lvs
#!/bin/bash
#description:start relserver
VIP=192.168.0.66
source /etc/init.d/functions #加载所有环境变量
case $1 in
start)
echo 'start LVS of Realserver DR'
/sbin/ifconfig lo:1 $VIP netmask 255.255.255.255 up
/sbin/route add -host $VIP dev lo:1
echo '1' > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo '2' > /proc/sys/net/ipv4/conf/lo/arp_announce
echo '1' > /proc/sys/net/ipv4/conf/all/arp_ignore
echo '2' > /proc/sys/net/ipv4/conf/all/arp_announce
;;
stop)
/sbin/ifconfig lo:1 down
echo 'Close LVS of Realserver DR'
echo '0' > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo '0' > /proc/sys/net/ipv4/conf/lo/arp_announce
echo '0' > /proc/sys/net/ipv4/conf/all/arp_ignore
echo '0' > /proc/sys/net/ipv4/conf/all/arp_announce
;;
*)
echo "Usage:$0 (start|stop)"
exit 1
esac
[root@centos-80 ~]# chmod +x /etc/init.d/lvs
[root@centos-80 ~]# /etc/init.d/lvs start
[root@centos-80 ~]# echo "/etc/init.d/lvs start" >> /etc/rc.local #脚本加入到开机自启动
[root@centos-80 ~]# yum -y install httpd
[root@centos-80 ~]# echo centos-80 > /var/www/html/index.html
[root@centos-80 ~]# systemctl restart httpd
[root@centos-80 ~]# scp /etc/init.d/lvs [email protected]:/etc/init.d/
[root@centos-90 ~]# chmod +x /etc/init.d/lvs
[root@centos-90 ~]# /etc/init.d/lvs start
[root@centos-90 ~]# echo "/etc/init.d/lvs start" >> /etc/rc.local #脚本加入到开机自启动
[root@centos-90 ~]# yum -y install httpd
[root@centos-90 ~]# echo centos-90 > /var/www/html/index.html
[root@centos-90 ~]# systemctl restart httpd
实验环境
机器名称 | IP | 网关 | 机器作用 |
centos-60 | DIP 192.168.0.60/24 VIP 192.168.0.66/32 |
192.168.0.1 | 主LVS也是备LVS |
centos-70 | DIP 192.168.0.70/24 VIP 192.168.0.77/32 |
192.168.0.1 | 主LVS也是备LVS |
centos-80 | 192.168.0.80/24 | 192.168.0.1 | RS1 WEB1 |
centos-90 | 192.168.0.90/24 | 192.168.0.1 | RS2 WEB2 |
[root@centos-60 keepalived]# vim keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
root@localhost
}
notification_email_from root@localhost
smtp_server localhost
smtp_connect_timeout 30
router_id centos-60
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.0.66
}
}
vrrp_instance VI_2 {
state BACKUP
interface ens33
virtual_router_id 52
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.0.77
}
}
virtual_server 192.168.0.66 80 {
delay_loop 6
lb_algo rr
lb_kind DR
protocol TCP
real_server 192.168.0.80 80 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
real_server 192.168.0.90 80{
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}
virtual_server 192.168.0.77 80 {
delay_loop 6
lb_algo rr
lb_kind DR
protocol TCP
real_server 192.168.0.80 80 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
real_server 192.168.0.90 80{
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}
[root@centos-70 ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
root@localhost
}
notification_email_from root@localhost
smtp_server localhost
smtp_connect_timeout 30
router_id centos-70
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.0.66
}
}
vrrp_instance VI_2 {
state MASTER
interface ens33
virtual_router_id 52
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.0.77
}
}
virtual_server 192.168.0.66 80 {
delay_loop 6
lb_algo rr
lb_kind DR
protocol TCP
real_server 192.168.0.80 80 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
real_server 192.168.0.90 80{
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}
virtual_server 192.168.0.77 80 {
delay_loop 6
lb_algo rr
lb_kind DR
protocol TCP
real_server 192.168.0.80 80 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
real_server 192.168.0.90 80{
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}
[root@centos-80 ~]# ifconfig lo:2 192.168.0.77 netmask 255.255.255.255 up
[root@centos-90 ~]# ifconfig lo:2 192.168.0.77 netmask 255.255.255.255 up
进行主备测试
centos-60 停止服务
[root@centos-60 keepalived]# systemctl stop keepalived
可以看到vip 192.168.0.66转移到 centos-70主机上去了,现在centos-70有2个VIP了
客户端继续访问 VIP 192.168.0.66 仍然可以访问
centos-60恢复服务
[root@centos-60 keepalived]# systemctl restart keepalived
根据优先级, VIP 192.168.0.66 漂移回centos-60主机
①从keepalived的工作原理可以知道,它是在IP网络层、TCP传输层以及应用层这三个层次进行服务器检测的。若服务器不可用则从集群中剔除,若修复服务器后,则将该服务器加入集群。
②keepalived主要有3个作用:管理VIP、监控LVS分发器、管理RS。
③在本文集群中,主LVS和备LVS属于同一个vrrp分组,主LVS定期以组播的方式向备LVS宣告自身还活着,这时备LVS就不会喧宾夺主。但是当备LVS在一个周期内未收到主LVS的宣告,备LVS就会自动提升自己为主LVS,VIP也会自动从主LVS漂移到备LVS。
④keepalived常与web服务器、mysql服务器构建集群。本文就是keepalived+lvs+DR+http架构,如后端real_server监控的是3306端口,则该架构就转换为keepalived+lvs+DR+mysql。
⑤每一个vrrp_instance都是一个集群,配置主LVS和备LVS都是属于配置同一个集群,故vrrp_instance实例名要相同。主LVS为了能以主播的方式宣告自己还活着,virtual_route_id VRRP组ID必须相同。每一个keepalived又是属于自身的,故拥有不一样的route_id。区分主备可以通过state定义,当主LVS故障后,VIP根据state和集群中节点的优先级priority进行VIP漂移。一般会漂移到state为BACKUP、priority在备LVS中最高的节点上。通过以上配置,可以扩展为一主多备,多主多备。
⑥2台服务器可以实现主备、主主。主备属于同一集群,而主主可以看作是两个主备。3台服务器可以一主二备,三主。一主二备属于同一集群,而三主可以看作是三个一主二备。这样,当主LVS挂了,会有备LVS接收VIP,当备LVS挂了,会有另一台备LVS接收。实现生产环境不中断服务的高可用架构。