Keepalived实现Nginx高可用
本文最近更新于2021.11.25
(一)Keepalived简介
Keepalived是集群中常见的高可用组件,其通过VRRP(Virtual Router Redundancy Protocol)虚拟路由冗余协议保证服务的高可用。
Keepalived的主要目的就是它自身启动为一个服务,它工作在多个LVS主机节点上,当前活动的节点叫做Master备用节点叫做Backup,Master会不停的向Backup节点通告自己的心跳,这种通告是基于VRRP协议的。Backup节点一旦接收不到Master的通告信息,它就会把LVS的VIP拿过来,并且把ipvs的规则也拿过来,在自己身上生效,从而替代Master节点。
Keepalived除了可以监控和转移LVS资源之外,它还可以直接配置LVS而不需要直接使用ipvsadm命令,因为它可以调用,也就是说在LVS+KEEPALIVED模型中,你所有的工作在Keepalived中配置就可以了,而且它还有对后端应用服务器健康检查的功能。
两台虚拟机
centos7.3虚拟机A 10.0.3.46
centos7.3虚拟机B 10.0.3.110
对外开放的虚拟ip 10.0.3.96(这个ip只需要在keepalived里面配置就可以了)
简述实验原理:
虚拟机A和B都需要安装nginx和keepalived(过程省略,其中keepalived为yum安装模式yum install keepalived -y,编译安装的貌似不能正常运行,暂时不清楚什么原因)我简单将keepalived理解为检测i服务器是否可用,如果某台服务器宕机,则将虚拟ip转移到另一台服务器
实验步骤:
为了区别虚拟机AB,修改nginx的默认页面
分别开启nginx
分别修改keepalived的配置文件keepalived.conf,yum安装默认放在/etc/keepalived/keepalived.conf,或者也可以自行find / -name keepalived.conf。注意需要把原文件内容全部删除(或者把原文件重命名做备份),否则会出错
在两台keepalived上都需要在/etc/sysctl.conf中添加以下参数,否则无法正常绑定虚拟ip
net.ipv4.ip_nonlocal_bind = 1
虚拟机A的keepalived配置文件全部内容为:(正常来说还应该配套一个检测Nginx存活状态的脚本,后续我实践了再加进来)
vrrp_instance VI_1 { state MASTER interface ens33 #这里需要根据自己的网卡接口修改 virtual_router_id 66 #该值保持一致,默认为51,但是建议修改为其他值,我的就是因为局域网内已经部署有一个keepalived占用了51这个id,导致keepalived无法正常启动 priority 101 #具有更高的优先级,比如说当这台虚拟机A宕机恢复后,keepalived根据这个优先级决定是否优先使用虚拟机A advert_int 1 authentication { #类型和密码必须与另一台虚拟机保持一致 auth_type PASS auth_pass 123456 } virtual_ipaddress { 10.0.3.96 #这个是我随便取的,只要局域网内该ip没有被占用就可以了 } }
虚拟机B的keepalived配置文件为
vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 66 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 123456 } virtual_ipaddress { 10.0.3.96 } }
我们可以看下原始的keepalived配置文件的注释。
! Configuration File for keepalived global_defs { #全局定义部分 notification_email { #设置报警邮件地址,可设置多个 acassen@firewall.loc #接收通知的邮件地址 } notification_email_from test0@163.com #设置 发送邮件通知的地址 smtp_server smtp.163.com #设置 smtp server 地址,可是ip或域名.可选端口号 (默认25) smtp_connect_timeout 30 #设置 连接 smtp server的超时时间 router_id LVS_DEVEL #主机标识,用于邮件通知 vrrp_skip_check_adv_addr vrrp_strict #严格执行VRRP协议规范,此模式不支持节点单播 vrrp_garp_interval 0 vrrp_gna_interval 0 script_user keepalived_script #指定运行脚本的用户名和组。默认使用用户的默认组。如未指定,默认为keepalived_script 用户,如无此用户,则使用root enable_script_security #如过路径为非root可写,不要配置脚本为root用户执行。 } vrrp_script chk_nginx_service { #VRRP 脚本声明 script "/etc/keepalived/chk_nginx.sh" #周期性执行的脚本 interval 3 #运行脚本的间隔时间,秒 weight -20 #权重,priority值减去此值要小于备服务的priority值 fall 3 #检测几次失败才为失败,整数 rise 2 #检测几次状态为正常的,才确认正常,整数 user keepalived_script #执行脚本的用户或组 } vrrp_instance VI_1 { #vrrp 实例部分定义,VI_1自定义名称 state MASTER #指定 keepalived 的角色,必须大写 可选值:MASTER|BACKUP interface ens33 #网卡设置,lvs需要绑定在网卡上,realserver绑定在回环口。区别:lvs对访问为外,realserver为内不易暴露本机信息 virtual_router_id 51 #虚拟路由标识,是一个数字,同一个vrrp 实例使用唯一的标识,MASTER和BACKUP 的 同一个 vrrp_instance 下 这个标识必须保持一致 priority 100 #定义优先级,数字越大,优先级越高。 advert_int 1 #设定 MASTER 与 BACKUP 负载均衡之间同步检查的时间间隔,单位为秒,两个节点设置必须一样 authentication { #设置验证类型和密码,两个节点必须一致 auth_type PASS auth_pass 1111 } virtual_ipaddress { #设置虚拟IP地址,可以设置多个虚拟IP地址,每行一个 192.168.119.130 } track_script { #脚本监控状态 chk_nginx_service #可加权重,但会覆盖声明的脚本权重值。chk_nginx_service weight -20 } notify_master "/etc/keepalived/start_haproxy.sh start" #当前节点成为master时,通知脚本执行任务 notify_backup "/etc/keepalived/start_haproxy.sh stop" #当前节点成为backup时,通知脚本执行任务 notify_fault "/etc/keepalived/start_haproxy.sh stop" #当当前节点出现故障,执行的任务; } virtual_server 192.168.119.130 80 { #定义RealServer对应的VIP及服务端口,IP和端口之间用空格隔开 delay_loop 6 #每隔6秒查询realserver状态 lb_algo rr #后端调试算法(load balancing algorithm) lb_kind DR #LVS调度类型NAT/DR/TUN #persistence_timeout 60 同一IP的连接60秒内被分配到同一台realserver protocol TCP #用TCP协议检查realserver状态 real_server 192.168.119.120 80 { weight 1 #权重,最大越高,lvs就越优先访问 TCP_CHECK { #keepalived的健康检查方式HTTP_GET | SSL_GET | TCP_CHECK | SMTP_CHECK | MISC connect_timeout 10 #10秒无响应超时 retry 3 #重连次数3次 delay_before_retry 3 #重连间隔时间 connect_port 80 #健康检查realserver的端口 } } real_server 192.168.119.121 80 { weight 1 #权重,最大越高,lvs就越优先访问 TCP_CHECK { #keepalived的健康检查方式HTTP_GET | SSL_GET | TCP_CHECK | SMTP_CHECK | MISC connect_timeout 10 #10秒无响应超时 retry 3 #重连次数3次 delay_before_retry 3 #重连间隔时间 connect_port 80 #健康检查realserver的端口 } } } vrrp_instance VI_2 { #vrrp 实例部分定义,VI_1自定义名称 state BACKUP #指定 keepalived 的角色,必须大写 可选值:MASTER|BACKUP 分别表示(主|备) interface ens33 #网卡设置,绑定vip的子接口,lvs需要绑定在网卡上,realserver绑定在回环口。区别:lvs对访问为外,realserver为内不易暴露本机信息 virtual_router_id 52 #虚拟路由标识,是一个数字,同一个vrrp 实例使用唯一的标识,MASTER和BACKUP 的 同一个 vrrp_instance 下 这个标识必须保持一致 priority 90 #定义优先级,数字越大,优先级越高。 advert_int 1 #设定 MASTER 与 BACKUP 负载均衡之间同步检查的时间间隔,单位为秒,两个节点设置必须一样 authentication { #设置验证类型和密码,两个节点必须一致 auth_type PASS auth_pass 1111 } virtual_ipaddress { #设置虚拟IP地址,可以设置多个虚拟IP地址,每行一个 192.168.119.131 } } virtual_server 192.168.119.131 80 { #定义RealServer对应的VIP及服务端口,IP和端口之间用空格隔开 delay_loop 6 #每隔6秒查询realserver状态 lb_algo rr #后端调试算法(load balancing algorithm) lb_kind DR #LVS调度类型NAT/DR/TUN #persistence_timeout 60 #同一IP的连接60秒内被分配到同一台realserver protocol TCP #用TCP协议检查realserver状态 real_server 192.168.119.120 80 { weight 1 #权重,最大越高,lvs就越优先访问 TCP_CHECK { #keepalived的健康检查方式HTTP_GET | SSL_GET | TCP_CHECK | SMTP_CHECK | MISC connect_timeout 10 #10秒无响应超时 retry 3 #重连次数3次 delay_before_retry 3 #重连间隔时间 connect_port 80 #健康检查realserver的端口 } } real_server 192.168.119.121 80 { weight 1 #权重,最大越高,lvs就越优先访问 TCP_CHECK { #keepalived的健康检查方式HTTP_GET | SSL_GET | TCP_CHECK | SMTP_CHECK | MISC connect_timeout 10 #10秒无响应超时 retry 3 #重连次数3次 delay_before_retry 3 #重连间隔时间 connect_port 80 #健康检查realserver的端口 } } }
Nginx存活状态检测脚本:(目前没有添加这个配置,放在这里是让大家知道有这个东西)
#!/bin/bash A=`ps -C nginx–no-header |wc -l` if [ $A -eq 0 ];then /usr/local/nginx/sbin/nginx sleep 2 if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then killallkeepalived fi fi
现在启动两台虚拟机的keepalived
systemctl start keepalived
此时ping 10.0.3.96会有反应,必须能ping通
PS:这种配置方法,会出现在ifconfig无法找到virtual_ipaddress的情况,但是可以正常ping通,整个keepalived也可以正常使用。这个以后熟悉了再回来补充
测试实验效果
尝试从外界访问10.0.3.96,优先访问46,因为46的优先级101比另一台的优先级100大
现在我们把虚拟机B上的keepalived服务停掉,再次访问,发现切换到虚拟机B上了(该nginx默认页面我没有进行修改)
现在把虚拟机A的keepalived重新启动
题外话扩展:
另外,还有一个关于Nginx的session(会话)处理问题,之前面试的时候被问过,一脸懵逼,所以这里顺便提一下
解决方法
1.Nginx配置ip_hash,使client访问的服务器固定
2.使用Redis等缓存会话
3.设置使用浏览器本地cookie