keepalived软件起初是专为LVS负载均衡软件设计的,用来管理并监控LVS集群系统中各个服务节点状态,后来又加入了可以实现高可用的VRRP功能.此,keepalived除了能够管理LVS软件外,还可以作为其他服务(例如:Nginx,Haproxy,MySQL等)的高可用解决方案软件。
VRRP(Virtual Router Redundancy Protocol)虚拟路由器冗余协议,是一种容错的主备模式的协议,保证当主机的下一跳路由出现故障时,由另一台路由器来代替出现故障的路由器进行工作,通过VRRP可以在网络发生故障时透明的进行设备切换而不影响主机之间的数据通信。
Keepalived软件主要是通过VRRP协议实现高可用功能,在安装keepalived的服务器主机上会在配置文件中设置一个虚拟IP,当该keepalived节点为主节点且正常运行时,设置的虚拟Ip就会在该节点生效且绑定在该主机的网卡上,而其他备用主机设置的虚拟IP就不会生效。当测到主keepalived节点出现故障时,备用keepalived节点检会进行抢占提供服务,抢占成功的keepalived节点就会将配置的虚拟IP绑定在自己的网卡上,这样对外部用户来说虚拟IP提供的服务是一直可用的,当故障服务器被修复后可以正常工作时Keepalived会自动的将该服务器加入到服务器群中。在整个过程中,故障检测、故障服务器剔除以及修复后的服务器重新上线这些操作都是由keepalived自动完成,运维人员只需要关注故障服务器的修复。
[root@lb01 ~]# yum install keepalived -y
[root@lb01 ~]# rpm -qa keepalived
keepalived-1.3.5-8.el7_6.x86_64
keepalived配置文件一般在/etc/keepalived/keepalived.conf下
# 全局配置
global_defs {
# 邮件通知信息
notification_email {
# 定义收件人
acassen@firewall.loc
}
# 定义发件人
notification_email_from Alexandre.Cassen@firewall.loc
# SMTP服务器地址
smtp_server 192.168.200.1
smtp_connect_timeout 30
# 路由器标识,一般不用改,也可以写成每个主机自己的主机名
router_id LVS_DEVEL
# VRRP的ipv4和ipv6的广播地址,配置了VIP的网卡向这个地址广播来宣告自己的配置信息,下面是默认值
vrrp_mcast_group4 224.0.0.18
vrrp_mcast_group6 ff02::12
}
# 定义用于实例执行的脚本内容,比如可以在线降低优先级,用于强制切换
vrrp_script SCRIPT_NAME {
}
# 一个vrrp_instance就是定义一个虚拟路由器的,实例名称
vrrp_instance VI_1 {
# 定义初始状态,可以是MASTER或者BACKUP
state MASTER
# 工作接口,通告选举使用哪个接口进行
interface ens33
# 虚拟路由ID,如果是一组虚拟路由就定义一个ID,如果是多组就要定义多个,而且这个虚拟
# ID还是虚拟MAC最后一段地址的信息,取值范围0-255
virtual_router_id 51
# 使用哪个虚拟MAC地址
use_vmac XX:XX:XX:XX:XX
# 监控本机上的哪个网卡,网卡一旦故障则需要把VIP转移出去
track_interface {
eth0
ens33
}
# 如果你上面定义了MASTER,这里的优先级就需要定义的比其他的高
priority 100
# 通告频率,单位为秒
advert_int 1
# 通信认证机制,这里是明文认证还有一种是加密认证
authentication {
auth_type PASS
auth_pass 1111
}
# 设置虚拟VIP地址,一般就设置一个,在LVS中这个就是为LVS主机设置VIP的,这样你就不用自己手动设置了
virtual_ipaddress {
# IP/掩码 dev 配置在哪个网卡
192.168.200.16/24 dev eth1
# IP/掩码 dev 配置在哪个网卡的哪个别名上
192.168.200.17/24 dev label eth1:1
}
# 虚拟路由,在需要的情况下可以设置lvs主机 数据包在哪个网卡进来从哪个网卡出去
virtual_routes {
192.168.110.0/24 dev eth2
}
# 工作模式,nopreempt表示工作在非抢占模式,默认是抢占模式 preempt
nopreempt|preempt
# 如果是抢占默认则可以设置等多久再抢占,默认5分钟
preempt delay 300
# 追踪脚本,通常用于去执行上面的vrrp_script定义的脚本内容
track_script {
}
# 三个指令,如果主机状态变成Master|Backup|Fault之后会去执行的通知脚本,脚本要自己写
notify_master ""
notify_backup ""
notify_fault ""
}
# 定义LVS集群服务,可以是IP+PORT;也可以是fwmark 数字,也就是防火墙规则
# 所以通过这里就可以看出来keepalive天生就是为ipvs而设计的
virtual_server 10.10.10.2 1358 {
delay_loop 6
# 算法
lb_algo rr|wrr|lc|wlc|lblc|sh|dh
# LVS的模式
lb_kind NAT|DR|TUN
# 子网掩码,这个掩码是VIP的掩码
net_mask 255.255.255.0
# 持久连接超时时间
persistence_timeout 50
# 定义协议
protocol TCP
# 如果后端应用服务器都不可用,就会定向到那个服务器上
sorry_server 192.168.200.200 1358
# 后端应用服务器 IP PORT
real_server 192.168.200.2 1358 {
# 权重
weight 1
# 应用服务器UP或者DOWN,就执行那个脚本
notify_up "这里写的是路径,如果脚本后有参数,整体路径+参数引起来"
notify_down "/PATH/SCRIPTS.sh 参数"
# MSIC_CHECK|SMTP_CHEKC|TCP_CHECK|SSL_GET|HTTP_GET这些都是
# 针对应用服务器做健康检查的方法
MISC_CHECK {}
# 用于检查SMTP服务器的
SMTP_CHEKC {}
# 如果应用服务器不是WEB服务器,就用TCP_CHECK检查
TCP_CHECK {
# 向哪一个端口检查,如果不指定默认使用上面定义的端口
connect_port <PORT>
# 向哪一个IP检测,如果不指定默认使用上面定义的IP地址
bindto <IP>
# 连接超时时间
connect_timeout 3
}
# 如果对方是HTTPS服务器就用SSL_GET方法去检查,里面配置的内容和HTTP_GET一样
SSL_GET {}
# 使用HTTP_GET方法去检查
HTTP_GET {
# 检测URL
url {
# 具体检测哪一个URL
path /testurl/test.jsp
# 检测内容的哈希值,也就是网页的md5值
digest 640205b7b0fc66c1ea91c463fac6334d
# 除了检测哈希值还可以检测状态码,比如HTTP的200 表示正常,两种方法二选一即可
status_code 200
}
url {
path /testurl2/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
url {
path /testurl3/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
# 向哪一个端口检查,如果不指定默认使用上面定义的端口
connect_port <PORT>
# 向哪一个IP检测,如果不指定默认使用上面定义的IP地址
bindto <IP>
# 连接超时时间
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
}
}
}
! Configuration File for keepalived
global_defs {
# 定义故障服务报警的Email地址,作用是服务发生切换或RS节点等有故障时,需要发送的Email地址,可以有多个,每行一个
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
# 制定发送邮件的发送人,即发送人地址,也是可选配置
notification_email_from Alexandre.Cassen@firewall.loc
# 指定发送邮件的smtp服务器
smtp_server 192.168.200.1
# 连接smtp的超时时间,也是可选配置
smtp_connect_timeout 30
#路由id,全局唯一,表示当前keepalived节点的唯一性
router_id lb01
}
# 定义一个vrrp_instance实例,名字为VI_1
vrrp_instance VI_1 {
#设置当前实例状态为MASTER。MASTER代表是主实例,BACKUP代表是备用实例
state MASTER
#当前实例绑定的网卡
interface eth0
#当前实例的虚拟路由id,一组主备的实例的路由id是相同的
virtual_router_id 51
#当前实例的优先级
priority 150
#主备之间同步检查时间间隔
advert_int 1
#一组主备实例的认证密码,方式非法节点进入路由组
authentication {
auth_type PASS
auth_pass 1111
}
#设置当前实例的虚拟IP
virtual_ipaddress {
10.1.1.50/24
}
}
! Configuration File for keepalived
global_defs {
#由于是全局唯一Id,所有需要与master保持不同
router_id lb02
}
vrrp_instance VI_1 {
#备用实例状态应设置为BACKUP
state BACKUP
interface eth0
virtual_router_id 51
#设置备用实例的优先级低于主实例,这样可保证在主实例故障修复后可以再次将主节点抢占回来
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.1.1.50/24
}
}
systemctl start keepalived
systemctl enable keepalived
ip addr|grep 10.1.1.50
LVS,全称Linux Virtual Server,是国人章文嵩发起的一个开源项目。
在社区具有很大的热度,是一个基于四层、具有强大性能的反向代理服务器。
早期使用lvs需要修改内核才能使用,但是由于性能优异,现在已经被收入内核。
LVS的一些相关术语:
LVS的模型中有两个角色:
调度器: Director,又称为Dispatcher,Balancer
调度器主要用于接受用户请求。
真实主机:Real Server,简称为RS。
用于真正处理用户的请求。
而为了更好地理解,我们将所在角色的IP地址分为以下三种: Director Virtual IP:调度器用于与客户端通信的IP地址,简称为VIP Director IP:调度器用于与RealServer通信的IP地址,简称为DIP。 Real Server : 后端主机的用于与调度器通信的IP地址,简称为RIP。
NAT模式称为全称Virtualserver via Network address translation(VS/NAT)
,是通过网络地址转换的方法来实现调度的。首先调度器(Director)接收到客户的请求数据包时(请求的目的IP为VIP),根据调度算法决定将请求发送给哪个后端的真实服务器(RS)。然后调度就把客户端发送的请求数据包的目标IP地址及端口改成后端真实服务器的IP地址(RIP),这样真实服务器(RS)就能够接收到客户的请求数据包了。真实服务器响应完请求后,查看默认路由(NAT模式下我们需要把RS的默认路由设置为DS服务器。)把响应后的数据包发送给DS,DS再接收到响应包后,把包的源地址改成虚拟地址(VIP)然后发送回给客户端。
具体工作流程:
原理:
基于ip伪装MASQUERADES
,原理是多目标DNAT。
所以请求和响应都经由Director调度器。
LVS-NAT的优点与缺点
优点:
RIP和DIP都应该使用同一网段私有地址,而且RS的网关要指向DIP。
使用nat另外一个好处就是后端的主机相对比较安全。
缺点:
就是效率低的意思。
在LVS(NAT)模式的集群环境中,由于所有的数据请求及响应的数据包都需要经过LVS调度器转发,如果后端服务器的数量大于10台,则调度器就会成为整个集群环境的瓶颈。我们知道,数据请求包往往远小于响应数据包的大小。因为响应数据包中包含有客户需要的具体数据,所以LVS(TUN)的思路就是将请求与响应数据分离,让调度器仅处理数据请求,而让真实服务器响应数据包直接返回给客户端。LVS/TUN
工作模式拓扑结构如图所示。其中,IP隧道(IP tunning)是一种数据包封装技术,它可以将原始数据包封装并添加新的包头(内容包括新的源地址及端口、目标地址及端口),从而实现将一个目标为调度器的VIP地址的数据包封装,通过隧道转发给后端的真实服务器(Real Server),通过将客户端发往调度器的原始数据包封装,并在其基础上添加新的数据包头(修改目标地址为调度器选择出来的真实服务器的IP地址及对应端口),LVS(TUN)模式要求真实服务器可以直接与外部网络连接,真实服务器在收到请求数据包后直接给客户端主机响应数据。
基于隧道封装技术。在IP报文的外面再包一层IP报文。 当Director接收到请求的时候,选举出调度的RealServer 当接受到从Director而来的请求时,RealServer则会使用lo接口上的VIP直接响应CIP。 这样CIP请求VIP的资源,收到的也是VIP响应。
只接受进站请求,解决了LVS-NAT时的问题,减少负载。
请求报文经由Director调度,但是响应报文不需经由Director。
全称:Virtual Server via Direct Routing(VS-DR),也叫直接路由模式,用直接路由技术实现虚拟服务器。当参与集群的计算机和作为控制管理的计算机在同一个网段时可以用此方法,控制管理的计算机接收到请求包时直接送到参与集群的节点。直接路由模式比较特别,很难说和什么方面相似,前种模式基本上都是工作在网络层上(三层),而直接路由模式则应该是工作在数据链路层上(二层)。
当Director接收到请求之后,通过调度方法选举出RealServer。
讲目标地址的MAC地址改为RealServer的MAC地址。
RealServer接受到转发而来的请求,发现目标地址是VIP。RealServer配置在lo接口上。
处理请求之后则使用lo接口上的VIP响应CIP。
只要求DIP和RIP的地址在同一个网段内。
三种模型虽然各有利弊,但是由于追求性能和便捷,DR是目前用得最多的LVS模型。
一个接一个,自上而下
加权,手动让能者多劳。
来自同一个IP地址的请求都将调度到同一个RealServer
不管IP,请求特定的东西,都定义到同一个RS上。
链接最少,也就是Overhead最小就调度给谁。
假如都一样,就根据配置的RS自上而下调度。
各个服务器相应的权值表示其处理性能。服务器的缺省权值为1,系统管理员可以动态地设置服务器的权值
WLC算法的改进。
SED算法的改进,无需队列。如果有realserver的连接数等于0就直接分配过去
主机名 | 主机地址 | 角色 |
---|---|---|
lb01 | 10.1.1.11 ,VIP:10.1.1.50 | LVS+keepalived主(Director) |
lb02 | 10.1.1.12 ,VIP:10.1.1.50 | LVS+keepalived备(Director) |
node1 | 10.1.1.15 | Nginx(RealServer) |
node2 | 10.1.1.16 | Nginx(RealServer) |
由于LVS服务器和后端服务器的网卡上都配置了VIP,那么当客户端联系VIP的时候肯定是和LVS服务器的VIP进行通信,然后由LVS服务器基于规则进行调度,我们知道2层通信是基于MAC地址的,那么首次通信时客户端可能并不知道LVS服务器的MAC地址,那么就需要进行ARP广播来解析出VIP所在的服务器的MAC地址,那么显然对客户端进行ARP应答的只能是LVS服务器不能是后端服务器,所以我们就要在后端上修改内核参数来禁止ARP应答和宣告。那么有2个内核参数表示这两个设置:
arp_ignore:表示接收到ARP广播时的响应级别,默认值为0
arp_announce:定义将自己的地址向外通告的级别,默认是0
为什么会有这些级别呢?因为主机可以有多个网卡,每个网卡都对应一个网段,默认情况下这个多网卡主机只要接入网络它就会把自己所在的所有网络地址都向外进行通告。
所以对于后端服务器,也就是本例子中的Nginx,我们应该在lo上配置子接口,且设置arp_ignore为1,arp_announce为2。
echo "1" > /proc/sys/net/ipv4/ip_forward
echo "2" > /proc/sys/net/ipv4/conf/all/arp_announce
echo "1" > /proc/sys/net/ipv4/conf/all/arp_ignore
echo "1" > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2" > /proc/sys/net/ipv4/conf/lo/arp_announce