Linux架构18 keepalived高可用, 抢占式和非抢占式, 高可用keepalived和nginx
一般是指2台机器启动着完全相同的业务系统,当有一台机器down机了,另外一台服务器就能快速的接管,对于访问的用户是无感知的。
注:高可用使用原则:能用负载均衡就不用高可用。高可用会浪费一台机器。
# 硬件通常使用 F5 (监测端口是否正常,如果不正常就自动切换到另一个端口,类似四层) # 软件通常使用 keepalived
keepalived软件是基于VRRP协议实现的,VRRP是虚拟路由冗余协议,主要用于解决单点故障问题
如下图,路由网关出现问题,vip漂移到另一台机器,并且vmac变更,并告诉ARP广播去修改ARP缓存表里的mac地址(vip是keepalived创建的虚拟ip地址进行机器间的漂移。vmac就是当前漂移的机器的mac地址,一个网卡只能有一个mac地址)
如何才能做到出现故障自动转移,此时VRRP就出现了,我们的VRRP其实是通过软件或者硬件的形式在Master和Backup外面增加一个虚拟的MAC地址(VMAC)与虚拟IP地址(VIP),
那么在这种情况下,PC请求VIP的时候,无论是Master处理还是Backup处理,PC仅会在ARP缓存表中记录VMAC与VIP的信息。
1、如何确定谁是主节点谁是备节点(选举投票,优先级) 2、如果Master故障,Backup自动接管,那么Master恢复后会夺权吗(抢占式、非抢占式) 3、如果两台服务器都认为自己是Master会出现什么问题(脑裂)
主机 | IP | 身份 |
---|---|---|
lb01 | 10.0.0.4 | master |
lb02 | 10.0.0.5 | backup |
10.0.0.3 | VIP |
2.保证lb01和lb02配置完全一致
[root@lb01 conf.d]# scp -r /etc/nginx/ssl-key/ 172.16.1.5:/etc/nginx/ [root@lb01 conf.d]# scp ./* 172.16.1.5:/etc/nginx/conf.d/
[root@lb01 conf.d]# yum install -y keepalived [root@lb02 conf.d]# yum install -y keepalived
# 查看keepalived的配置文件 [root@lb01 conf.d]# rpm -qc keepalived --------------------------------------- /etc/keepalived/keepalived.conf /etc/sysconfig/keepalived # 配置主节点配置文件 [root@lb01 conf.d]# vim /etc/keepalived/keepalived.conf global_defs { # 全局配置 router_id lb01 # 身份识别,唯一的(一般给主机名即可) } vrrp_instance VI_1 { # 主要配置 VI_1为一个实例的名字 state MASTER # 状态,只有MASTER(主)和BACKUP(备);必须大写(没什么用,实际根据priority大小决定主还是备,这个相当于注释) interface eth0 # 网卡绑定(vip绑定),心跳检测(用这块网卡去监测) virtual_router_id 51 # 虚拟路由标识,组id,把master和backup判断为一组 priority 100 # 优先级(真正判断是主是从的条件)(值越大优先级越高) advert_int 1 # 监测状态间隔时间(单位是秒,对上面网卡进行心跳检测) authentication { # 认证(用于组成员身份判断) auth_type PASS # 认证方式,互相通讯的方式(这里是密码的方式) auth_pass 1111 # 认证密码指定 } virtual_ipaddress { # 虚拟的vip地址 10.0.0.3 } } ---------------------------------------
[root@lb02 ~]# vim /etc/keepalived/keepalived.conf global_defs { router_id lb02 } vrrp_instance VI_1 { # 接管同一个实例,VI_1名称不变 state BACKUP interface eth0 virtual_router_id 51 priority 90 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 10.0.0.3 } }
区别 | master主节点 | backup备节点 |
---|---|---|
router_id(唯一标识符) | lb01 | lb02 |
state(角色状态) | MASTER | BACKUP |
priority(优先级) | 100 | 90 |
7.启动keepalived
[root@lb01 ~]# systemctl start keepalived [root@lb01 ~]# systemctl enable keepalived # 可以加入开机项 [root@lb01 ~]# tail -f /var/log/messages # 日志默认和系统的放一起了 [root@lb02 ~]# systemctl start keepalived [root@lb02 ~]# tail -f /var/log/messages # 测试: 检查windows的arp缓存表。通过 arp -a 命令查看vmac和谁一致,说明漂移到谁这了。如下图
# 默认在系统日志 /var/log/messages #配置keepalived [root@lb02 ~]# vim /etc/sysconfig/keepalived KEEPALIVED_OPTIONS="-D -d -S 0" #配置rsyslog [root@lb02 ~]# vim /etc/rsyslog.conf # 在末尾添加 local0.* /var/log/keepalived.log #重启服务 [root@lb02 ~]# systemctl restart rsyslog [root@lb02 ~]# systemctl restart keepalived #查看日志 [root@lb02 ~]# tail -f /var/log/keepalived.log
1.当两个节点都启动时
#由于节点1的优先级高于节点2,所以VIP在节点1上面 [root@lb01 ~]# ip addr | grep 10.0.0.3 inet 10.0.0.3/32 scope global eth0 [root@lb02 ~]# ip addr | grep 10.0.0.3
[root@lb01 ~]# systemctl stop keepalived #节点2联系不上节点1,主动接管VIP [root@lb02 ~]# ip addr | grep 10.0.0.3 inet 10.0.0.3/32 scope global eth0
[root@lb01 ~]# systemctl start keepalived #由于节点1的优先级高于节点2,所以恢复节点1之后,vip又漂回节点1 [root@lb01 ~]# ip addr | grep 10.0.0.3 inet 10.0.0.3/32 scope global eth0
1、两个节点的state都必须配置为BACKUP(官方建议,不改测试下来还是抢占式) 2、两个节点都在vrrp_instance中添加nopreempt参数 3、其中一个节点的优先级必须要高于另一个节点的优先级。 PS: 两台服务器都角色状态启用nopreempt后,必须修改角色状态统一为BACKUP, 唯一的区别就是优先级。 配置步骤: 1.修改state 为backup 2.增加nopreempt
1)节点一修改
[root@lb01 ~]# vim /etc/keepalived/keepalived.conf ... ... vrrp_instance VI_1 { state BACKUP nopreempt ...... } [root@lb01 ~]# systemctl restart keepalived
2)节点二修改
[root@lb02 ~]# vim /etc/keepalived/keepalived.conf ... ... vrrp_instance VI_1 { state BACKUP nopreempt ...... } [root@lb02 ~]# systemctl restart keepalived
# cmd输入 C:\Users\ldc>arp -a 接口: 10.0.0.1 --- 0xc Internet 地址 物理地址 类型 10.0.0.3 00-0c-29-12-de-f5 动态 10.0.0.4 00-0c-29-7a-dc-51 动态 10.0.0.5 00-0c-29-12-de-f5 动态 # 说明vip在lb02上,非抢占式
由于某些原因,导致两台keepalived高可用服务器在指定时间内,无法检测到对方是否存活,各自去调用资源,分配工作,而此时两台服务器都还活着并且工作。
1.服务器网线松动,网络故障 2.服务器硬件发生损坏,硬件故障 3.主备服务器之间开启了防火墙
[root@lb02 ~]# systemctl start firewalld [root@lb01 ~]# systemctl start firewalld
如下图,Wireshark监测ip为5和4同时在工作,一个请求过来,2边都会执行(浪费资源,不推荐这么做)
# 访问浏览器因为开启防火墙,所以访问不了站点,需要配置开启http服务 [root@lb02 ~]# firewall-cmd --add-service=http [root@lb02 ~]# firewall-cmd --add-service=https
# 干掉一台服务 [root@lb02 ~]# systemctl stop firewalld # 判断是否有脑裂现象 先做信任,免密登录 [root@lb01 ~]# vim check_naolie.sh #!/bin/sh vip=10.0.0.3 lb02_ip=10.0.0.5 while true;do ssh $lb02_ip 'ip addr | grep 10.0.0.3' &>/dev/null if [ $? -eq 0 -a `ip add|grep "$vip"|wc -l` -eq 1 ];then # -a是and意思 echo "ha is split brain.warning." else echo "ha is ok" fi sleep 5 done --------------------------------- -eq 等于 -ne 不等于 -ge 大于等于 -gt 大于 -le 小于等于 -lt 小于
注:keepalived如何在生产使用 1.需要有硬件服务器(证券,银行,国企等) 在云上不需要keepalived,阿里云自带高可用 2.必须要有两台硬件设备做高可用 建议:上云 | 对于 国企\银行\证券,一定会用keepalived,现在也有用私有云的技术
1.nginx默认监听所有IP (nginx会监听网卡上所有ip)
#如果nginx宕机,用户请求页面会失败,但是keepalived没有关闭,VIP仍然在nginx挂掉了的机器上,导致影响业务; #我们应该编写一个脚本,判断nginx状态,如果nginx挂掉,先尝试重启nginx,如果启动不了则关闭keepalived [root@lb01 ~]# vim check_web.sh ps -ef | grep [n]ginx &>/dev/null if [ $? -eq 1 ];then systemctl start nginx &>/dev/null sleep 3 ps -ef | grep [n]ginx &>/dev/null if [ $? -eq 1 ];then systemctl stop keepalived fi fi # 下方脚本和上面的脚本功能一致 [root@lb01 ~]# vim check_web.sh #!/bin/sh nginxpid=$(ps -C nginx --no-header|wc -l) # 查nginx的进程数,最少2个进程,master和worker #1.判断Nginx是否存活,如果不存活则尝试启动Nginx if [ $nginxpid -eq 0 ];then systemctl start nginx sleep 3 #2.等待3秒后再次获取一次Nginx状态 nginxpid=$(ps -C nginx --no-header|wc -l) #3.再次进行判断, 如Nginx还不存活则停止Keepalived,让地址进行漂移,并退出脚本 if [ $nginxpid -eq 0 ];then systemctl stop keepalived fi fi
3.调用脚本
# 注意:在os中直接执行/root/check_web.sh是执行不了的,因为不是命令。给脚本增加执行权限,就可以直接执行 # 给脚本添加执行权限 [root@lb01 ~]# chmod +x check_web.sh [root@lb01 ~]# /root/check_web.sh # 写绝对路径就能执行了 # keepalived内部就可以设置调用脚本 [root@lb01 ~]# vim /etc/keepalived/keepalived.conf global_defs { router_id lb01 } #每5秒执行一次脚本,脚本执行内容不能超过5秒,否则会中断再次重新执行脚本 vrrp_script check_web { # 调用脚本,起个名字 script "/root/check_web.sh" # 脚本位置,绝对路径,必须像上面授权执行权限 interval 5 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 10.0.0.3 } #调用并运行脚本(注意要在这个实例里面) track_script { check_web } } #在Master的keepalived中调用脚本,抢占式,仅需在master配置即可。(注意,如果配置为非抢占式,那么需要两台服务器都使用该脚本)