终于到了这一节,主要是面试最近被问到了关于高可用负载器,对客户而言,如何单一ip的实现。
问题
根据之前所学,我们已经知道,中间的负载均衡器如果是基于4层的,实际可以是LVS,如果是基于7层的,也可以是NGINX,但无论是啥,基于这种在客户端->服务端之间放了一层代理服务器的结构,都会存在一些隐患:
1、负载均衡器挂掉了怎么办? 它是单点的,它挂了,业务下线,意味着一切都结束了,即使你后方的real server还在健康工作也无济于事。
2、负载均衡器没挂,但是后方的某台real server发生了故障,但此时负载均衡器中还记载着后方服务器的负载映射记录,并未将其消除掉,此时将会导致通过负载均衡器转发过来的请求,有可能有的可以成功请求,有的落在故障机器上,导致请求失败。
解决思路
问题1:
针对问题1,属于典型的单点故障问题,解决方案也比较直接,一台不行,就上多台!
但这里多台的语义,可以有多个,分为 主备和主主。
主主
首先主主的话,也就是同时有多个负载服务器在工作,但此时要想到,对客户端而言,VIP只有1个,而如果主主就会出现多个IP,对于这种情况,可以通过前端引入其他技术,例如DNS动态解析来解决,但复杂度比较高,不太常用。
主备
其次就是主备了,意思就是说同一时刻,只有一台主机器在工作,另外的备机只有当主挂了的时候才会迅速接替主机进行工作,其他时间都是不工作的。
主备模型比较常用,因此这里主要探讨主备。
要从两点进行讨论:
1、方向性
备机如何检测到主挂了呢?
一种方式是每个备机每隔一个周期进行主动询问一次主机的情况,但这种显然会对主机造成一定的压力。
另外一种,则是被动监听的方式,由主机周期性向它的备机们发送请求,如果在若干周期(为什么是若干周期,因为网络存在波动,不能因为在第一时间没有接受到,就执行什么操作,需要有个重试的机制)没有收到主机的来信,则认为主机确实是挂了的。
2、效率性
当确认主机挂掉后,各个备机中,最终会选出唯一一个能当上主机的机器,那是谁呢? 如果不做处理,每个机器都进行争抢,可能多个回合都无法选出一个主机来。
如果你学过zookeeper,那么一定知道zookeeper中的选举机制是让贤制的,也就是说,如果每个机器如果都有一个权重,那么当选主的时候,大家争先去选那个权重最大的作为主机,这样的话,可以在很短的时间内很快选出主机。
问题2:
针对问题2,在想解决之前,首先要先确定,如何确定一个real server挂了?
1、ping ip? 不对,ip是基于4层的,能ping通,却不一定代表对方服务就是可以用的。
2、访问一下,换言之,就是使用应用层的http协议,发送一个请求,返回200,就代表服务是OK的。
解决方式
1、LVS在LINUX内核中有对应的模块ipvs,如果要实现上述的功能,解决单点故障,实现HA,可以在里边增加新的逻辑代码? 不太好。
2、引入第三方,这个第三方可以是人,也可以是自动化程序,而人是不可靠的,必然需要程序来实现这一套流程的自动化。
因此,KeepAlived横空出世!
KeepAlived
可以做的事情
1、监控自身的LVS服务
2、Master通告自身还活着,Backup监听Master状态,Master挂了,一堆Backup选出一个新的Master
3、故障转移,配置转移,配置vip,添加ipvs,keepalived有配置文件来配置这些行为
4、对后端的real server做健康检查,当后方服务不可用时,从LVS负载条目中进行剔除。
基于1,2两点,keepalived需要在主机和每个从机上都进行配置。
且keepalived是一个通用的HA实现解决的工具,不仅可以保证LVS的高可用,还可以保证NGINX的高可用,甚至如果你想,tomcat的高可用都可以。
实验结构图
基于上次LVS的实验,没有用到的node04,作为LVS的备机使用。
LVS主机(node01)和LVS备机(node04)机器上在同一时间只能有1台机器可以有VIP。
它们的机器上需要安装keepalived,通过keepalived来完成通信和故障转移。
实操
环境预处理
实操之前,需要确保环境是干净的。
1、清除LVS配置
基于上次搭建,node01上面如果你没有重启过电脑,那么上次手动进行的LVS配置应该还是存在的:
清除配置:
ipvsadm -C
再次查看,发现已经没有相关映射了:
2、移除VIP网卡
eth0:8是我们上次配置的VIP,进行移除:
ifconfig eth0:8 down
实操开始
node01,node04:
安装
yum install keepalived ipvsadm -y
cd /etc/keepalived/
万事操作前先备份:
cp keepalived.conf keepalived.conf.bak
vi keepalived.conf
全局配置:
可以在发生故障时,给你发送邮件。
接着向下看:
#vrrp:虚拟路由冗余协议
vrrp_instance VI_1 {
state MASTER # 谁是主机谁这里配MASTER,其他的配BACKUP,这里把node01作为主机,是MASTER,如果是node04作为备机,就是BACKUP
interface eth0 #一个公司基本会有多个网卡进行不同类型的通信,这里指定一个网卡来进行KEEPALIVED的通信
virtual_router_id 51 #集群id标识,为了标识处于同一集群
priority 100 #权重值,Master需要比Backup高 #node01 100 node04 50
advert_int 1
#安全配置
authentication {
auth_type PASS
auth_pass 1111
}
#虚拟vip配置
virtual_ipaddress {
#等同于:ifconfig eth0:3 192.168.150.100/24
192.168.150.100/24 dev eth0 label eth0:3 # ip地址/mask掩码 dev 物理网卡名 label 子网卡
}
}
virtual_ipaddress不知道怎么配?
man 5 keepalived.conf
vi搜索:
/virtual_ipaddress
#这里相当于之前的LVS的ipvsadm的配置
#配置入站的ip和端口
virtual_server 192.168.150.100 80 {
delay_loop 6
lb_algo rr #负载算法
lb_kind DR #负载种类,NAT/DR
nat_mask 255.255.255.0
#持久化时间,例如一个客户端负载到后方某个服务器,LVS会记住这个客户端,当这个客户端下次再来时,保证还到此服务器,利用先前分配的资源
persistence_timeout 0
protocol TCP #通信协议
real_server 192.168.150.12 80 { #真实服务器配置
weight 1
HTTP_GET { #后方服务器健康检查
url {
path / #请求url
status_code 200 #期望返回码
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
real_server 192.168.150.13 80 { #真实服务器配置
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
HTTP_GET 是啥? 代表http get请求, SSL_GET代表https get请求
好的,至此,keepalived配置完成。
查看效果
在node01启动:
service keepalived start
node01查看:
发现自动已经多了子网卡 eth0:3的vip了。。
发现LVS的负载也自动配置好了。。
在node04启动:
service keepalived start
发现VIP没有被配置(证明了,同一时刻,只有主机会有VIP)
再查看LVS的配置:
发现自动被配置好了。(为什么预先被配置好? 为了保证某一时刻,变成主机,无需再去进行配置,速度快!)
故障转移效果
我们手动制造node01故障,来查看keepalived故障转移的效果:
ifconfig eht0 down #物理网卡down掉,其下的所有子ip都会被down掉
此时去查看node04:
发现node04的vip已经被自动配置上了。 VIP被漂移过来了!
对于客户端而言,这个过程,是透明的,是没有故障出现的!!!
那如果再把node01的网卡up起来呢?(人为的修复好了)
ifconfig eht0 up
会发现,node01的vip重新被挂载了,而node04的vip又被卸掉了。
可见,LVS的故障切换,当主机重新好了的时候,会重新成为主机。
但这并非所有框架的通用做法,要考虑这样做的成本(如果需要数据一致性的应用,切换回来,主机和从机同时阻塞然后需要同步主挂掉这段期间的数据),而LVS只作为通信,并没有太多的数据,所以可以采用这种。
监控后方服务健康
node01查看LVS负载配置:
真实服务器node02(192.168.150.12)进行关闭服务:
service httpd stop
node01查看LVS负载配置:
发现确实对LVS负载的访问不通的服务进行了剔除
当node02重新启动后,会发现LVS负载条目中会被重新加入进来。
keepalived,作为一个程序的潜在问题
只要是程序,就有挂掉的可能性。
查看keepalived的进程:
发现有3个,1个主进程(和别的keepalived通告自身还活着),2个子进程(检测real server健康)
强制杀死keepalived:
kill -9 1526
kill -9 1528
kill -9 1529
这会导致什么问题?
1、node01配置的vip和LVS负载配置没有被回收。
2、node01没有了keepalived,也就不能通告node04,因此,node04认为node01挂掉了,而也会出现vip配置和LVS负载配置
这导致,两台机器都出现VIP,在同一局域网内,这个问题暴露的很明显,一个客户端的每次请求说不准是不是请求的一个LVS。