keepalived配置及典型应用案例
keepalived配置及典型应用案例
?
使用源码先安装keepalived?1.2.6
cd?/usr/local/src
wget?http://www.keepalived.org/software/keepalived-1.2.6.tar.gz
tar?zxf?keepalived-1.2.6.tar.gz?
cd?keepalived-1.2.6
./configure?--prefix=/usr/local/keepalived?
make
make?install
?
所设keepalived安装到/usr/local/keepalived,?则所有配置文件均位于此目录之下。我一直没搞明白一个问题,Linux默认总是将程序安装到/usr/local目录下,所有程序共享了/usr/local/sbin目录。这对一些人的操作习惯是有影响的。为何不考虑使用每个软件一个独立的目录呢?
?
1.?建立服务启动脚本,以便使用service命令控制之
cp?/usr/local/keepalived/etc/rc.d/init.d/keepalived?/etc/init.d/keepalived
chmod?+x?/etc/init.d/keepalived
?
因为我们使用非默认路径(/usr/local)安装keepalived,?故需要修改几处路径,以保证keepalived能正常启动,?需要修改的文件如下:
2.?修改/etc/init.d/keepalived,?寻找大约15行左右的.?/etc/sysconfig/keepalived,?修改为:
.??/usr/local/keepalived/etc/sysconfig/keepalived,?即指向正确的文件位置
同时在上述行下添加以下内容(将keepavlied主程序所在路径导入到环境变量PATH中):
PATH="$PATH:/usr/local/keepalived/sbin"
export?PATH
3.?修改/usr/local/keepalived/etc/sysconfig/keepalived文件,设置正确的服务启动参数
KEEPALIVED_OPTIONS="-D?-f?/usr/local/keepalived/etc/keepalived/keepalived.conf"
?
4.?经过以上修改,keepalived基本安装即可完成,启动测试之:
service?keepalived?restart
?
5.?切勿忘记将此服务设置为开机启动
chkconfig?keepalived?on
?
默认的配置文件中,指定了两个数个虚拟IP?:?192.168.200.16??192.168.200.17??192.168.200.18
可使用ip?addr命令验证之。
?
以上实验只需要一台主机,因为当前节点被指定为主节点,且没有收到其它节点的VRRP组播信息,故自动绑定了虚拟IP。
?
参考案例一:主-备模式
在这种模式下,虚拟IP在某时刻只能属于某一个节点,另一个节点作为备用节点存在。当主节点不可用时,备用节点接管虚拟IP,提供正常服务。
节点A?192.168.0.11?(主节点),?节点B?192.168.0.12(备用节点)??虚拟IP(对外提供服务的IP?192.168.0.200?
要求默认情况下由节点A提供服务,当节点A不可用时,由节点B提供服务(即虚拟IP漂移至节点B)。
?
节点A上的配置文件/usr/local/keepalived/etc/keepalived/keepalived.conf
global_defs?{
???notification_email?{
?????root@localhost
???}
???notification_email_from?root@localhost
???smtp_server?localhost
???smtp_connect_timeout?30
???router_id?NodeA
}
?
默认的配置文件中,使用第三方smtp服务器,但这在现实中几乎没有意义(需要验证的原因),我们将其指定为localhost,?将通知信息的发送交给本地sendmail服务处理。查阅说明文档得知route_id配置是为了标识当前节点,我将其设置为NodeA。当然两个节点的此项设置可相同,也可不相同。
vrrp_instance?VI_1?{
????state?MASTER??#指定A节点为主节点?备用节点上设置为BACKUP即可
????interface?eth0??#绑定虚拟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.200.16/24
????????192.168.200.17/24
????????192.168.200.18/24
????}
}
?
默认的配置文件中,竟然没有子网掩码,从而导致使用了默认子网掩码255.255.255.255,如果导致无法从其它机器访问虚拟IP(keepalived虚拟IP无法ping通)。
?
按同样的方法配置节点B并修改配置文件,可将A节点的配置文件复制到B节点,并修改以下几项:
router_id??NodeB
state??BACKUP
priority??99
?
其它项不必修改。
测试及验证:拔掉节点A的网线,就发现虚拟IP已经绑定到节点B上,再恢复A节点的网线,虚拟IP又绑定回节点A之上。
但是这种方式存在恼裂的可能,即两个节点实际都处于正常工作状态,但是无法接收到彼此的组播通知,这时两个节点均强行绑定虚拟IP,导致不可预料的后果。
这时就需要设置仲裁,即每个节点必须判断自身的状态(应用服务状态及自身网络状态),要实现这两点可使用自定义shell脚本实现,通过周期性地检查自身应用服务状态,并不断ping网关(或其它可靠的参考IP)均可。当自身服务异常、或无法ping通网关,则认为自身出现故障,就应该移除掉虚拟IP(停止keepalived服务即可)。主要借助keepalived提供的vrrp_script及track_script实现:
在keepalived的配置文件最前面加入以下代码,定义一个跟踪脚本:
vrrp_script?check_local?{?#定义一个名称为check_local的检查脚本
????script?"/usr/local/keepalived/bin/check_local.sh"?#shell脚本的路径
????interval?5??#运行间隔
}
?
再在vrrp_instance配置中加入以下代码使用上面定义的检测脚本:
track_script?{
check_local
}
?
我们在/usr/local/keepalived/bin/check_local.sh定义的检测规则是:
1. 自身web服务故障(超时,http返回状态不是200)
2.??无法ping通网关
3.??产生以上任何一个问题,均应该移除本机的虚拟IP(停止keepalived实例即可)
?
但这里有个小问题,如果本机或是网关偶尔出现一次故障,那么我们不能认为是服务故障。更好的做法是如果连续N次检测本机服务不正常或连接N次无法ping通网关,才认为是故障产生,才需要进行故障转移。另一方面,如果脚本检测到故障产生,并停止掉了keepalived服务,那么当故障恢复后,keepalived是无法自动恢复的。我觉得利用独立的脚本以秒级的间隔检查自身服务及网关连接性,再根据故障情况控制keepalived的运行或是停止。
?
这里提供一个思路,具体脚本内容请大家根据自己的需要编写即可。
?
如下图的案例:
?
?
假设节点A和B组成主备关系,A为备用节点,B为主节点,那么当在图标红叉位置发生网络故障时,节点A接收不到节点B的组播通知,将抢占虚拟IP。这时出现的后果就是节点A和节点B均拥有虚拟IP,就可能导致了脑裂。所以我们以网关IP连通性作为参考,可避免此问题产生。
?
?
参考案例二:双主模式
主备模式的缺点就是始终只有一台机器位于工作状态,另外一台机器永远是备用状态,存在资源浪费之问题。
双主模式允许两台机器均处于工作状态并互相作为备份。
搭建keepalived双方模式的要素:
1. 必须有两个虚拟IP,?分别绑定至两个节点上
2. 每个节点作为某个虚拟IP的主节点,并同时作为另外一个虚拟IP的备用节点。
3.当某个节点产生故障时,两个虚拟IP自动绑定至正常节点上
?
参阅相关文章,这就相当于使用两台物理路由器(普通主机视为路由器即可),构造出两个虚拟VRRP路由器。
?
也就是说,两个节点的配置应该是交叉的,对同个虚拟IP,交叉互为主备。
节点A的关键配置:
vrrp_instance?vip1?{
????state?MASTER
????interface?eth0
????virtual_router_id?51??#本机两个vrrp_instance组的此值不能相同,但对应备用节点的此值必须相同
????priority?99#对应备用节点值应该比此值小
????advert_int?1
????authentication?{
????????auth_type?PASS
????????auth_pass?1111
????}
????virtual_ipaddress?{
????????192.168.100.1/24
????}
}
?
vrrp_instance?vip2?{
????state?BACKUP
????interface?eth0
????virtual_router_id?52?#本机两个vrrp_instance组的此值不能相同,但对应主节点的此值必须相同
????priority?90??#主节点的值应该比此值大
????advert_int?1
????authentication?{
????????auth_type?PASS
????????auth_pass?1111
????}
????virtual_ipaddress?{
????????192.168.100.2/24
????}
}
?
复制节点A的配置至B节点,并将MASTER修改为BACKUP,?同时将BACKUP修改为MASTER。优先级和虚拟路由器组id(virtual_route_id)要特别注意其它配置必须保持相同。
?
B节点的配置:
vrrp_instance?vip1?{
????state?BACKUP
????interface?eth0
????virtual_router_id?51
????priority?90
????advert_int?1
????authentication?{
????????auth_type?PASS
????????auth_pass?1111
????}
????virtual_ipaddress?{
????????192.168.100.1/24
????}
}
?
vrrp_instance?vip2?{
????state?MASTER
????interface?eth0
????virtual_router_id?52
????priority?99
????advert_int?1
????authentication?{
????????auth_type?PASS
????????auth_pass?1111
????}
????virtual_ipaddress?{
????????192.168.100.2/24
????}
}
?
另外,为了保证服务可靠性,我们应该在每个节点运行shell脚本检测本机的服务是否正常,一旦检测到服务异常时,停止掉本机的keepalived,?如此虚拟IP自动转移到备用机器之上,如每隔3秒检测一次本机服务状态,如果连接3次检测失败,则停止掉keepalived实例。同时如果本机服务是正常的,但是keepalived没有启动(故障恢复之后),则启动keepalived,以达到故障恢复之目的。
check_service.sh文件的内容
#!/bin/bash
?
pidfile=/var/lock/subsys/`basename?$0`.pid
if?[?-f?$pidfile?]?&&?[?-e?/proc/`cat?$pidfile`?]?;?then
????exit?1
fi
?
trap?"rm?-fr?$pidfile?;?exit?0"?1?2?3?15
echo?$$?>?$pidfile
?
maxfails=3
fails=0
success=0
?
while?[?1?]
do
????/usr/bin/wget?--timeout=3?--tries=1?http://127.0.0.1/?-q?-O?/dev/null
????if?[?$??-ne?0?]?;?then
????????let?fails=$[$fails+1]
????????success=0
????else
????????fails=0
????????let?success=$[$success+1]
????fi
?
????if?[?$fails?-ge?$maxfails?]?;?then
????????fails=0
????????success=0
?
????????#check?keepalived?is?running???try?to?stop?it
????????service?keepalived?status?|?grep?running
????????if?[?$??-eq?0?]?;?then
????????????logger?-is?"local?service?fails?$maxfails?times?...?try?to?stop?keepalived."
????????????service?keepalived?stop?2>&1?|?logger
????????fi
????fi
?
????if?[?$success?-gt?$maxfails?]?;?then
????????#check?keepalived?is?stopped???try?to?start?it
????????service?keepalived?status?|?grep?stopped
????????if?[?$??-eq?0?]?;?then
????????????logger?-is?"service?changes?normal,?try?to?start?keepalived?."
????????????service?keepalived?start
????????fi
????????success=0
????fi
????sleep?3
done
?
两个节点上均应运行此脚本,请将此脚本加入到cron任务中(此程序已经作了单实例运行机制,加入计划任务的作用就是防止脚本意外中断后检测功能失效),可实现的功能:
?
如果本地服务连续三次检测失败,就尝试停止keepalived服务(如果keepalived处于运行状态)
如果本地服务连接三次检测成功,但keepalived没有启动,则启动之
关键的执行点,均已经记录到系统日志中(/var/log/messages)
?
执行crontab?-e?,?加入以下内容:
*/1??*??*??*??*?/root/check_service.sh
?
如果需要此脚本的原始文件,请联系笔者信箱zhangxugg@163.com。
?
停止掉本机的keepalived,?稍过一会,就会keepalived服务被自动启动了(这是因为本地服务检测正常)
停止掉本机的nginx,?稍过一会,就会发现keepalived服务也被停止掉了
再启动nginx,?稍过一会,发现keepalived也被正常启动,并绑定了正确的虚拟IP
?
我们可根据具体环境,将服务的检测功能强化(如检测到网关的连接性),以达到较好的故障转移效果。
?
1 楼 w520hua 2012-08-28 这个之前从没听说过,又多了一个见识,楼主厉害