Keepalived详解
keepalived主要用作RealServer的健康状态检查以及LoadBalance主机和BackUP主机之间failover的实现。
keepalived主要目的在于,其自身启动一个服务,能够实现工作在双节点或多个节点上,并且可以在内核生效的ipvs规则
其中当前持有资源的节点被称为活跃节点,另外的节点被称为备节点
被称为 Master/Backup 传承了vrrp的特***
备节点如果收不到主节点传递过来的心跳信息,之后于是将资源抢回并使用,并在本地生效规则
keepalived核心组成部分
1.vrrp的实现
2.virtual_server:基于vrrp作为所谓通告机制之上的
这段可以不用,如果不是为lvs提供高可用***的话,也可以用nginx或haporxy 等轻量级高可用***,这样可以借助vrrp调用外部脚本的方式来实现
3.vrrp_script:以外部脚本方式进行检测
vrrp状态机制
双方节点都启动之后,要实现状态转换工作,初始状态都是backup而后向对方发送通告以及自己的优先级信息,如果收到shutdown信息则转换为intalize状态,如果收到startup而且优先级为最大,意味着其为master
而对另外的节点来讲收到的startup优先级小于255,那么就意味着其角色为backup
如果某通告的时候,backup发现比自己优先级比较低,那么直接将master角色抢回来
vrrp工作流程
对于keepalived而言,系统启动起来后会生成一个主进程
master一般来讲会生成两个子进程:
·vrrp stack:用来实现负载均衡的资源转换
·vrrp checker:用来检查其可用***,能够检查realserver可用***
事实上基于一些机制或一些脚本也能检查我们服务本身的健康状况,这里只是提供IPVS后端realserver健康状态监测的
同时也实现了I/O复用的功能等
大概工作流程:
keepalived读取并分析主配置文件并生效主配置文件,而后指挥两个子进程工作的主进程(stack和checker)
但是我们看到前面有个watchdog(看门狗),其可以帮我们的主进程去监测两个子进程
主进程并不负责具体工作,所有工作都是由子进程去完成,所以两个子进程任何一个故障的话,那么这个keepalived本身并不完整,因此keepalived启动起来以后,两个子进程会每隔一段时间定期的向主进程打开一个unix内部套接的文件
两个子进程被watchdog监控了,两个子进程会定期的向unix内部套接文件写数据(发送心跳信息),如果某个子进程不再发送,那么主进程会认为其挂掉,然后再重启这个子进程
VRRP的优先级别
VRRP每个节点是有自己的优先级的,一般优先级是从0-255 ,数字越大优先级越高
因此我们可以这么定义:
假如要有一初始化的状态,其中一节点优先级100 另一节点优先级99,那么毫无疑问,谁的优先级高谁就是主节点
所有的节点刚启动后上线都是backup状态,需通过选举的方式选择master,如果其他节点没有响应则将自己提升为master
通告机制
如果节点之间master出现故障,其会自动转移当前角色,这时我们的管理员应该知道其已切换角色
keepalived支持邮件发送机制,如果其状态发生改变的话 可以通过邮件方式发送给管理员,使管理员第一时间可以查看其活动状态,方便之后的运维工作
Keepalived支持多主节点
Keepalived支持多主节点共存,但是对于同一组服务来讲,都会遵循一个法则,就是只有一个主节点,因为VIP地址只能在一个节点运行,所以它是一主多备的模式,但是备节点越多就说明浪费的资源占用越大
还需要注意的是,keepalived的转移速度和监控是非常轻量级,尤其适用于不使用共享存储、节点非常少的场景中应用
如果想要实现多主模型的话,我们可以这么去规划:
使两个节点都活动起来,运行两组资源,我们在两个物理路由基础上,做两组虚拟路由
对于第一组来讲,我们设定上面优先级高,而下面优先级比较低;
再做第二组虚拟路由,设定下面优先级高,而上面优先级比较低;
组号 |
第一组优先级 |
第二组优先级 |
vip,vmac 1 |
100/Master |
99/Slave |
vip,vmac 2 |
99/Slave |
100/Master |
那么问题又来了:
各自运行一个那么前端用户如何访问呢:
现在有2个mac地址,2个ip 对于用户看来如何访问同一个主机呢
其实可以通过DNS添加多条A记录实现轮询的方式,不同的用户解析不同的主机
但并不要求其绝对的均衡,因为我们前端很可能是提供反向代理的服务,如果是web服务的话尽可能不要使用这样的方案
因此这样一来 两个节点都能分发用户的请求到后端的各上游服务器上去,于是就能实现正常转发
VRRP同时还支持一主多备的机制,如果发现2个节点不够那么则定义3个,从而在3个节点定义3个虚拟路由,其中每一组当中,一个为主其他为备,一定要平均下来
分辨出同一组物理路由设备中的虚拟路由
vrrp必须提供一套完整的机制,简单来讲每一组虚拟路由都需要自己独有的唯一标示,说白了就是虚拟路由vrid编号,ID不能一样,因此每一次选举收到的通告信息还要查看自己属于组内哪一个角色的,因此只是将vrrp通告用于对应组的路由决策
vrrp认证机制
明文验证:
双方都设置好域共享秘钥
散列认证:
基于hmac加密方式进行认证
因为keepalived工作核心就是vrrp
对于keepalived来讲有自己的man文档,可以通过文档获取帮助
实现虚拟路由转移无非就是为了实现转移IP,如果转移多个IP的话必须将其定义为组
安装配置keepalived
实验环境规划:
服务器IP |
服务器角色 |
操作系统 |
10.0.10.61 |
Master |
CentOS 6.4 64-bit |
10.0.10.62 |
Slave |
CentOS 6.4 64-bit |
安装keepalived,由于centos6.4自带其rpm包,所以直接yum即可
[root@node1 ~]# yuminstall keepalived –y
[root@node1 ~]# cd/etc/keepalived/
[root@node1keepalived]# cat keepalived.conf
[root@node1keepalived]# cp keepalived.conf keepalived.conf.bak
修改配置文件
(被改动的参数已标红)
[root@node2 keepalived]# cat keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email_from admin@localhos {
root@localhost #通知邮箱
}
notification_email_from [email protected]
smtp_server 127.0.0.1 #smtp服务器的IP地址
smtp_connect_timeout 30 #连接邮件服务器超时时间
router_id LVS_DEVEL #路由器的标示(不是虚拟路由的标示)
}
#配置VRRPD参数
vrrp_instance VI_1 { #虚拟路由器的标示符,名称可以任意取,不用更改
state MASTER #其初始状态,选举产生之后,才可以升级为master,我们这里将其明确定义master了,那么必须定义其优先级为最大才可以
interface eth0 #选举通告哪个网卡接口
virtual_router_id 61 #虚拟路由ID号,一般不能大于255,一般取决于mac地址最后一位
priority 100 #初始优先级,如果是master必须高于其他节点
advert_int 1 #通告
authentication { #认证机制
auth_type PASS #使用哪种方式认证,PASS为明文认证
auth_pass UwQCqa1K #认证密码,最好随机生成
}
virtual_ipaddress { #虚拟地址池
10.0.10.100
}
}
由于我们目前只定义主备模型,没有定义realserver,所以往下的参数先注释 稍后再开启
注释配置文件:以当前行为首,将当前行以下全部添加注释符号
:.,$s@^@#
配置完毕将 keepalived.conf 拷贝至另外一节点
[root@node1keepalived]# scp keepalived.conf root@node2:/etc/keepalived/
更改node2的keepalived配置文件参数:
stateBACKUP #将其模式改为备节点
priority 99 #其优先级必须比master要低
保存退出并启动keepalived
[root@node1keepalived]# /etc/init.d/keepalived start
在启动主节点之前先tail megess 查看其日志变动
[root@node1 keepalived]# tail -20/var/log/messages
Jun 911:20:12 node1 Keepalived_vrrp[2022]: Interface queue is empty #Interface queue是空的
Jun 911:20:12 node1 Keepalived_vrrp[2022]: No such interface, eth1
Jun 911:20:12 node1 Keepalived_vrrp[2022]: Netlink reflector reports IP 10.0.10.61added #当前节点的IP地址
Jun 911:20:12 node1 Keepalived_vrrp[2022]: Netlink reflector reports IP 172.23.214.7added
Jun 911:20:12 node1 Keepalived_vrrp[2022]: Netlink reflector reports IPfe80::20c:29ff:fed6:6bad added
Jun 911:20:12 node1 Keepalived_vrrp[2022]: Registering Kernel netlink reflector
Jun 911:20:12 node1 Keepalived_vrrp[2022]: Registering Kernel netlink commandchannel
Jun 911:20:12 node1 Keepalived_vrrp[2022]: Registering gratuitous ARP shared channel
Jun 911:20:12 node1 Keepalived_healthcheckers[2021]: Opening file'/etc/keepalived/keepalived.conf'. #打开的配置文件,并加载此配置文件
Jun 911:20:12 node1 Keepalived_healthcheckers[2021]: Configuration is using : 7209Bytes
Jun 911:20:12 node1 Keepalived_vrrp[2022]: Opening file'/etc/keepalived/keepalived.conf'.
Jun 911:20:12 node1 Keepalived_vrrp[2022]: Configuration is using : 62902 Bytes
Jun 911:20:12 node1 Keepalived_vrrp[2022]: Using LinkWatch kernel netlinkreflector...
Jun 911:20:12 node1 Keepalived_vrrp[2022]: VRRP sockpool: [ifindex(2), proto(112),fd(10,11)] #sockpool已经打开
Jun 911:20:12 node1 Keepalived_healthcheckers[2021]: Using LinkWatch kernel netlinkreflector...
Jun 911:20:13 node1 Keepalived_vrrp[2022]: VRRP_Instance(VI_1) Transition to MASTERSTATE #已经转换为master状态
Jun 911:20:14 node1 Keepalived_vrrp[2022]: VRRP_Instance(VI_1) Entering MASTER STATE
Jun 911:20:14 node1 Keepalived_vrrp[2022]: VRRP_Instance(VI_1) setting protocolVIPs.
Jun 911:20:14 node1 Keepalived_vrrp[2022]: VRRP_Instance(VI_1) Sending gratuitousARPs on eth0 for 10.0.10.100 #并且在eth0上添加了vip地址,而且添加了gratuitous arp
Jun 911:20:14 node1 Keepalived_healthcheckers[2021]: Netlink reflector reports IP10.0.10.100 added
Jun 911:20:19 node1 Keepalived_vrrp[2022]: VRRP_Instance(VI_1) Sending gratuitousARPs on eth0 for 10.0.10.100
由此可见,其服务应该已经被启动起来了
[root@node1 ~]# ip add | awk '/inet 10.0.10.100/ {print $2}'
10.0.10.100/32
启动备节点并观察日志
[root@node2 keepalived]#/etc/init.d/keepalived start
[root@node2 keepalived]# tail/var/log/messages
Jun 913:29:07 node2 Keepalived_healthcheckers[1700]: Registering Kernel netlinkreflector
Jun 913:29:07 node2 Keepalived_healthcheckers[1700]: Registering Kernel netlinkcommand channel
Jun 913:29:07 node2 Keepalived_vrrp[1701]: Opening file'/etc/keepalived/keepalived.conf'.
Jun 913:29:07 node2 Keepalived_vrrp[1701]: Configuration is using : 62900 Bytes
Jun 913:29:07 node2 Keepalived_vrrp[1701]: Using LinkWatch kernel netlinkreflector...
Jun 913:29:07 node2 Keepalived_healthcheckers[1700]: Opening file'/etc/keepalived/keepalived.conf'.
Jun 9 13:29:07 node2Keepalived_healthcheckers[1700]: Configuration is using : 7207 Bytes
Jun 9 13:29:07 node2 Keepalived_vrrp[1701]: VRRP_Instance(VI_1) EnteringBACKUP STATE #其状态已经被转至backup状态
Jun 913:29:07 node2 Keepalived_healthcheckers[1700]: Using LinkWatch kernel netlinkreflector...
Jun 913:29:07 node2 Keepalived_vrrp[1701]: VRRP sockpool: [ifindex(2), proto(112),fd(10,11)]
现在,我们已将主备模式配置成功,接下来我们来验证是否可以实现资源转换
将主节点停,并查看备节点是否将资源转移
[root@node1 keepalived]#/etc/init.d/keepalived stop
查看备节点日志信息
[root@node2 keepalived]# tail -f/var/log/messages
Jun 9 13:39:48node2 Keepalived_vrrp[1701]: VRRP_Instance(VI_1) Transition to MASTER STATE
Jun 913:39:49 node2 Keepalived_vrrp[1701]: VRRP_Instance(VI_1) Entering MASTER STATE #已经从backup状态切换至master状态
Jun 913:39:49 node2 Keepalived_vrrp[1701]: VRRP_Instance(VI_1) setting protocolVIPs.
Jun 913:39:49 node2 Keepalived_vrrp[1701]: VRRP_Instance(VI_1) Sending gratuitousARPs on eth0 for 10.0.10.100 #已在eth0网卡中添加vip
Jun 913:39:49 node2 Keepalived_healthcheckers[1700]: Netlink reflector reports IP 10.0.10.100added
使用ip add 查看是否添加vip
[root@node2 keepalived]# ip add | awk '/inet 10.0.10.100/'
inet 10.0.10.100/32 scope global eth0
再使node1上线,其会自动再次切换至备节点状态,因为keepalived默认工作在抢占模式下,所以vrrp有两种工作模式,一种为抢占模式,一种为非抢占模式
在非抢占模式下,就算优先级在高也无法转移资源,除非节点宕机
定义Keepalived检测机制
示例:
vrrp_script chk_mantaince_down { #自定义名称
script "[[ -f/etc/keepalived/down ]] && exit 1 || exit 0"
interval 1 #检查时间间隔
weight -2 #如果条件成立则将权重-2
}
名称自定义,而后执行脚本命令,一旦这个脚本执行失败则权重要降低
每隔一秒检测一次,这个脚本可以是脚本的路径也可以是命令
定义完后,未必可以使用,还必须在打算调用脚本的虚拟路由实例上去跟踪这个脚本
如下所示:
#定义检测模块
vrrp_script chk_mantaince_down {
script "[[ -f /etc/keepalived/down ]] && exit 1 || exit0"
interval 1
weight -2
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 61
priority 99
advert_int 1
authentication {
auth_type PASS
auth_pass UwQCqa1K
}
virtual_ipaddress {
10.0.10.100
}
#调用定义的检测模块
track_script {
chk_mantaince_down
}
}
双方都配置好,并重启服务
查看node1
[root@node1 keepalived]# ip add | grep 100
inet 10.0.10.100/32 scope global eth0
创建down文件
[root@node1 keepalived]# touch down
查看日志信息
[root@node1 keepalived]# tail/var/log/messages
Jun 914:21:01 node1 Keepalived_vrrp[3974]: VRRP_Script(chk_mantaince_down) failed
Jun 914:21:03 node1 Keepalived_vrrp[3974]: VRRP_Instance(VI_1) Received higher prioadvert
Jun 914:21:03 node1 Keepalived_vrrp[3974]: VRRP_Instance(VI_1) Entering BACKUP STATE
Jun 914:21:03 node1 Keepalived_vrrp[3974]: VRRP_Instance(VI_1) removing protocolVIPs.
Jun 914:21:03 node1 Keepalived_healthcheckers[3973]: Netlink reflector reports IP10.0.10.100 removed
明确显示了已切换至backup状态,并将vip在本机移除
将node1 的 down文件删除,并查看其状态
[root@node1 keepalived]# rm -f down
[root@node1 keepalived]# ip add | awk '/inet 10.0.10.100/{print $2}'
10.0.10.100/32
总结:
事实上在keepalived中,无非是调用外来自定义脚本来实现其状态转移的,所有的脚本都可以使用vrrp_scprit调用再从vrrp_script中使用track_stript进行追踪定义的检测模块就可以了
END,感谢各位