Linux Keepalived
Keepalived是一个用C编写的路由软件。该项目的主要目标是为Linux系统和基于Linux的基础架构提供简单而强大的负载平衡和高可用性设施。负载平衡框架依赖于众所周知且广泛使用的Linux虚拟服务器(IPVS)内核模块,提供Layer4负载均衡。Keepalived实现了一组检查器,以根据其健康状况动态地和自适应地维护和管理负载平衡的服务器池。另一方面,VRRP实现了高可用性协议。VRRP是路由器故障转移的基础。此外,Keepalived为VRRP有限状态机实现了一组挂钩,提供低级和高速协议交互。为了提供最快的网络故障检测,Keepalived实现了BFD协议。VRRP状态转换可以考虑BFD提示来驱动快速状态转换。Keepalived框架可以单独使用,也可以一起使用,以提供灵活的基础架构。
keepalived由于其非常轻量所以常常与lvs或nginx反向代理一起使用,用于实现director的高可用,就像天造地设的一对儿!keepalived在功能上虽然没有HeartBeat和corosync等程序强大,往往需要借助一些外部的脚本文件来辅助完成各种细节上的功能,但是只是为了高可用director而不是大型成百上千台主机的话,还是keepalived比较好用;后两个由于其功能多且强大,所以适合更大型的高可用集群;
keepalived角色:
Active/Passive 活动节点和备用节点
相对于lvs我们需要的资源只有两个:VIP地址和ipvs规则,其中ipvs规则可以在各个director上提前配置好,其实最不稳定的就是VIP地址,因为只有Active节点可以拥有VIP地址从而向外提供服务;所以keepalived的功能就是当Active节点上的服务出现故障时,Passive可以马上将VIP地址抢过来,配置到自己的网卡上,继续向外提供服务;但是Passive怎么知道Active是活动的、可提供服务的呢?这就需要作为Active的节点定期主动的向外发送自己还“活着“的消息(一般是通过组播的方式),通知Passive节点:只要朕不死,你永远是太子的信息;如果Passive过了指定的时间周期还没有收到Active的通知信息就认为其已经down掉了,然后自己取而代之,最为Active节点向外提供服务;
Keepalived其实就是VRRP在Linux上以守护进程方式的实现;
keepalived可以根据配置文件自动生成ipvs规则;
keepalived还可以对各后端RS进行健康状态监测;
VRRP:Virtual Route Redundant Protocol,虚拟路由冗余协议;
vrrp协议可以将多个路由器虚拟成一个大的路由器,这个大的路由器对底层是透明的,用户并不知道其内部有多个路由器,这些路由器中有一个为Master路由器,真正对外服务的设备,其他的为Backup路由器(Master为Vip地址拥有者,向外提供服务),当Master路由器故障时Backup路由器可以通过选举机制再选出一个Master来继续提供服务(其实vrrp也可以实现负载均衡,也就是将所有路由器划分成虚拟的区域(一个虚拟区域即为一个虚拟路由器),每个路由器可以属于多个虚拟区域,不同的路由器在不同的区域担任的角色不同,比如:一个路由器在area1中为Master,则在area2中就为Backup;通过将不同地址段的主机划分到不同的Master上,来实现负载均衡从而减少路由器的负载和利用闲置路由器);可以看出这跟前面描述的Keepalived的工作机制是相似的;
vrrp中关于Master和Backup的转换有两种模式:抢占模式和非抢占模式;其中抢占模式为优先级高者为Master,非抢占模式为只要当前的Master路由器是正常工作的就算有优先级更高的路由器也不会成为Master;
vrrp还支持验证功能,对于同一个虚拟区域(也就是同一个虚拟路由器)需要使用相同的字符串进行签名;其中有三种模式:不验证,简单明文验证,md5加密验证;一般都是简单的明文验证,因为开销比较小;
vrrp使用不同的vrrp id来标识不同的虚拟路由器;具有相同vrrp id的路由器为一个大的虚拟路由器;
VRRP的先关信息可以在H3C或者华为的官网中查找相关的资料,有很多!
配置前提:关闭防火墙,selinux;
时间同步(ntp),ssh基于秘钥登录,基于主机名通信;
安装相关软件;
yum install keepalived -y
配置文件:
/etc/keepalived/keepalived.conf
global_defs { }:全局配置段;
vrrp_instance { }:vrrp实例段,也就是用来实现虚拟路由器的;
vrrp_sync_group { }:vrrp同步组,可以实现多个ip地址一起迁移;
vritual_server { }:虚拟服务器,也就是指定LVS后端RS服务器的;如果是高可用nginx就用不到这一块;
global_defs {
notification_email { 指定将各种信息发送到指定邮箱
[email protected] 邮箱地址
}
notification_email_from [email protected] 发件人邮箱
smtp_server 192.168.200.1 指定邮件服务器地址
smtp_connect_timeout 30 指定邮件服务器的连接超时时间
router_id LVS_DEVEL 定义当前设备的ID号,唯一
vrrp_skip_check_adv_addr 是否检查来自同一个路由器的vrrp通告地址
vrrp_garp_interval 0 指定发送免费ARP的延时 单位为ms
vrrp_mcast_group4 224.0.0.18 指定VRRP通告信息的组播地址,可以不配置;
}
vrrp_sync_group VG_1 { vrrp同步组,可以将多个IP地址一起进行故障转移,比如使用lvs-nat模式时,面向外网的VIP需要和面向内网的DIP一起转移,才可以继续提供服务;
group {
inside_network # name of the vrrp_instance
outside_network # One for each movable IP
}
}
例子:
vrrp_instance OUTSIDE {
eth0
VIP
}
vrrp_instance INSIDE {
eth0
DIP
}
vrrp_sync_group VG_1 {
group {
INSIDE
OUTSIDE
}
}
vrrp_instance VI_1 { 指定vrrp实例名称
state MASTER 指定Master/Backup状态
interface eth0 指定在哪块网卡接口上配置VIP地址
virtual_router_id 51 指定虚拟路由器id
priority 100 指定优先级
advert_int 1 VRRP通告间隔 单位为s
preempt | nopreempt 指定keepalived的工作模式,默认为抢占模式
notify_master
当keepalived状态转变成Master时就执行后面的字符串(脚本)
notify_backup
当keepalived状态转变成Backup时就执行后面的脚本
notify_fault
当keepalived故障时就执行后面的脚本
notify_stop
当keepalived停止时就执行后面的脚本
notify
只要keepalived状态改变就执行后面的脚本
Note:上面的notify后面一般都会接一个关于发送邮件的脚本,用于当keepalived出现各种情况时,能够马上通知管理员来进行检查;
authentication { VRRP验证配置段
auth_type PASS 指定验证类型
auth_pass 1111 指定验证时使用的字符串,建议更改一个复杂一点的
}
virtual_ipaddress { 指定虚拟IP地址(VIP)
192.168.200.16
192.168.200.17
192.168.200.18
}
}
Note:如果实现的是nginx的高可用,则无需下面的配置;
virtual_server 192.168.200.100 443 { 指定虚拟服务的地址及接口
delay_loop 6 指定向RS服务器进行健康状态检测的轮询延迟时间
lb_algo rr|wrr|lc|wlc|lblc|sh|dh 指定LVS调度器类型
lb_kind NAT LVS转发模式 NAT,TUN,DR
persistence_timeout 50 LVS持久连接超时时间
protocol TCP 指定所使用的传输层协议类型
virtualhost
sorry_server 192.168.200.200 1358 指定sorry服务器地址,当RS服务器全部宕机以后,所有的访问都会被指向sorry服务器;sorry服务器上一般都是通告一些类似“服务器正在维修,暂时无法提供信息”这种信息;一般都是使用directory作为sorry服务器
real_server 192.168.201.100 443 { 指定RS服务器地址及端口
weight 1 指定权重
notify_up
当进行健康状态检测以后RS状态为UP后通过调用相关的脚本通知管理员;
notify_down
当进行健康状态检测以后RS状态为DOWN后通过调用相关的脚本通知管理员;
SSL_GET|HTTP_GET|TCP_CHECK { 设置SSL_GET、HTTP_GET或TCP_CHECK等健康检查方式
url { URL配置段
path / 设置请求指定信息页的地址路径
digest ff20ad2481f97b1754ef3e12ecd3a9cc 指定摘要信息
}
url {
path /mrtg/
digest 9b3a0c85a887a256d6939da88aabd8cd
作为健康状态监测页面的校验码,需要手动生成以后填写在这里,然后用它跟每次请求的页面做对比,如果相同就表示状态健康;
}
status_code 200 指定返回的HTTP头部中的状态码
Note:上面的设置是通过请求指定的信息,如果请求成功就表示后端服务器处于正常运行;
connect_timeout 3 超时连接时间
nb_get_retry 3 请求失败以后的重试次数
delay_before_retry 3 重试之前的延迟时间
connect_ip
connect_port
bindto
bind_port
connect_timeout
}
}
}
后面的配合类似,之所以列出是为了展示一个virtual_server中可以配置多个RS,便于仿照配置;
virtual_server 10.10.10.2 1358 {
delay_loop 6
lb_algo rr
lb_kind NAT
persistence_timeout 50
protocol TCP
sorry_server 192.168.200.200 1358
real_server 192.168.200.2 1358 {
weight 1
HTTP_GET {
url {
path /testurl/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
url {
path /testurl2/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
url {
path /testurl3/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
real_server 192.168.200.3 1358 {
weight 1
HTTP_GET {
url {
path /testurl/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334c
}
url {
path /testurl2/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334c
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}
配置例子:我列出的仅为一端的配置,在另一边别忘做相关的修改
global_defs {
notification_email {
root@localhost
}
notification_email_from guowei@localhost
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id node2
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass e57b49ed
}
virtual_ipaddress {
192.168.80.12
}
}
添加日志文件;
vim /etc/sysconfig/keepalived
KEEPALIVED_OPTIONS="-D -S 3"
vim /etc/rsyslog.conf
local3.* /var/log/keepalived.log
启动keepalived:
systemctl restart rsyslog.service
systemctl start keepalived.service
维护方法:
当Active升级keepalived版本时,一般需要停掉当前的keepalived服务,但这种方法明显是不太好的,我们可以通过外部的脚本手动的将其调度为备用服务器之后,再进行升级;
在配置文件中添加以下一段:
vim /etc/keepalived/keepalived.conf
vrrp_script chk_schedown {
script "/etc/keepalived/keepalived_down.sh" 指定欲运行的脚本
Note:script这个指令会执行外部的脚本,然后根据脚本执行成功与否的状态来决定下面指令的执行,一般都是与weight命令配合使用;如果weight命令为负值(其实正负都一样,为负就加负值,为正就加正值),则当script执行脚本失败时,此端的优先级(priority)就变为:原优先级与weight的和,即(100+(-2))=98,如果执行成功则优先级不变即100;何为脚本执行失败?答:echo $? 的值为非0(取值在0-255之间),即为失败;可以在脚本中使用exit来手动指定脚本执行成功与否;
interval 2 指定脚本调用的间隔时间
weight -2
user root
}
vrrp_instance VI_1 {
track_script {
chk_schedown
}
} 此处的意思是track_script{ }要放在vrrp_instance{ }中;
vim /etc/keepalived/keepalived_down.sh
#!/bin/bash
if [[ -f /etc/keepalived/down ]]
then
exit 1
fi
exit 0
当在/etc/keepalived/目录中创建down文件时,本端优先级就会减2,从而就会由Master转成Backup;
chmod +x /etc/keepalived/keepalived_down.sh
实现负载均衡:也就是将两台主机上的keepalived划分成两个虚拟主机VI_1和VI_2,其中一台主机在VI_1中为MASTER,在VI_2中为BACKUP;另一台主机在VI_1中为BACKUP,在VI_2中为MASTER;在上面的基础上再添加下面的内容即可:
vrrp_instance VI_2 {
state BACKUP
interface ens33
virtual_router_id 52
priority 99
advert_int 1
authentication {
auth_type PASS
auth_pass r57b49rd
}
virtual_ipaddress {
192.168.80.20
}
track_script {
chk_schedown
}
}
添加邮件通知功能:
vim /etc/keepalived/keepalived.conf 在vrrp_instance VI_1中添加一下内容
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
脚本:
#!/bin/bash
vip=192.168.80.12
contact=’root@localhost’
notify () {
mailsubject=”`hostname` to be $1:$vip floating” 邮件主题
mailbody=”`date ‘+%F %H:%M:%S’`:vrrp transition ,`hostname` changed to be $1”
消息内容:时间和状态转移情况
echo $mailbody | mail -s “$mailsubject” $contact 邮件发送
}
case “$1” in
master)
notify master
exit 0
;;
backup)
notify backup
exit 0
;;
fault)
notify fault
exit 0
;;
*)
echo ‘Usage:`basename $0` {master|backup|fault}’
exit 1
;;
esac
实现LVS负载均衡:
实验环境:两个director(centos7:192.168.80.130和node2:192.168.80.136),两个RS(clone1:192.168.80.131和clone2:192.168.80.134),使用LVS的DR模式,其中director使用keepalived实现高可用;
RS端:
yum install httpd -y
echo "
echo $mailbody | mail -s "$mailsubject" $contact
}
case "$1" in
master)
notify master
systemctl restart nginx.service
exit 0
;;
backup)
notify backup
exit 0
;;
fault)
notify fault
exit 0
;;
*)
echo 'Usage:`basename $0` {master|backup|fault}'
exit 1
;;
esac
BACKUP端:
#!/bin/bash
vip=192.168.80.12
contact='root@localhost'
notify () {
mailsubject="`hostname` to be $1:$vip floating"
mailbody="`date '+%F %H:%M:%S'`:vrrp transition,`hostname` changed to be $1"
echo $mailbody | mail -s "$mailsubject" $contact
}
case "$1" in
master)
notify master
exit 0
;;
backup)
notify backup
systemctl restart nginx.service
exit 0
;;
fault)
notify fault
exit 0
;;
*)
echo 'Usage:`basename $0` {master|backup|fault}'
exit 1
;;
esac
注:根据马哥视频做的学习笔记,如有错误,欢迎指正;侵删;
借鉴文章:https://blog.csdn.net/hzsunshine/article/details/62041036