Keepalived 是一个基于VRRP协议针对LVS负载均衡软件设计的,通过监控集群中各节点的状态以实现LVS服务高可用的软件,可以解决静态路由出现的单点故障问题。
Keepalived除了能够管理LVS软件,还可以对NGINX haproxy MySQL等软件提供高可用解决方案。
VRRP协议:组播地址224.0.0.18 协议号112 主服务器承载VRRP地址接收用户请求并发送VRRP报文(VRRP地址作为所有客户机默认网关),备监听主服务器 若超时未收到VRRP报文,随时顶替成为主服务器,并生成并承载预先定义的主服务器的VRRP地址
在一个LVS服务集群中通常有主服务器(MASTER)和备份服务器(BACKUP)两种角色的服务器,但是对外表现为一个虚拟IP(VIP),主服务器会发送VRRP通告信息给备份服务器,当备份服务器收不到VRRP消息的时候,即主服务器异常的时候,备份服务器就会接管虚拟IP,继续提供服务,从而保证了高可用性。
Keepalived体系主要模块及其作用
keepalived体系架构中主要有三个模块,分别是core、check和vrrp。
●core模块:为keepalived的核心,负责主进程的启动、维护及全局配置文件的加载和解析。
●vrrp模块:是来实现VRRP协议的。(调度器之间的健康检查和主备切换)
●check模块:负责健康检查,常见的方式有端口检查及URL检查。(节点服务器的健康检查)健康检测方法(探针)
1.发送心跳消息(ping、pong)
2.TCP端口检测 向主机IP:PORT发起三次握手连接
3.HTTP URL检测 向主机 http://IP:PORT/... URL路径发送http GET方法,主机返回2XX 3XX为正常,4XX 5XX为异常
主DR 服务器:192.168.80.101
备DR 服务器:192.168.80.102
Web 服务器1:192.168.80.103
Web 服务器2:192.168.80.104
vip:192.168.80.66
客户端:192.168.80.200
1.配置负载调度器(主、备相同)
关闭防火墙
systemctl stop firewalld.service setenforce 0
安装ipvsadm,keepalived
yum -y install ipvsadm keepalived modprobe ip_vs cat /proc/net/ip_vs
(1)配置keeplived(主、备DR 服务器上都要设置)
备份配置
cd /etc/keepalived/ cp keepalived.conf keepalived.conf.bak
更改keepalive配置文件
此处设置的为抢占式,主服务器从故障恢复后会重新抢占回master位置。
若要设置非抢占式,两服务器需要均设为BACKUP并且nopreempt。此时谁先启动谁当master,若master故障后成为backup,即使故障恢复也仍然为backup,不抢占master。
vim keepalived.conf ...... global_defs { #定义全局参数 --10行--修改,邮件服务指向本地 smtp_server 127.0.0.1 --12行--修改,指定服务器(路由器)的名称,主备服务器名称须不同,主为✨LVS_01,备为✨LVS_02 router_id LVS_01 --14行--✨注释掉,取消严格遵守VRRP协议功能,否则VIP无法被连接 #vrrp_strict } vrrp_instance VI_1 { #定义VRRP热备实例参数 --20行--修改,指定热备状态,主为✨MASTER,备为✨BACKUP state MASTER --21行--修改,指定承载vip地址的物理接口 interface ens33 --22行--修改,指定虚拟路由器的✨ID号,每个热备组保持一致 virtual_router_id 10 #nopreempt #如果设置非抢占模式,两个节点state必须为BACKUP,并加上配置 nopreempt --23行--修改,指定优先级,数值越大优先级越高,这里设置✨主为100,✨备为90 priority 100 advert_int 1 #通告间隔秒数(心跳频率) authentication { #定义认证信息,每个热备组保持一致 auth_type PASS #认证类型 --27行--修改,指定验证密码,✨主备服务器保持一致 auth_pass abc123 } virtual_ipaddress { #指定群集vip地址 192.168.80.66 } } --36行--修改,指定虚拟服务器地址(VIP)、端口,定义虚拟服务器和Web服务器池参数 virtual_server 192.168.80.66 80 { delay_loop 6 #健康检查的间隔时间(秒) lb_algo rr #指定调度算法,轮询(rr) --39行--修改,指定群集工作模式,直接路由(DR) lb_kind DR persistence_timeout 0 #连接保持时间(秒) 这里需要显示效果所以0,生产环境需要开启 protocol TCP #应用服务采用的是 TCP协议 --43行--修改,指定第一个Web节点的地址、端口 real_server 192.168.80.103 80 { weight 1 #节点的权重 --45行--删除,添加以下健康检查方式 TCP_CHECK #这里使用TCP CHECK(ping tcp端口 url 验证方式三选一) connect_port 80 #添加检查的目标端口 connect_timeout 3 #添加连接超时(秒) nb_get_retry 3 #添加重试次数 delay_before_retry 3 #添加重试间隔 } } real_server 192.168.80.104 80 { #添加第二个 Web节点的地址、端口 weight 1 TCP_CHECK { connect_port 80 connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } ##删除后面多余的配置## }
开启服务
systemctl start keepalived systemctl enable keepalived ip addr #查看虚拟网卡vip
(2)启动 ipvsadm 服务
--192.168.80.101---
ipvsadm-save > /etc/sysconfig/ipvsadm systemctl start ipvsadm
ipvsadm -ln #如没有VIP 的分发策略,则重启 keepalived 服务,systemctl restart keepalived
--192.168.80.102---
ipvsadm-save > /etc/sysconfig/ipvsadm systemctl start ipvsadm
ipvsadm -ln
(3)调整 proc 响应参数,关闭Linux 内核的重定向参数响应,避免后续数据包不经过负载均衡器直接发往节点服务器
vim /etc/sysctl.conf net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 net.ipv4.conf.ens33.send_redirects = 0
sysctl -p
2.配置节点服务器
关闭防火墙
systemctl stop firewalld setenforce 0
安装httpd服务
yum -y install httpd systemctl start httpd systemctl enable httpd
配置回环地址承载VIP
vim /etc/sysconfig/network-scripts/ifcfg-lo:0 DEVICE=lo:0 ONBOOT=yes IPADDR=192.168.80.66 NETMASK=255.255.255.255
service network restart 或 systemctl restart network
ifup lo:0 ifconfig lo:0 route add -host 192.168.80.66 dev lo:0
调整Linux内核ARP参数,阻止更新 VIP 的 MAC 地址,避免ARP缓存表混淆,产生冲突
vim /etc/sysctl.conf net.ipv4.conf.lo.arp_ignore = 1 net.ipv4.conf.lo.arp_announce = 2 net.ipv4.conf.all.arp_ignore = 1 net.ipv4.conf.all.arp_announce = 2 IGNORE=1 只响应目的地址为物理网卡地址的ARP请求,不响应回环地址 ANNOUNCE=2 使用发送报文的网卡的IP地址做ARP请求源地址,而不是使用虚拟集群IP 这两条对ARP一进一出做了限制,让VIP虚拟地址无法接受和响应ARP请求以避免arp混乱
sysctl -p
--192.168.80.103---
echo 'this is xue web!' > /var/www/html/index.html
--192.168.80.104---
echo 'this is benet web!' > /var/www/html/index.html
在客户端访问 http://192.168.80.66/
ip addr 查看IP #ipvsadm是根据ip生成的 ifconfig查看不了 ipvsadm -ln 查看自动生成的规则 #keepalive是为ipvsadm设计的程序 只要设置keepalive自动配置ipvsadm
curl 192.168.80.66
再在主服务器关闭 keepalived 服务后再测试systemctl stop keepalived
Keepalived通过什么判断哪台主机为主服务器,通过什么方式配置浮动IP?(面试题)
Keepalived首先做初始化先检查state状态,master为主服务器,backup为备服务器。
然后再对比所有服务器的priority,谁的优先级高谁是最终的主服务器。
优先级高的服务器会通过ip命令为自己的电脑配置一个提前定义好的浮动IP地址。
keepalived的抢占与非抢占模式(面试题)抢占模式即MASTER从故障中恢复后,会将VIP从BACKUP节点中抢占过来。
非抢占模式即MASTER恢复后不抢占BACKUP升级为MASTER后的VIP
非抢占式两节点state必须都设置为bakcup,且必须配置nopreempt。
注意:这样配置后,我们要注意启动服务的顺序,优先启动的获取master权限,与优先级没有关系了。
故障原因^现象
当主从服务器间的通信链路产生故障,从服务器收不到主服务器的VRRP报文,则认为主服务器已经宕机,自己也成为主服务器。但此时主服务器并未宕机(只是通信链路终端让从服务器觉得主服务器宕机),于是网络中就产生了两个master服务器,都带有VIP地址,造成服务混乱,这就是VRRP的脑裂现象。
解决方法
既然从服务器觉得主服务器宕机,那就索性关闭主服务器keepalive服务 让主服务器变为备服务器,变为既成事实,这样也就解决了脑裂。
预防策略
方法1
主从服务器间增加一条通信链路,除非两条链路都断了,不然不会产生脑裂
方法2
编写脚本让主服务器监听与从服务器的链接是否保持,若连接断开,主服务器自己关闭keepalive服务 成为从服务器。
但这又带来一个问题,如何判断是链路断了还是主机宕机了?由于主从负载均衡服务器与节点服务器在同一个局域网,所以可以让第三方主机(节点服务器)代理检测。
ssh 【节点服务器IP】 ping -c 3 【从服务器IP】
编写脚本,主服务器ping另一台负载均衡服务器,若ping不通再使用ssh命令让节点服务器代替自己ping备服务器
- 主服务器ping不通,节点ping不通,副服务器宕机。主服务器无需关闭自己keepalive只需要发出副服务器宕机的警告。
- 主服务器ping不通,节点能ping,主从间链路故障,主服务器需要自行关闭自己的keepalived服务,并发出警告主从服务器链路故障。
这种紫砂脚本在主从服务器上任意一端部署一个即可,不要两个都部署,不然两边就都杀光了。
不分主从不分抢占非抢占,重点是一方ping另外一方,再让节点服务器也ping另外一方。
方法3
使用zabbix等监控软件,创建监控项,创建触发项测试关闭keepalive服务。
Keepalived除了能够管理LVS软件,还可以对NGINX haproxy MySQL等软件提供高可用解决方案。
NGINX不像LVS一样是基于内核的,NGINX是应用软件。对于LVS来说判断方法很简单,内核没崩LVS就在,ping不通了,自然也就可以判断系统崩了
但是NGINX作为应用软件,有可能系统好好的,只是NGINX崩了,此时就不能通过ping这种方法判断调度器的存活状态。NGINX只能通过编写脚本实现检测NGINX进程是否正常。
对于NGINX,Keepalived只能使用其故障切换功能【图1】,至于调度器的健康检查则需要编写脚本路径写入vrrp—script 并在track—script中引用【图2】
大概原理为,在脚本中检测NGINX运行情况,若异常,则杀死keepalive服务。此后的流程就与LVS的处理一致了,当keepalive服务消失后,从服务器接收不到VRRP报文,进行主从切换。
由于只是调度器的健康检测方式略有不同,最后还是落实到keepalive停止发送vrrp报文导致主从切换,所以NGINX的Keepalived与LVS的Keepalived一样,也需要预防线路中断造成脑裂。
清除刚刚所做的操作(主从服务器都要)
恢复配置文件
mv keepalived.conf.bak keepalived.conf
查看LVS负载均衡配置,清空
ipvsadm -ln ipvsadm -C
主服务器配置
由于主从服务器均使用NGINX服务,NGINX服务自带轮询,所以这里就不使用keepalive配置文件中的real—server选项进行服务器节点轮询设置,将其注释或删除。
本示例将使用NGINX服务的轮询。设置nginx.conf文件,在http块上方添加一个stream块进行NGINX四层负载均衡反向代理,指向主从负载均衡服务器后的两个WEB服务器。
vim /etc/keepalived/keepalived.conf global_defs { #定义全局参数 smtp_server 127.0.0.1 #邮件服务指向本地 router_id NGINX01 #指定服务器(路由器)的名称,主备服务器名称须不同,主为✨NGINX01,备为✨NGINX02 #vrrp_strict #✨注释掉,取消严格遵守VRRP协议功能,否则VIP无法被连接 } #检测脚本 vrrp_script chk_http_port { script "/usr/local/src/check_nginx_pid.sh" #心跳执行的脚本,检测nginx是否启动 interval 2 #(检测脚本执行的间隔,单位是秒) weight 2 #权重 } #vrrp 实例定义部分 vrrp_instance VI_1 { state MASTER # 指定keepalived的角色,MASTER为主,BACKUP为备 interface ens33 # 当前进行vrrp通讯的网络接口卡(当前centos的网卡) 用ifconfig查看你具体的网卡 virtual_router_id 66 # 虚拟路由编号,主从要一直 priority 100 # 优先级,数值越大,获取处理请求的优先级越高 advert_int 1 # 检查间隔,默认为1s(vrrp组播周期秒数) #授权访问 authentication { auth_type PASS #设置验证类型和密码,MASTER和BACKUP必须使用相同的密码才能正常通信 auth_pass 1111 } track_script { chk_http_port #(调用检测脚本) } virtual_ipaddress { 192.168.80.66 # 定义虚拟ip(VIP),可多设,每行一个 } }
从服务器配置
由于主从服务器均使用NGINX服务,NGINX服务自带轮询,所以这里就不使用keepalive配置文件中的real—server选项进行服务器节点轮询设置,将其注释或删除。
本示例将使用NGINX服务的轮询。设置nginx.conf文件,在http块上方添加一个stream块进行NGINX四层负载均衡反向代理,指向主从负载均衡服务器后的两个WEB服务器。
vim /etc/keepalived/keepalived.conf global_defs { #定义全局参数 smtp_server 127.0.0.1 #邮件服务指向本地 router_id NGINX02 #指定服务器(路由器)的名称,主备服务器名称须不同,主为✨NGINX01,备为✨NGINX02 #vrrp_strict #✨注释掉,取消严格遵守VRRP协议功能,否则VIP无法被连接 } #检测脚本 vrrp_script chk_http_port { script "/usr/local/src/check_nginx_pid.sh" #心跳执行的脚本,检测nginx是否启动 interval 2 #(检测脚本执行的间隔) weight 2 #权重 } #vrrp 实例定义部分 vrrp_instance VI_1 { state BACKUP # 指定keepalived的角色,MASTER为主,BACKUP为备 interface ens33 # 当前进行vrrp通讯的网络接口卡(当前centos的网卡) 用ifconfig查看你具体的网卡 virtual_router_id 66 # 虚拟路由编号,主从要一直 priority 99 # 优先级,数值越大,获取处理请求的优先级越高 advert_int 1 # 检查间隔,默认为1s(vrrp组播周期秒数) #授权访问 authentication { auth_type PASS #设置验证类型和密码,MASTER和BACKUP必须使用相同的密码才能正常通信 auth_pass 1111 } track_script { chk_http_port #(调用检测脚本) } virtual_ipaddress { 192.168.80.66 # 定义虚拟ip(VIP),可多设,每行一个 } }
检测脚本 主从都要设置
要检测NGINX进程的存在,可以使用killall -0查看返回值,或是netstat/ss筛选80端口,或是ps aux查看是否有NGINX进程
vim /usr/local/src/check_nginx_pid.sh #!/bin/bash #检测nginx是否启动了 A=`ps -C nginx --no-header | wc -l` if [ $A -eq 0 ];then #如果nginx没有启动就启动nginx systemctl start nginx #重启nginx if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then #nginx重启失败,则停掉keepalived服务,进行VIP转移 killall keepalived fi fi
chmod 775 check_nginx_pid.sh 或者 chmod +x check_nginx_pid.sh
测试
访问vip,主负载均衡服务器响应,主服务器中NGINX通过轮询发送给后端的两个WEB服务器
curl http://192.168.80.66:8080
查看两机IP,发现主服务器拥有vip,备服务器没有
ip addr
关闭nginx,keepalive中设置的脚本发现nginx进程消失,杀死主机的keepalive进程。从服务器超时未收到vrrp报文,变为主服务器
systemctl stop nginx
查看两机IP,发现vip已经转移到备服务器,备服务器成为主服务器
ip addr
若想还原故障的主服务器,需要先打开nginx,再打开keepalive。由于脚本中设置没有nginx就会杀死keepalive、
systemctl start nginx systemctl start keepalived
查看两机IP,主服务器回复后vip恢复,备服务器vip消失
ip addr
keepalive基于什么协议?
VRRP协议:组播地址224.0.0.18 协议号112
keepalive怎么选举master?
Keepalived首先做初始化先检查state状态,master为主服务器,backup为备服务器。
然后再对比所有服务器的priority,谁的优先级高谁是最终的主服务器。
优先级高的服务器会通过ip命令为自己的电脑配置一个提前定义好的浮动IP地址。
keepalive怎么生成VIP?
主服务器通过IP命令生成预先设置的VIP
keepalive怎么故障切换?
主服务器承载VRRP地址接收用户请求并发送VRRP报文(VRRP地址作为所有客户机默认网关)
备监听主服务器 若超时未收到VRRP报文,顶替成为主服务器,并生成并承载预先定义的主服务器的VRRP地址
keepalive抢占模式和非抢占模式如何工作?
抢占模式即MASTER从故障中恢复后,会将VIP从BACKUP节点中抢占过来。
非抢占模式即MASTER恢复后不抢占BACKUP升级为MASTER后的VIP。
怎么设置非抢占模式?
非抢占式两节点state必须都设置为bakcup,且必须配置nopreempt。
注意:这样配置后,我们要注意启动服务的顺序,优先启动的获取master权限,与优先级没有关系了。
脑裂现象如何?
主备服务器都有VIP地址
产生脑裂原因?
主备服务器间通信链路断开,主服务器仍在运行,但备服务器由于通信链路原因误认为主服务器宕机
脑裂解决方法?
主备服务器任选一台,关闭keepalived服务
脑裂预防方案?
1 增加一条通信线路
2 编写脚本,主服务器ping另一台负载均衡服务器,若ping不通再使用ssh命令让节点服务器代替自己ping备服务器
- 都无法ping通则为副服务器宕机,主服务器无需关闭自己keepalive只需要发出副服务器宕机的警告。
- 若主负载均衡服务器不能ping通副负载均衡服务器,但是节点服务器可以ping通副服务器,则为链路故障,此时脑裂产生,主服务器需要自行关闭自己的keepalived服务,并发出警告主从服务器链路故障
这种紫砂脚本在主从服务器上任意一端部署一个即可,不要两个都部署,不然两边就都杀光了。
不分主从不分抢占非抢占,重点是一方ping另外一方,再让节点服务器也ping另外一方。
3 使用zabbix等监控软件,创建监控项,创建触发项测试关闭keepalive服务。
如何健康检查 调度器和节点服务器?
如果是LVS这种内核级别的做健康检测
调度器无需特别管理,keepalive会自动切换,因为LVS是基于内核,系统崩了LVS也就自己掉了
节点服务器则通过检查tcp端口,或http请求查看返回状态码(也是在keepalive配置文件中修改,设置轮询后还要设置健康检测方式)
如果是NGINX这种应用程序做健康检查
调度器需要编写脚本检查应用程序进程是否存在,不存在就把自己的keepalive进程结束
节点服务器无需特别管理,因为NGINX自带节点的健康检查方式(只需要设置轮询,失败次数,超时时间。用不着指定通过啥方式健康检查)