前言
在前面我们介绍了多种实现高可用性的解决方案。而实现高可用集群的组件有 heartbeat、corosync、cman和keepalived。对于前面三种集群组件而言都需要借助相应的CRM程序来完成高可用服务。如前面 讲到的利用heartbeat+haresource来实现http高可用集群、利用corosync+pacemaker(或 heartbeat+pacemaker)来实现mysql的高可用集群以及使用RHCS组件中自带的集群组件CMAN+Rgmanager来实现 http的高可用集群。其实这三种集群组件实现的功能都差不多,因此,使用哪种解决方案来实现高可用服务就因人而异了。不过常用的集群组件一般都是 heartbeat和corosync,它们都可以和pacemaker结合起来工作。只不过corosync比heartbeat的功能更加强大和丰 富,因此如果想要和pacemaker结合起来实现高可用集群,首选应该是corosync。好了,来说说keepalived吧。keepalived 也是一种集群组件,它也是实现高可用集群的一种解决方案,只不过它通常用来实现IPVS的高可用集群。即lvs中的前端director高可用集群。
keepalived简介
keepalived 是一个基于VRRP协议来实现IPVS的高可用的解决方案。对于LVS负载均衡来说,如果前端的调度器direct发生故障,则后端的 realserver是无法接受请求并响应的。因此,保证前端direct的高可用性是非常关键的,否则后端的服务器是无法进行服务的。而我们的 keepalived就可以用来解决单点故障(如LVS的前端direct故障)问题。keepalived的主要工作原理是:运行keepalived 的两台服务器,其中一台为MASTER,另一台为BACKUP,正常情况下,所有的数据转换功能和ARP请求响应都是由MASTER开完成的,一旦 MASTER发生故障,则BACKUP会马上接管MASTER的工作,这种切换时非常迅速的。
并且MASTER和BACKUP组成一个虚拟服务器, 虚拟服务器有一个虚拟IP地址和一个虚拟MAC地址,这个虚拟IP地址就是对外服务的地址,虚拟IP地址总是运行在MASTER上。因此即便是 MASTER发生故障,则BACKUP也参加竞选成为MASTER,因此也就具备了虚拟IP地址,继续向外提供服务。而keepalived之所以能够实 现高可用功能,完全是因为它是基于VRRP协议来工作的,因此VRRP协议是keepalived的核心。所在在说keepalived之前,还是先来了 解下VRRP协议吧。
VRRP协议
VRRP协议叫做虚拟路由冗余协议,从它的名称就可以知道它是用来提供冗余功能的。它是为了解决静态路由单 点故障而设计的一个主从模式的协议,一旦MASTER节点发生故障,其该节点上的服务和IP地址会立刻转移到BACKUP节点上,从而继续提供高可用性。 对于了解网络的朋友,都知道在设计网络的时候,必须要考虑到网络的冗余,这里的冗余指的是设备冗余。否则,一旦某一个单点路由器发生故障,其下行所有用户都不能上网了,这种现象是非常严重的。
而 VRRP协议却可以很好的解决这个问题。VRRP协议设计的思想就是将多个物理路由器虚拟成一个路由器。这个路由器我们称作为虚拟路由器。虚拟路由器上有 一个IP地址,叫做虚拟IP地址。这个虚拟IP地址是向外提供某种服务的地址或者当做某些主机或节点的网关地址。在这多个物理路由器上,拥有这个虚拟IP 地址的路由器叫做MASTER路由器,其他的则是BACKUP路由器。只有MASTER路由器才能接受和转发数据,BACKUP路由器是不能转发数据的。 对于谁能够成为MASTER路由器,需要根据每个路由器自身的优先级来判断的。对于虚拟路由器而言,只要有一台物理路由器是正常的,则虚拟路由器永远都不 会发生故障,因此,即便MASTER路由器发生故障,其他的BACKUP也会立即参加竞选成为MASTER,从而继续提供数据转发功能和保证网络的连续 性。
VRRP路由器
在这里先解释一下,这里所说的路由器在linux系统下则叫做服务器或者节点,而在网络中,专业的叫法则是称作为路由器。叫法虽不同,但是表达的都是一个意思。
VRRP路由器就是一台物理路由器,只是这台路由器上面运行了vrrp协议或者VRRPD程序。一台VRRP路由器可以位于多个虚拟路由器中。
虚拟路由器
虚拟路由器就是将多个VRRP路由器通过某种方式组成一个路由器,既然是虚拟的,就是说并不是实际存在的。虚拟路由器的标识符叫做虚拟路由器ID(VRID),其ID范围是0-255。
VRRP实例
VRRP实例就是提供某种相同服务或相同路由的一组路由器,每一个组就是一个实例。
MASTER和BACKUP
在一个虚拟路由器中,有多个VRRP路由器, 这些VRRP路由器中又有一个叫做MASTER路由器,其他的则叫做BACKUP路由器。当VRRP协议在每一个物理路由器上初始启动时,则所有的路由器 都会发送VRRP通告信息,且都会参加竞选成为MASTER路由器。其中每一个路由器都有一个priority,priority最大的路由器将会成为 MASTER路由器,其他的则是BACKUP路由器。如果priority相同,则每个路由器上IP地址最大的路由器将会成为MASTER路由器。
MASTER路由器拥有虚拟IP地址,且负责响应ARP报文请求和转发数据。BACKUP只能接受VRRP报文通告。它不会抢占成为MASTER,除非它有更高的优先级。
VRRP协议的工作机制
VRRP 路由器是通过竞选协议来实现虚拟路由器功能的,所有的VRRP报文都是通过多播的形式向外发送。虚拟路由器是由虚拟路由器ID(VRID)和虚拟IP地址 组成的。虚拟路由器上有一个虚拟的MAC地址,其地址格式为:00-00-5E-00-01-{VRID}。所以,不管谁是MASTER路由器,其对外提 供服务的IP(为VIP)和MAC地址(为虚拟MAC地址)都是相同的。客户端并不会因为MASTER的改变而改变,对他们来说,这种主从切换时透明的。
默认情况下,竞选成功后,只有MASTER路由器能够发送通告信息,且每个1秒钟发送一次。如果BACKUP路由器在 这段时间内,没有收到MASTER路由器的VRRP通告信息,则认为MASTER路由器宕机,则BACKUP路由器中优先级最高的路由器会抢占成为为新的 MASTER路由器。当然也可以通过VRRP接口跟踪功能来改变路由器的优先级以便让最高优先级的路由器成为MASTER。它的跟踪机制是:如果 MASTER上监控的某个接口发生故障,则MASTER的priority值会相应降低,且降低后的priority值一定要小于BACKUP上的 priority值。这样才可以保证,其他的BACKUP能够抢占成为新的MASTER路由器。
由于出于安全性的考虑,因此,MASTER和BACKUP之间的数据是加密传输的。
VRRP的主从模式
在这种模式下,只有一个MASTER,其他的则作为BACKUP。其中MASTER负责数据转发和响应ARP请求。
VRRP双主模式
在这种模式下,两台路由器都是MASTER路由器,每一台路由器上都运行着2个服务,其中每一台路由器即充当这个服务中的MASTER路由器又充当另一个服务的BACKUP路由器。在这种模式下,可以实现流量负载共享功能,即可以在多个设备上转发数据。
例如:有2个路由器, 分别是server1和server2,且这两个路由器都运行着httpd和mysqld服务,对于server1来说,它即充当着httpd服务中的 MASTER,又充当着mysqld服务中的BACKUP服务器。而server2即充当着mysqld服务中的MASTER,又充当着httpd服务中 的BACKUP服务。
VRRP中的ARP处理机制
在VRRP协议中,只有MASTER才能够响应ARP请求,因此,当MASTER收到ARP请求时,它响应的是虚拟mac地址,而不是实际的物理机mac地址。因此,不管那台服务器作为MASTER其虚拟MAC地址都不会变,所以对于对端本机而言,其通信的目标mac地址仍然是虚拟mac地址,它是不会发生改变的。因此也就不会影响到对端主机的通信了。
VRRP的优势:
冗余性:可以使用多个路由器设备作为LAN客户端的默认网关,大大降低了默认网关成为单点故障的可能性;
负载共享:允许来自LAN客户端的流量由多个路由器设备所共享;
多VRRP组:在一个路由器物理接口上可配置多达255个VRRP组,每一个组就是一个实例;
多IP地址:基于接口别名在同一个物理接口上配置多个IP地址,从而支持在同一个物理接口上接入多个子网;
抢占:在master故障时允许优先级更高的backup成为master;
通告协议:使用IANA所指定的组播地址224.0.0.18进行VRRP通告;
VRRP接口追踪:基于接口状态来改变其VRRP优先级来确定最佳的VRRP路由器成为master;
好了,谈完了brrp协议,我们还是回来谈谈keepalived吧!
keepalived实现高可用服务具有的特性
1、在keepalived实现IPVS的高可用服务中,当MASETR发生故障时,则MASTER上的IPVS规则被删除,且BACKUP上的IPVS增加
2、当后端的realserver或相关服务发生故障时,则在MASTER上与这个realserver相应的IPVS规则会被删除
2、keepalived的主从切换时非常迅速的,一般是秒级切换。
keepalived配置文件详解
keepalived的所有配置都在一个配置文件里,但是所有的配置分为3部分:
1、全局配置(Global Configuration)
全局配置是对整个keepalived都起效的配置。
2、VRRPD配置
VRRPD配置是keepalived的核心配置
3、LVS配置
只有当使用keepalived来配置和管理LVS,才需要配置LVS这部分。否则,如果使用keepalived来做HA,LVS的配置完全不需要。
1、全局配置
全局配置包含2段,即全局定义和静态地址路由段
全局定义
全局定义是用来设置keepalived的通知机制和vrrp路由器id的
global_defs
{
notification_email
{
[email protected] notification_email用来指定keepalived在发生事件(比如主从切换)时,需要发送email的对象。对象可以有一个或多个,每行只能定义一个。
}
notification_email_from [email protected] 指定邮件的发送人
smtp_server 127.0.0.1 这里是指定邮件服务器地址的。如果本地开启了sendmail进程,这里可以使用默认配置。
stmp_connect_timeout 30 设置与邮件服务器连接的超时时长
router_id my_hostname 设置vrrp路由器的id,用来标识路由器本身
}
静态地址和路由段
这里的静态地址就是我们常说的VIP地址,VIP不是static,它会随VRRPD而添加/删除。
static_ipaddress
{
192.168.108.100/24 brd + dev eth0 scope global 这里就是定义VIP地址的,以及发送广播通告的接口。且作用域为全局
...
}
下面一部分是用来定义路由的
static_routes
{
src $SRC_IP to $DST_IP dev $SRC_DEVICE
...
src $SRC_IP to $DST_IP via $GW dev $SRC_DEVICE
}
2、VRRPD配置
VRRPD配置端也包含2部分:VRRP同步组(synchroization Group)和VRRP实例(VRRP Instance)
VRRP同步组的作用是:当VRRP路由器上接2个网段时,即一个内网和一个外网。只要当其中的一个网段出现问题,都会导致keepalived发生切换时事件。如果不使用同步组的话,一旦外网发生故障,VRRP路由器仍然认为自己是健康的,因此不会发生切换事件。从而会导致问题。
VRRP同步组的配置
vrrp_sync_group <string> {
group { 在同步组中至少要有一个实例
inside_network 这里是用来定义实例名称的,这里有2个实例:一个叫inside_network ,一个叫outside_network
outside_network
...
}
notify_master /path/to/to_master.sh notify_master表示当切换成为master后要执行的脚本,这个脚本可以接受参数
notify_backup /path_to/to_backup.sh notify_backup表示当切换成为backup后要执行的脚本,这个脚本可以接受参数
notify_fault "/path/fault.sh VG_1" notify_falut表示当MASTER和BACKUP都发生故障时要执行的脚本
notify /path/to/notify.sh
smtp_alert 这个表示当keepalived发生切换事件时要发送邮件给Global_defs中定义的对象
}
VRRP实例配置
VRRP实例配置主要是定义了VRRP同步组中每一个实例的具体信息
vrrp_instance inside_network { 这里的实例名称必须是vrrp_sync_group中定义的
state MASTER 这里定义的是vrrp路由器的初始状态,状态只有2中:MASTRT和BACKUP。当2台路由器都启动后,马上就会参加竞选,priority高的路由器会成为MASTER。这里的state并不表示这台路由器一直是MASTER。
interface eth0 定义的是需要监测的接口,这个接口是与实例绑定在一起的
dont_track_primary 忽略vrrp的接口错误,默认不设置
track_interface { 这里是设置要监控的接口,其中任何一个接口出现问题,都会进入FALUT状态
eth0
eth1
}
mcast_src_ip <IPADDR> 定义多播地址,如果不设置,默认使用绑定网卡的Primary IP
garp_master_delay 10 当状态变成MASTER后,延迟进行免费ARP请求
virtual_router_id 51 定义虚拟路由器的ID。ID号的范围为0-255
priority 100 定义VRRP路由器的优先级,处于MASTER状态的VRRP路由器的优先级一定要比处于BACKUP状态的VRRP路由器的优先级要大
advert_int 1 MASTER和BACKUP同步检查的间隔时间,默认为1秒
authentication { 这一段是用来设置认证的,只有认证通过,才可以竞选成为MASTER或BACKUP
auth_type PASS 设置认证类型,支持的认证类型有PASS和AH
autp_pass 1234 设置认证密码,MASTER和BACKUP的密码要一样才可以通过认证
}
virtual_ipaddress { 这里是定义虚拟路由器地址的,即VIP地址。当服务器的状态切换成MASTER后,这些地址会被添加;当切换成BACKUP时,这些地址会被删除。因此, 每台服务器上不需要绑定任何地址,keepalived会自动使用ip addr进行绑定。
#<IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPT> label <LABEL>
192.168.108.100/24 dev eth1
192.168.108.101/24 dev eth2 label eth2:1
}
virtual_routes { 这里是用来定义虚拟路由的,当服务器的状态切换成MASTER后,这些路由会被添加;当切换成BACKUP时,这些路由会被删除
# src <IPADDR> [to] <IPADDR>/<MASK> via|gw <IPADDR> dev <STRING> scope <SCOPE> tab
src 192.168.100.1 to 192.168.109.0/24 via 192.168.200.254 dev eth1
192.168.110.0/24 via 192.168.200.254 dev eth1
192.168.111.0/24 dev eth2
192.168.112.0/24 via 192.168.100.254
}
nopreempt 设置不抢占功能。且这个参数只能设置在BACKUP上。而且这个BACKUP的优先级要比另一台BACKUP的优先要高(如果有另一个BACKUP的话)
preemtp_delay 300 设置抢占延迟时间,默认为5分钟,即300秒
debug 设置为Debug级别
}
3、LVS配置
对于LVS配置这部分,只有当使用keepalived来管理和配置LVS时才需要这部分的配置。否则这部分可以不需要。
LVS配置包含2部分:虚拟服务器组(Virtual Server Group)和虚拟服务器(Virtual Server)。这些配置都会传递给ipvsadm作为参数。
虚拟服务器组(Virtual Server Group)
这一段配置的主要目的是让一台realserver上的某个service可以属于多个Virtual Server,并且只做一次健康状况检查。
virtual_server_group <STRING> {
# VIP port
<IPADDR> <PORT>
<IPADDR> <PORT>
...
fwmark <INT>
}
虚拟服务器配置
Virtual Server可以以下面3种方式的任意一种方式进行配置:
a、 virtual server IP port
b、 virtual server fwmark int
c、 virtual server group string
这里以a方式的配置来说明
virtual_server 192.168.108.100 80 { 定义虚拟服务器的地址和(服务)端口,这个地址是之前定义好的VIP地址
delay_loop 3 定义每隔几秒钟检查一下realserver的状态
lb_algo rr|wrr|lc|wlc|lblc|sh|dh LVS的调度算法
lb_kind NAT|DR|TUN LVS的集群模式
persistence_timeout 120 会话保持时长,如果在这段时间内用户没有进行任何操作,则用户的下一次请求会被调度到另一个节点上去。因此,这种情况下,可能会导致之前保留的session信息不在另一个节点上,会出现一些意外现象。
persistence_granularity <NETMASK> 会话保持粒度,ipvsadm中的-M参数,默认是0xffffffff,即根据每个客户端做会话保持。
protocol TCP 使用的协议是TCP还是UDP
virtualhost <string>
sorry_server <IPADDR> <PORT> 定义一个备用机的ip地址和服务端口。当所有的realserver都失效后才会启用,可以用来返回一些提示信息给用户。
#下面是用来定义realserver的,每一个realserver都需要定义其相关配置,如下:
real_server <IPADDR> <PORT> 这里是realserver的ip地址和服务端口
{
weight 1 定义服务器的权重
inhibit_on_failure 在服务器健康状况检查失败后,将其weight设置为0,而不是直接从ipvs中删除
notify_up <STRING> | <QUOTED-STRING> 在检测到service up时执行的脚本
notify_down <STRING> | <QUOTED-STRING> 在检测到service down时执行的脚本
#下面定义的是一些服务的健康检查方式。健康检查方式只需要定义一次即可,如http服务既可以使用http服务的健康检查方式来配置也可以使用TCP服务的健康检查方式来配置,只需要配置一段即可。
HTTP_GET | SSL_GET 这里定义是http和https的检查方式
{
url { http和https检查的url,如果有多个url,可以定义多个。每一个url使用“{}”括起来
path / http服务检查的默认路径
digest <STRING> https检查后的摘要信息
status_code 200 http检查的返回状态码
}
connect_port 80 健康检查的服务端口
bindto <IPADD> 以此地址发送请求对服务器端进行健康检查
connect_timeout 连接超时时间
nb_get_retry 3 设置重连次数
delay_before_retry 2 重连间隔时间
}
#下面配置的是对所有的TCP服务进行健康检查的方式。对于
TCP_CHECK { TCP服务的健康检查方式
connect_port 80
bindto 192.168.1.1
connect_timeout 4
}
SMTP_CHECK { SMTP服务的健康检查方式
host {
connect_ip <IP ADDRESS>
connect_port <PORT>
bindto <IP ADDRESS>
}
connect_timeout <INTEGER>
retry <INTEGER>
delay_before_retry <INTEGER>
helo_name <STRING>|<QUOTED-STRING smtp helo请求命令的参数
}
#下面定义的是MISC健康检查方式,执行一个程序
MISC_CHECK
{
misc_path <STRING>|<QUOTED-STRING> 这里是一个外部程序或脚本
misc_timeout <INT> 脚本执行的超时时间
#如果定义了misc_dynamic的话,健康检查程序的退出码会动态的调整服务器的weight。
#返回0,表示健康检查ok,权重wight不被修改
#返回1,表示健康检查失败,weight设置为0
#返回2-255,表示检查检查ok,weight=退出状态码-2.例如如果返回的状态码为10,则weight=10-2=8
misc_dynamic
}
}
}