Keepalived总结
简介
Keepalived是Linux下一个轻量级的高可用解决方案,它与HeartBeat,RoseHA实现的功能类似,都可以实现服务或者网络的高可用,但是又有差别.HeartBeat是一个专业的,功能完善的高可用软件,它提供了HA软件所需要的基本功能,比如心跳检测和资源接管,检测集群中的系统服务,在集群节点间转移共享IP地址的所有者等,HeartBeat功能强大,但是部署和使用相对比较麻烦.而Keepalived主要是通过虚拟路由冗余来实现高可用功能的.
基本概念
VRRP(Virtual Router Redundancy Protocol)
虚拟路由器冗余协议
背景
在现实世界中,主机之间的通信都是通过配置静态路由器(默认网关)来完成的,而主机之间的路由器一旦出现故障,通信就会失败.所以引入了虚拟路由器冗余
VRRP可以将两台或者多台物理路由器设备虚拟成一个虚拟路由器,这个虚拟路由器通过虚拟IP对外提供服务,而在虚拟路由器内部,多台物理路由器协同工作,但同一时间只有一台对外提供服务.即分为Master和backup
master拥有对外服务的虚拟IP,提供各种网络功能,如ARP请求,ICMP,数据转发等.而其它backup路由器仅仅接收master的通告信息
具体选主算法可参见对zookeeper算法原理的分析
Keepalived的工作原理
OSI网络七层模型.pngKeepalived工作在TCP/IP参考模型的第三层,第四层和第五层,也就是网络层,传输层和应用层.
备注:其中会话层,表示层,应用层可以统一看作是应用层
网络层
在网络层,运行着四个重要的协议:互联网协议(IP),互联网控制报文协议(ICMP),地址转换协议(ARP)以及反向地址转换协议(RARP).Keepalived在网络层采用最常见的工作方式是通过ICMP向服务器集群中的每个节点发送一个ICMP的数据包(类似于Ping实现的功能),如果某个节点没有返回响应数据包,那么就认为此节点发生了故障,Keepalived将报告此节点失效,并从服务器集群中剔除故障节点
传输层
提供了两个重要协议:传输控制协议(TCP)和用户数据协议(UDP).
TCP可以提供可靠的数据传输服务,IP地址和端口代表一个TCP连接的一个连接端口.要获得TCP服务,需在发送机的一个端口和接收机的一个端口上建立连接,而Keepalived在传输层就是利用TCP的端口连接和扫描技术来判断集群节点是否正常的.
应用层
可以运行FTP,TELNET,SMTP,DNS等各种不同类型的高层协议
Keepalived的运行方式也更加全面化和复杂化,我们可以通过编写程序来运行Keepalived,而Keepalived将根据我们设定监测各种程序或者服务是否正常
Keepalive的体系结构
Keepalived体系结构.jpgScheduler I/O Multiplexer
是一个I/O复用分发调度器,它负责安排Keepalived所有内部的任务请求
Memory Management
一个内存管理机制,这个框架提供了访问内存的一些通用方法
Control Plane
Keepalived的控制面板,可以实现对配置文件进行编译和解析,Keepalived的配置文件解析比较特殊,它并不是一次解析所有模块的配置,而是只有在用到某模块时才解析相应的配置。
Core components
这个部分是Keepalived的核心组件,包含了一些列功能模块,主要有WatchDog、Checkers、VRRP Stack、IPVS wrapper和Netlink Reflector
(1)WatchDog
WatchDog是计算机可靠性领域中一个极为简单又非常有效的检测工具,它的工作原理是针对被监视的目标设置一个计数器和一个阈值,WatchDog会自己增加此计数值,然后等待被监视的目标周期性地重置该计数值。一旦被监控目标发生错误,就无法重置此计数值,WatchDog就会检测到,于是就采取对应的恢复措施,例如重启或关闭。
在Linux中很早就引入了WatchDog功能,而Keepalived正是通过WatchDog的运行机制来监控Checkers和VRRP进程的。
(2)Checkers
这是Keepalived最基础的功能,也是最主要的功能,可实现对服务器运行状态检测和故障隔离。
(3)VRRP Stack
这是Keepalived后来引入的VRRP功能,可以实现HA集群中失败切换(Failover)功能。Keepalived通过VRRP功能再结合LVS负载均衡软件即可部署一套高性能的负载均衡集群系统。
(4)IPVS wrapper
这是IPVS功能的一个实现。IPVS wrapper模块可以将设置好的IPVS规则发送到内核空间并提交给IPVS模块,最终实现IPVS模块的负载均衡功能。
(5)Netlink Reflector
用来实现高可用集群中Failover时虚拟IP(VIP)的设置和切换。Netlink Reflector的所有请求最后都发送到内核空间的NETLINK模块来完成。
Keepalived 的安装
(1)使用 yum 源在线安装
yum install keepalived
(2)离线 tar 包方式安装
- 下载 Keepalived for Linux 解压安装。
- 以 Keepalived for Linux - Version 1.2.13 版本为例。
[root@nodeA ~]# tar -zxvf keepalived-1.2.13.tar.gz
[root@nodeA ~]# cd keepalived-1.2.13
[root@nodeA keepalived-1.2.13]# ./configure
[root@nodeA keepalived-1.2.13]# make & make install
配置安装成功
Keepalived configuration
------------------------
Keepalived version : 1.2.13
Compiler : gcc
Compiler flags : -g -O2
Extra Lib : -lssl -lcrypto -lcrypt
Use IPVS Framework : Yes
IPVS sync daemon support : Yes
IPVS use libnl : No
fwmark socket support : Yes
Use VRRP Framework : Yes
Use VRRP VMAC : Yes
SNMP support : No
SHA1 support : No
Use Debug flags : No
最终安装成功
ake complete
make[1]: Leaving directory `/root/keepalived-1.2.13/keepalived'
make -C genhash
make[1]: Entering directory `/root/keepalived-1.2.13/genhash'
gcc -g -O2 -I/usr/src/linux/include -I/usr/src/linux/include -I../lib -Wall -Wunused -Wstrict-prototypes -c -o main.o main.c
gcc -g -O2 -I/usr/src/linux/include -I/usr/src/linux/include -I../lib -Wall -Wunused -Wstrict-prototypes -c -o sock.o sock.c
gcc -g -O2 -I/usr/src/linux/include -I/usr/src/linux/include -I../lib -Wall -Wunused -Wstrict-prototypes -c -o layer4.o layer4.c
gcc -g -O2 -I/usr/src/linux/include -I/usr/src/linux/include -I../lib -Wall -Wunused -Wstrict-prototypes -c -o http.o http.c
gcc -g -O2 -I/usr/src/linux/include -I/usr/src/linux/include -I../lib -Wall -Wunused -Wstrict-prototypes -c -o ssl.o ssl.c
Building ../bin/genhash
strip ../bin/genhash
Make complete
make[1]: Leaving directory `/root/keepalived-1.2.13/genhash'
Make complete
Keepalived 配置
- keepalived 只有一个配置文件 keepalived.conf,其中包含了三类配置区域。
全局配置 Global Configuration
全局配置区域包含了 global_defs(全局配置标识)、static_ipaddress(静态地址)、static_routes(静态路由) 区域配置项。
global_defs 区域
主要是配置故障发生时的通知对象以及机器标识。
global_defs {
notification_email {
a@abc.com
b@abc.com
...
}
notification_email_from admin@example.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
enable_traps
router_id node1
}
配置项 | 说明 |
---|---|
notification_email | 故障发生时给谁发邮件通知。 |
notification_email_from | 通知邮件从哪个地址发出。 |
smpt_server | 通知邮件的 smtp 地址。 |
smtp_connect_timeout | 连接 smtp 服务器的超时时间。 |
enable_traps | 开启 SNMP 陷阱(Simple Network Management Protocol)。 |
router_id | 标识本节点的字条串,通常为 hostname,但不一定非得是 hostname。故障发生时,邮件通知会用到。 |
static_ipaddress 和 static_routes 区域
配置的是本节点的 IP 和 路由 信息。如果机器上已经配置了 IP 和路由,那么这两个区域可以不用配置。
static_ipaddress {
10.210.214.163/24 brd 10.210.214.255 dev eth0
...
}
static_routes {
10.0.0.0/8 via 10.210.214.1 dev eth0
...
}
VRRP 配置
- VRRP 配置区域主要包含了 vrrp_instance(VRRP 实例)、vrrp_sync_group(VRRP 同步组)、vrrp_script(VRRP 脚本) 、virtual_server 区域配置项。
vrrp_instance 和 vrrp_sync_group 区域
- vrrp_instance 用来定义对外提供服务的 VIP 区域及其相关属性。
- vrrp_rsync_group 用来定义 vrrp_intance 组,使得这个组内成员动作一致。例如两个 vrrp_instance 同属于一个 vrrp_rsync_group,那么其中一个vrrp_instance 发生故障切换时,另一个 vrrp_instance 也会跟着切换(即使这个 instance 没有发生故障)。
vrrp_sync_group VG_1 {
group {
inside_network # name of vrrp_instance (below)
outside_network # One for each moveable IP.
...
}
notify_master /path/to_master.sh
notify_backup /path/to_backup.sh
notify_fault "/path/fault.sh VG_1"
notify /path/notify.sh
smtp_alert
}
vrrp_instance VI_1 {
state MASTER
interface eth0
use_vmac <VMAC_INTERFACE>
dont_track_primary
track_interface {
eth0
eth1
}
mcast_src_ip <IPADDR>
lvs_sync_daemon_interface eth1
garp_master_delay 10
virtual_router_id 1
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 12345678
}
virtual_ipaddress {
10.210.214.253/24 brd 10.210.214.255 dev eth0
192.168.1.11/24 brd 192.168.1.255 dev eth1
}
virtual_routes {
172.16.0.0/12 via 10.210.214.1
192.168.1.0/24 via 192.168.1.1 dev eth1
default via 202.102.152.1
}
track_script {
check_running
}
nopreempt
preempt_delay 300
debug
notify_master <STRING>|<QUOTED-STRING>
notify_backup <STRING>|<QUOTED-STRING>
notify_fault <STRING>|<QUOTED-STRING>
notify <STRING>|<QUOTED-STRING>
smtp_alert
}
配置项 | 说明 |
---|---|
notify_master | 分别表示切换为主时所执行的脚本。 |
notify_backup | 分别表示切换为备时所执行的脚本。 |
notify_fault | 分别表示切换出错时所执行的脚本。 |
notify | 表示任何一状态切换时都会调用该脚本,并且该脚本在以上三个脚本执行完成之后进行调用,keepalived 会自动传递三个参数 |
smt_palert | 表示是否开启邮件通知(用全局区域的邮件设置来发通知)。 |
state | 可以是 MASTER 或 BACKUP,不过当其他节点 keepalived 启动时会将 Priority(优先级)比较大的节点选举为 MASTER,因此该项其实没有实质用途。 |
interface | 节点固有 IP(非 VIP)的网卡,用来发 VRRP 包。因为在配置虚拟 IP 的时候必须是在已有的网卡上添加的。 |
use_vmac 是否使用 VRRP 的虚拟 MAC 地址。不配置即不使用 dont_track_primary | 忽略 VRRP 网卡错误。(默认未设置) |
track_interface | 设置额外的监控,监控以下网卡,如果任何一个不通就会切换到 FALT 状态。(可选项) |
mcast_src_ip | 修改 vrrp 组播包的源地址,默认源地址为 master 的 IP。(由于是组播,因此即使修改了源地址,该 master 还是能收到回应)。这里实际上就是在哪个地址上发送 VRRP 通告,一定要选择稳定的网卡端口来发送,如果没有设置那么就用默认的绑定的网卡的 IP,也就是 interface 指定的 IP 地址。 |
lvs_sync_daemon_interface | 绑定 lvs syncd 的网卡。 |
garp_master_delay | 当切为主状态后多久更新 ARP 缓存,默认 5 秒。 |
virtual_router_id | 设置 VRID,取值在 0-255 之间,用来区分多个 instance 的 VRRP 组播(同一网段中 virtual_router_id 的值不能重复,否则会出错)。将决定多播的 MAC 地址 |
priority | 用来选举 master,要成为 master,这个选项的值最好高于其他机器 50 个点,该项取值范围是 1-255(在此范围之外会被识别成默认值 100)。 |
advert_int | 发 VRRP 包的时间间隔,即多久进行一次 master 选举(可以认为是健康查检时间间隔,默认为 1 秒)。 |
authentication | 认证区域,认证类型(auth_type)有 PASS 和 HA(IPSEC),推荐使用 PASS(密码只识别前 8 位)。认证密码(auth_pass)。 |
virtual_ipaddress | VIP(虚拟 IP 地址),随着 state 的变化而增加删除,当 state 为 master 的时候就添加,当 state 为 backup 的时候删除,主要由优先级来决定的,和 state 设置的值没有多大关系,可以设置多个 IP 地址。 |
virtual_routes | 虚拟路由,当 IP 漂过来之后需要添加的路由信息。原理和 virtual ipaddress 一样,只不过这里是增加和删除路由。 |
virtual_ipaddress_excluded | 发送的 VRRP 包里不包含的 IP 地址,为减少回应 VRRP 包的个数。在网卡上绑定的 IP 地址比较多的时候用。 |
lvs_sync_daemon_interface | lvs syncd 绑定的网卡。 |
nopreempt | 允许一个 priority 比较低的节点作为 master,即使有 priority 更高的节点启动。设置不抢占,只能设置在 state 为 backup 的节点上。次要实现类似于关闭 auto failback 的功能需要将所有节点的 state 都设置为 backup,或者将 master 节点的priority 设置的比 backup 低。 |
preempt_delay | 抢占延迟,master 启动多久之后进行接管资源(VIP/Route 信息等),前提是没有 nopreempt 选项。 |
debug | debug 级别。 |
track_script | 引用健康检查脚本 |
vrrp_script 区域
- 用来做健康检查,当时检查失败时会将 vrrp_instance 的 priority 减少相应的值。
- 首先在 vrrp_script 区域定义脚本名字和脚本执行的间隔和脚本执行的优先级变更。然后在实例 vrrp_instance 里面引用,有点类似脚本里面的函数引用一样:先定义,后引用函数名。
vrrp_script check_running {
script "/usr/local/bin/check_running"
interval 10
weight 10
}
配置项 | 说明 |
---|---|
script | 健康检查脚本名称 |
interval | 脚本执行间隔 |
weight | 脚本结果导致的优先级变更:10 表示优先级 +10;-10 则表示优先级 -10。 |
VRRP 脚本 vrrp_script 和 VRRP 实例 vrrp_instance 属于同一个级别。
使用 Keepalived 实现双机热备
双机热备是指两台机器都在运行,但并不是两台机器都同时在提供服务。
当提供服务的一台出现故障的时候,另外一台会马上自动接管并且提供服务,而且切换的时间非常短。
至少需要两台服务器,其中一台为 master 始终提供服务,另外一台作为 backup 始终处于空闲状态。
准备工作
两台物理服务器和一个虚拟服务器(VIP)
master redhat6.5 192.168.102.31 nodeA
backup redhat6.5 192.168.102.32 nodeB
192.168.102.30 VIP
防火墙设置
注意:务必要设置防火墙开放端口,VRRP 协议需要 master 不断发送 “状态正常” 的广播信息,一旦 backup 不能收到 master 的广播信息,backup 会尝试切换到 master 状态来接管 VIP。
iptables -I INPUT -i eth0 -d 224.0.0.0/8 -p vrrp -j ACCEPT
iptables -I OUTPUT -o eth0 -d 224.0.0.0/8 -p vrrp -j ACCEPT
service iptables restart
安装并配置 Keepalived
主机 nodeA 上的配置
global_defs {
router_id nodeA
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
nopreempt
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.102.30
}
}
备机 nodeB 上的配置
global_defs {
router_id nodeB
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 50
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.102.30
}
}
master 上运行 Keepalived 的效果。
[root@nodeA keepalived]# tailf /var/log/messages
Oct 26 02:30:13 nodeA Keepalived_vrrp[12147]: Configuration is using : 61594 Bytes
Oct 26 02:30:13 nodeA Keepalived_vrrp[12147]: Using LinkWatch kernel netlink reflector...
Oct 26 02:30:13 nodeA Keepalived_vrrp[12147]: VRRP sockpool: [ifindex(2), proto(112), unicast(0), fd(10,11)]
Oct 26 02:30:13 nodeA Keepalived_healthcheckers[12146]: Configuration is using : 6137 Bytes
Oct 26 02:30:13 nodeA Keepalived_healthcheckers[12146]: Using LinkWatch kernel netlink reflector...
Oct 26 02:30:14 nodeA Keepalived_vrrp[12147]: VRRP_Instance(VI_1) Transition to MASTER STATE
Oct 26 02:30:15 nodeA Keepalived_vrrp[12147]: VRRP_Instance(VI_1) Entering MASTER STATE
Oct 26 02:30:15 nodeA Keepalived_vrrp[12147]: VRRP_Instance(VI_1) setting protocol VIPs.
Oct 26 02:30:15 nodeA Keepalived_vrrp[12147]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 192.168.102.30
Oct 26 02:30:15 nodeA Keepalived_healthcheckers[12146]: Netlink reflector reports IP 192.168.102.30 added
Oct 26 02:30:20 nodeA Keepalived_vrrp[12147]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 192.168.102.30
*master 上通过 ip addr 可以看到 192.168.102.30 绑定到了 eth0 上。
[root@nodeA ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:06:15:3b brd ff:ff:ff:ff:ff:ff
inet 192.168.102.31/21 brd 192.168.103.255 scope global eth0
inet 192.168.102.30/32 scope global eth0
inet6 fe80::20c:29ff:fe06:153b/64 scope link
valid_lft forever preferred_lft forever
backup 上运行 Keepalived 的效果。
Oct 26 06:57:52 nodeB Keepalived_vrrp[3333]: Opening file '/etc/keepalived/keepalived.conf'.
Oct 26 06:57:52 nodeB Keepalived_healthcheckers[3332]: Registering Kernel netlink reflector
Oct 26 06:57:52 nodeB Keepalived_healthcheckers[3332]: Registering Kernel netlink command channel
Oct 26 06:57:52 nodeB Keepalived_healthcheckers[3332]: Opening file '/etc/keepalived/keepalived.conf'.
Oct 26 06:57:52 nodeB Keepalived_healthcheckers[3332]: Configuration is using : 6115 Bytes
Oct 26 06:57:52 nodeB Keepalived_vrrp[3333]: Configuration is using : 61572 Bytes
Oct 26 06:57:52 nodeB Keepalived_vrrp[3333]: Using LinkWatch kernel netlink reflector...
Oct 26 06:57:52 nodeB Keepalived_vrrp[3333]: VRRP_Instance(VI_1) Entering BACKUP STATE
Oct 26 06:57:52 nodeB Keepalived_vrrp[3333]: VRRP sockpool: [ifindex(2), proto(112), unicast(0), fd(10,11)]
Oct 26 06:57:52 nodeB Keepalived_healthcheckers[3332]: Using LinkWatch kernel netlink reflector...
- 查看 ip_vs 模块 是否自动加载成功。
[root@nodeA ~]# lsmod | grep ip_vs
ip_vs 141092 0
nf_conntrack 133387 3 ip_vs,xt_conntrack,nf_conntrack_ipv4
libcrc32c 12644 3 xfs,ip_vs,nf_conntrack
防火墙配置
Centos 6.5 中使用 iptables
iptables -I INPUT -i ${interface} -d 224.0.0.0/8 -p vrrp -j ACCEPT
iptables -I OUTPUT -o ${interface} -d 224.0.0.0/8 -p vrrp -j ACCEPT
service iptables save
Centos 7 中使用 firewalld
firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface ${interface} --destination 224.0.0.18 --protocol vrrp -j ACCEPT
firewall-cmd --direct --permanent --add-rule ipv4 filter OUTPUT 0 --out-interface ${interface} --destination 224.0.0.18 --protocol vrrp -j ACCEPT
firewall-cmd --reload