您现在的位置是:首页 >学无止境 >Keepalived结合Nginx实现WEB高可用服务网站首页学无止境

Keepalived结合Nginx实现WEB高可用服务

Linux学习中 2024-06-17 10:13:24
简介Keepalived结合Nginx实现WEB高可用服务

前言

随着Nginx在国内的发展潮流,越来越多的互联网公司都在使用Nginx,Nginx高性能、稳定性成为IT人士青睐的HTTP和反向代理服务器。
Nginx负载均衡一般位于整个网站架构的最前端或者中间层,如果为最前端时单台Nginx会存在单点故障,也就是一台Nginx宕机,会影响用户对整个网站的访问。所以需要加入Nginx备份服务器,Nginx主服务器与备份服务器之间形成高可用,一旦发现Nginx主宕机,能快速将网站恢复至备份主机。

一. 使用脚本实现高可用

这种方式是通过两台服务器都绑定同一个VIP结合服务一起使用,通过判断服务是否正常,若服务不正常或者关闭了,这时在主服务器上的VIP会漂移到备服务器上,以达到高可用的方案。

1. 需要准备2台服务器
2. 将防火墙提前关闭
3. 两台服务器都装好nginx
4. 两台服务器都部署相同的VIP IP地址
5. 两台服务器通过启动脚本的方式进行判断服务是否正常

服务器系统服务IPVIP IP
CentOS7.9Nginx192.168.154.128192.168.154.188
CentOS7.9Nginx192.168.154.23192.168.154.188

1. 部署nginx服务

这里就直接使用yum install 的方式快速安装好nginx服务(以下步骤,两台服务器都要操作)
如果要用其他方式安装,可以参考这篇:部署安装Nginx服务实例

yum install -y epel-release; yum install -y nginx  

这里需要先安装epel-release,安装好这个扩展源,才会有nginx的软件包。

为了让两台服务器的网页看着有区别,重新设置index.html页面文件。
第一台服务器:

[root@localhost ~]# cd /usr/share/nginx/html/
[root@localhost html]# rm -rf *
[root@localhost html]# echo "This is 154.128 WebServer " > index.html

第二台服务器:

[root@localhost ~]# cd /usr/share/nginx/html/
[root@localhost html]# rm -rf *
[root@localhost html]# echo "This is 154.23 WebServer " > index.html

启动nginx服务

[root@localhost html]# systemctl start nginx

在网页上查看
在这里插入图片描述
![在这里插入图片描述](https://img-blog.csdnimg.cn/c5482f8615f443ffae852f5575eda272.png

2. 配置VIP的子网卡

切换到对应的目录进行创建子网卡(两台服务器都需要配置)

[root@localhost html]# cd /etc/sysconfig/network-scripts/
[root@localhost network-scripts]# vim ifcfg-ens32:0
[root@localhost network-scripts]# cat ifcfg-ens32:0
TYPE="Ethernet"
BOOTPROTO="static"
DEVICE="ens32:0"
ONBOOT="yes"
IPADDR="192.168.154.188"
NETMAST="255.255.255.0"

这里就不需要加上网关,可以查看默认已有的网关

[root@localhost network-scripts]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.154.1   0.0.0.0         UG    100    0        0 ens32
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0

配置好之后,可以用ifup命令启动下网卡,看下有没有问题;可以在两台服务器都试下,如果第一台服务器启动测试了没问题,需要先将网卡使用ifdown ens32:0 停止,再到另外一台服务器上启动。

[root@localhost network-scripts]# ifup ens32:0
[root@localhost network-scripts]# echo $?
0
[root@localhost html]# ifconfig |grep -wi "inet"|awk 'NR==2,NR==3{print $2}'
192.168.154.23
192.168.154.188

3. SHELL编程实现Nginx高可用脚本

部署两台Nginx服务器,发布WEB测试页面
通过两台IP均可以实现访问WEB网页
增加第三个IP,称为VIP,可以绑定至某一台0.188
实现访问VIP(域名)即可访问一台Nginx WEB服务
当该Nginx WEB服务宕机,VIP自动切换至另外一台WEB
时刻保证不管哪台Nginx WEB宕机,VIP均可以访问WEB

有了思路就可以开始写脚本,可以将脚本分成几步来实现

[root@localhost ~]# vim auto_nginx_status.sh
#!/bin/bash
#2023年5月10日15:47:28
#auto nginx status 
#####################
NGINX_NUM=$(ps -ef|grep nginx|grep -Ev "grep|auto_nginx"|wc -l)
if [ $NGINX_NUM -gt 0 ];then
        ping -c3 192.168.154.188 >>/dev/null 2>&1
        if [ $? -ne 0 ];then
                cd /etc/sysconfig/network-scripts/
                cat>ifcfg-ens32:0<<-EOF
                TYPE="Ethernet"
                BOOTPROTO="static"
                DEVICE="ens32:0"
                ONBOOT="yes"
                IPADDR="192.168.154.188"
                NETMAST="255.255.255.0"
                EOF
                ifup ens32:0
        fi
else
        cd /etc/sysconfig/network-scripts/
        ifdown ens32:0 >>/dev/null 2>&1
        rm -rf /etc/sysconfig/network-scripts/ifcfg-ens32:0
fi

第一版的脚本将Nginx服务与VIP关联起来,通过判断脚本进程是否正常来添加VIP网卡;添加之前先ping这个IP是否能通信,可以通信说明这个VIP正在使用,若这个网卡不能通信,说明处于一个释放的状态,这时另外一台服务器才会添加VIP的网卡。

当然这个脚本还是有缺陷的,因为只能判断后就退出脚本了,我们要让这个脚本可以一直运行。就需要加上while循环语句了。

[root@localhost ~]# vim auto_nginx_status.sh
#!/bin/bash
#2023年5月10日15:47:28
#auto nginx status 
#####################
while true
do
        sleep 5
        date
        NGINX_NUM=$(ps -ef|grep nginx|grep -Ev "grep|auto_nginx"|wc -l)
        if [ $NGINX_NUM -gt 0 ];then
                ping -c3 192.168.154.188 >>/dev/null 2>&1
                if [ $? -ne 0 ];then
                        cd /etc/sysconfig/network-scripts/
                        cat>ifcfg-ens32:0<<-EOF
                        TYPE="Ethernet"
                        BOOTPROTO="static"
                        DEVICE="ens32:0"
                        ONBOOT="yes"
                        IPADDR="192.168.154.188"
                        NETMAST="255.255.255.0"
                        EOF
                        ifup ens32:0
                fi
        else
                cd /etc/sysconfig/network-scripts/
                ifdown ens32:0 >>/dev/null 2>&1
                rm -rf /etc/sysconfig/network-scripts/ifcfg-ens32:0
        fi
done

第二版就出来了,加上while循环可以让脚本一直在后台执行,并且可以给它限定多少秒执行一次,并且显示出时间。但是这样看的话,有很多字段是重复的,我们可以将它定义成变量,这样就显示简洁很多。

#!/bin/bash
#2023年5月10日15:47:28
#auto nginx status 
#####################
ENS_FILE="ens32:0"
ENS_VIP="192.168.154.188"
ENS_DIR="/etc/sysconfig/network-scripts"
while true
do
        sleep 5
        date 
        NGINX_NUM=$(ps -ef|grep nginx|grep -Ev "grep|auto_nginx"|wc -l)
        if [ $NGINX_NUM -gt 0 ];then
                ping -c3 ${ENS_VIP} >>/dev/null 2>&1
                if [ $? -ne 0 ];then
                        cd ${ENS_DIR}/
                        cat>ifcfg-${ENS_FILE}<<-EOF
                        TYPE="Ethernet"
                        BOOTPROTO="static"
                        DEVICE="${ENS_FILE}"
                        ONBOOT="yes"
                        IPADDR="${ENS_VIP}"
                        NETMAST="255.255.255.0"
                        EOF
                        ifup ${ENS_FILE}
                fi
        else
                cd ${ENS_DIR}/
                ifdown ${ENS_FILE} >>/dev/null 2>&1
                rm -rf ifcfg-${ENS_FILE}
        fi
done

基本上就能实现所有功能了,下面来进行测试

4. 测试脚本的功能实现

检测第一台Nginx服务出现问题的时候,VIP是否会漂移到第二台服务器上,让网站可以实现高可用的方案。
在两台服务器上都运行这个脚本

[root@localhost ~]# /bin/bash auto_nginx_status.sh 
2023年 05月 10日 星期三 16:08:27 CST
2023年 05月 10日 星期三 16:08:34 CST
2023年 05月 10日 星期三 16:08:41 CST
2023年 05月 10日 星期三 16:08:48 CST
2023年 05月 10日 星期三 16:08:55 CST
2023年 05月 10日 星期三 16:09:02 CST
2023年 05月 10日 星期三 16:09:09 CST
2023年 05月 10日 星期三 16:09:16 CST
[root@localhost ~]# ifconfig |grep -wi "inet"|awk 'NR==1,NR==2{print $2}'
192.168.154.128
192.168.154.188

当前VIP在128这台服务器上
在这里插入图片描述
这时我们将第一台上的Nginx服务给关了,看下VIP是否会跳到第二台服务器上,让网页显示的内容是23的index.html文件的信息。

[root@localhost ~]# pkill nginx
[root@localhost ~]# ifconfig |grep -wi "inet"|awk 'NR==1,NR==2{print $2}'
192.168.154.128
127.0.0.1

杀死nginx进程时,在查看网卡的IP,发现VIP 188已经被释放了,那么接下来在网页上查看VIP是否显示的是第二台服务器上的内容。
在这里插入图片描述
已经变成第二台上的index.html文件的信息了,当然VIP也被绑到第二台服务器上了。

[root@localhost ~]# ifconfig |grep -wi "inet"|awk 'NR==2,NR==3{print $2}'
192.168.154.23
192.168.154.188

测试结果是没有什么问题的,但是仔细思考会发现这样的方式显然不够自动化,脚本需要人工去执行,而且过程比较繁琐,需要多配置一个子网卡。
接下来要讲的keepalived会简单很多,只需要将服务给部署好后,keepalived会检测服务是否正常,不正常的情况下会将VIP漂移到备用服务器上,同时移除主服务器,待主服务器上的服务正常后,重新让服务器回到服务器集群中。

二. 使用Keepalived服务实现高可用

概念======>《Keepalived概念与安装部署过程》
需要先把服务部署好之后,配置对应的参数
这里就直接使用yum安装服务

服务系统IP角色
Keepalived,NginxCentOS7.9172.17.0.2Master
Keepalived,NginxCentOS7.9172.17.0.3Backup

2.1 部署Keepalived

yum install keepalived -y

编写Keepalived与Nginx关联的脚本,需要在两台服务器上配置

cat auto_config_nginx_status.sh
#!/bin/bash
NGINX_NUM=$(ps -ef|grep nginx|grep -Ev "grep|auto_config"|wc -l)
if [ $NGINX_NUM -eq 0 ];then
        systemctl stop keepalived.service
fi   
#还需要将脚本权限设置成可执行权限
chmod +x auto_config_nginx_status.sh

将脚本加入到keepalived的配置文件中

第一台服务器设置成主master:

vim /etc/keepalived/keepalived.conf 
  1 ! Configuration File for keepalived
  2 
  3 global_defs {
  4    notification_email {
  5      sysadmin@firewall.loc
  6    }
  7    notification_email_from Alexandre.Cassen@firewall.loc
  8    smtp_server 127.0.0.1
  9    smtp_connect_timeout 30
 10    router_id LVS_DEVEL
 11 }
 12 
 13 vrrp_script check_nginx {
 14         script "/root/auto_config_nginx_status.sh"  #脚本的路径
 15         interval 5     #每隔5秒执行脚本
 16 
 17 vrrp_instance VI_1 {
 18     state MASTER
 19     interface eth0
 20     virtual_router_id 151
 21     priority 100
 22     advert_int 5
 23     authentication {
 24         auth_type PASS
 25         auth_pass 1111
 26     }
 27     virtual_ipaddress {
 28         172.17.0.188
 29     }
 30     track_script {
 31         check_nginx
 32     }
 33 }

第二台服务器:

vim /etc/keepalived/keepalived.conf 
  1 ! Configuration File for keepalived
  2 
  3 global_defs {
  4    notification_email {
  5      acassen@firewall.loc
  6    }
  7    notification_email_from Alexandre.Cassen@firewall.loc
  8    smtp_server 127.0.0.1
  9    smtp_connect_timeout 30
 10    router_id LVS_DEVEL
 11 }
 12 
 13 vrrp_script check_nginx {
 14         script "/root/auto_config_nginx_status.sh"
 15         interval 5
 16 }
 17 
 18 vrrp_instance VI_1 {
 19     state BACKUP
 20     interface eth0
 21     virtual_router_id 151
 22     priority 90
 23     advert_int 5
 24     authentication {
 25         auth_type PASS
 26         auth_pass 1111
 27     }
 28     virtual_ipaddress {
 29         172.17.0.188
 30     }
 31     track_script {
 32         check_nginx
 33    }
 34 }

然后两台服务器都启动服务就搞定了

systemctl restart keepalived.service

2.2 查看内核日志

在系统内核日志中查看启动服务的状态

[root@Master-02 ~]# tail -Fn 30 /var/log/messages
May 11 05:41:25 8be7506dd805 Keepalived_vrrp[1652]: Opening file '/etc/keepalived/keepalived.conf'.
May 11 05:41:30 8be7506dd805 Keepalived_vrrp[1652]: VRRP_Instance(VI_1) Transition to MASTER STATE
May 11 05:41:35 8be7506dd805 Keepalived_vrrp[1652]: VRRP_Instance(VI_1) Entering MASTER STATE
May 11 05:41:35 8be7506dd805 Keepalived_vrrp[1652]: VRRP_Instance(VI_1) setting protocol VIPs.
May 11 05:41:35 8be7506dd805 Keepalived_vrrp[1652]: Sending gratuitous ARP on eth0 for 172.17.0.188
May 11 05:41:35 8be7506dd805 Keepalived_vrrp[1652]: VRRP_Instance(VI_1) Sending/queueing gratuitous ARPs on eth0 for 172.17.0.188
May 11 05:41:35 8be7506dd805 Keepalived_vrrp[1652]: Sending gratuitous ARP on eth0 for 172.17.0.188
May 11 05:41:35 8be7506dd805 Keepalived_vrrp[1652]: Sending gratuitous ARP on eth0 for 172.17.0.188

目前VIP地址在Master服务器上,且当前172.17.0.2是为MASTER状态

[root@localhost ~]# curl 172.17.0.188
0.2IP server 

当前VIP显示的网页信息也是0.2机器上的,再来看下backup服务器的日志信息

[root@Backup-03 ~]# tail -Fn 30 /var/log/messages
May 11 05:41:44 b31c0155f7d0 Keepalived_healthcheckers[1441]: Opening file '/etc/keepalived/keepalived.conf'.
May 11 05:41:44 b31c0155f7d0 Keepalived_vrrp[1442]: SECURITY VIOLATION - scripts are being executed but script_security not enabled.
May 11 05:41:44 b31c0155f7d0 Keepalived_vrrp[1442]: VRRP_Instance(VI_1) removing protocol VIPs.
May 11 05:41:44 b31c0155f7d0 Keepalived_vrrp[1442]: Using LinkWatch kernel netlink reflector...
May 11 05:41:44 b31c0155f7d0 Keepalived_vrrp[1442]: VRRP_Instance(VI_1) Entering BACKUP STATE

backup服务器显示也是启动了keepalived.conf这个文件,当前状态为BACKUP。

可以通过查看VIP配置到哪台服务器上可以知道谁是MASTER状态。

2.3 查看网卡IP

这里要注意的是keepalived的VIP使用ifconfig命令是查看不到的

[root@Master-02 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
        RX packets 4462  bytes 975851 (952.9 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2738  bytes 376935 (368.1 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

需要在ip addr 命令中查看,VIP IP只能在服务器集群中的一个,如果VIP存在在多台服务器那就说明配置的时候出现问题了。

[root@Master-02 ~]# ip addr|grep -Eio "([0-9]{1,3}.){3}[0-9]{1,3}"
127.0.0.1
172.17.0.2
172.17.255.255
172.17.0.188

当然也可以通过抓包的方式来查看谁是MASTER。

VRRP通过竞选协议来实现虚拟路由器的功能,所有的协议报文都是通过IP组播(multicast)包(组播地址 224.0.0.18)形式发送。

2.4 使用tcpdump抓包

如果没有这个命令可以使用yum下载

[root@localhost ~]# which tcpdump
/usr/sbin/tcpdump
[root@localhost ~]# rpm -qf /usr/sbin/tcpdump
tcpdump-4.9.2-4.el7_7.1.x86_64
[root@Backup-03 ~]#yum install -y  tcpdump-4.9.2-4.el7_7.1.x86_64

由172.17.0.2服务器每个5秒发送组播包(224.0.0.18)到服务器集群中。

[root@Backup-03 ~]# tcpdump -i eth0 -nn host 172.17.0.2
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
06:09:26.728428 IP 172.17.0.2 > 224.0.0.18: VRRPv2, Advertisement, vrid 151, prio 100, authtype simple, intvl 5s, length 20
06:09:31.728754 IP 172.17.0.2 > 224.0.0.18: VRRPv2, Advertisement, vrid 151, prio 100, authtype simple, intvl 5s, length 20
06:09:36.729083 IP 172.17.0.2 > 224.0.0.18: VRRPv2, Advertisement, vrid 151, prio 100, authtype simple, intvl 5s, length 20
06:09:41.729403 IP 172.17.0.2 > 224.0.0.18: VRRPv2, Advertisement, vrid 151, prio 100, authtype simple, intvl 5s, length 20
06:09:46.729751 IP 172.17.0.2 > 224.0.0.18: VRRPv2, Advertisement, vrid 151, prio 100, authtype simple, intvl 5s, length 20

接下来我们模拟0.2服务器的服务宕机,看下VIP地址会不会漂移到另外一台服务器上。

2.5 模拟服务宕机

将172.17.0.2上的nginx给kill掉,由于脚本上的设置,当nginx服务关闭的时候,keepalived也会关闭。

[root@Master-02 ~]# pkill nginx
[root@Master-02 ~]# systemctl status keepalived
● keepalived.service - LVS and VRRP High Availability Monitor
   Loaded: loaded (/usr/lib/systemd/system/keepalived.service; disabled; vendor preset: disabled)
   Active: inactive (dead) since Thu 2023-05-11 06:19:37 UTC; 12s ago
  Process: 2952 ExecStart=/usr/sbin/keepalived $KEEPALIVED_OPTIONS (code=exited, status=0/SUCCESS)
 Main PID: 2953 (code=exited, status=0/SUCCESS)
   CGroup: /docker/8be7506dd805cc8dab483ae8954e61f78629d981094ef138546ad1328fa489af/system.slice/keepalived.service

查看0.2的日志信息

May 11 06:19:36 8be7506dd805 Keepalived[2953]: Stopping
May 11 06:19:36 8be7506dd805 systemd: Stopping LVS and VRRP High Availability Monitor...
May 11 06:19:36 8be7506dd805 Keepalived_vrrp[2955]: VRRP_Instance(VI_1) sent 0 priority
May 11 06:19:36 8be7506dd805 Keepalived_vrrp[2955]: VRRP_Instance(VI_1) removing protocol VIPs.
May 11 06:19:36 8be7506dd805 Keepalived_healthcheckers[2954]: Stopped
May 11 06:19:37 8be7506dd805 Keepalived_vrrp[2955]: Stopped
May 11 06:19:37 8be7506dd805 Keepalived[2953]: Stopped Keepalived v1.3.5 (03/19,2017), git commit v1.3.5-6-g6fa32f2
May 11 06:19:37 8be7506dd805 systemd: Stopped LVS and VRRP High Availability Monitor.

0.2上的keepalived服务停止了;继续查看0.3的日志信息

May 11 06:19:37 b31c0155f7d0 Keepalived_vrrp[1442]: VRRP_Instance(VI_1) Transition to MASTER STATE
May 11 06:19:42 b31c0155f7d0 Keepalived_vrrp[1442]: VRRP_Instance(VI_1) Entering MASTER STATE
May 11 06:19:42 b31c0155f7d0 Keepalived_vrrp[1442]: VRRP_Instance(VI_1) setting protocol VIPs.
May 11 06:19:42 b31c0155f7d0 Keepalived_vrrp[1442]: Sending gratuitous ARP on eth0 for 172.17.0.188
May 11 06:19:42 b31c0155f7d0 Keepalived_vrrp[1442]: VRRP_Instance(VI_1) Sending/queueing gratuitous ARPs on eth0 for 172.17.0.188
May 11 06:19:42 b31c0155f7d0 Keepalived_vrrp[1442]: Sending gratuitous ARP on eth0 for 172.17.0.188

0.3的状态转变成了MASTER,同时VIP也漂移到0.3机器上。

[root@Backup-03 ~]# ip addr |grep -Eo "([0-9]{1,3}.){3}[0-9]{1,3}"
127.0.0.1
172.17.0.3
172.17.255.255
172.17.0.188

以上部署的过程,第一台服务器上的服务若出现宕机的情况,在第一台服务器上的VIP会释放,Keepalived的VRRP路由冗余技术会将VIP配置到第二台服务器; 假如第一台服务器的服务经过运维人员恢复正常后,重新启动keepalived服务时,由于第一台的优先级高于第二台服务器,那么keepalived的VRRP会通过竞选的方式,100>90 ,将第二台的VIP重新漂移到第一台服务器上;
这种方式显然在企业中受影响会比较大,因为从第一台服务器到第二台服务器 ,VRRP会将VIP给释放,然后绑定到另外一台服务器,这个期间,会有3-5秒的时间,用户是访问不了网页的;第一台服务恢复后,VIP又会漂移回来,这时又会有几秒钟的用户访问不了;当前在keepalived中可以设置不抢占的方式,这样即使第一台服务恢复了,优先级也比第二台的高的情况下,也不会重新漂移回来到第一台服务器上。

需要在配置文件中重新设置,要注意的点是,设置成不抢占,需要将状态修改成BACKUP,因为MASTER状态无视不抢占这个设定。

#此时VIP在172.17.0.3的服务器中
[root@Backup-03 ~]# ip addr |grep -Eo "([0-9]{1,3}.){3}[0-9]{1,3}"
127.0.0.1
172.17.0.3
172.17.255.255
172.17.0.188

#在172.17.0.2的配置文件中将实例1的VIP设置成不抢占,并且将状态修改成BACKUP
! Configuration File for keepalived

global_defs {
   notification_email {
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
}
vrrp_script check_nginx {
        script "/root/auto_config_nginx_status.sh"
        interval 5
}
vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 151
    priority 100
    nopreempt  		#不抢占
    advert_int 5
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        172.17.0.188
    }
    track_script {
        check_nginx
    }
}

可以看到第一台服务器优先级高于第二台服务器时,也不会出现抢占VIP的情况。

[root@Master-02 ~]# tail -Fn 30 /var/log/messages
May 11 07:27:08 8be7506dd805 Keepalived_vrrp[11506]: VRRP_Instance(VI_1) removing protocol VIPs.
May 11 07:27:08 8be7506dd805 Keepalived_vrrp[11506]: Using LinkWatch kernel netlink reflector...
May 11 07:27:08 8be7506dd805 Keepalived_vrrp[11506]: VRRP_Instance(VI_1) Entering BACKUP STATE
May 11 07:27:08 8be7506dd805 Keepalived_vrrp[11506]: VRRP sockpool: [ifindex(88), proto(112), unicast(0), fd(10,11)]
May 11 07:27:08 8be7506dd805 Keepalived_vrrp[11506]: VRRP_Script(check_nginx) succeeded

以上仅仅是Nginx+keepalived主备模式,始终存在一台服务器处于空闲状态,那么如何更好的把两台服务器利用起来,下面可以Nginx+keepalived双主架构来实现,让两台服务器对外两个VIP地址,同时接收用户的请求。

三. 双主架构部署Nginx+Keepalived

这种方式可以有效的利用现有的资源,提升接收请求的并发量,让两台服务器互为主备,要实现这个效果,就需要在配置文件中在添加一个事例VI_2

3.1 在配置文件中添加功能

172.17.0.2 服务器:

! Configuration File for keepalived
global_defs {
   notification_email {
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
}
vrrp_script check_nginx {
        script "/root/auto_config_nginx_status.sh"
        interval 5
}
vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 151
    priority 100
    advert_int 5
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        172.17.0.188
    }
    track_script {
        check_nginx
    }
}
vrrp_instance VI_2 {   # 实例2
    state BACKUP        #第一台服务器上添加第二个实例,有一个主状态,这个就设置成备用状态
    interface eth0     #网卡接口不变
    virtual_router_id 152   #id号需要修改,实例之间ID号不能一致
    priority 90				#作为备用服务器,优先级可以设置成90
    advert_int 5			#表示每五秒进行一次健康检查
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        172.17.0.189 		#VIP IP设置成189
    }
    track_script {
        check_nginx
    }
}

172.17.0.3 服务器:

! Configuration File for keepalived

global_defs {
   notification_email {
     acassen@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
}
vrrp_script check_nginx {
        script "/root/auto_config_nginx_status.sh"
        interval 5
}
vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 151
    priority 90
    advert_int 5
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        172.17.0.188
    }
    track_script {
        check_nginx
   }
}
vrrp_instance VI_2 {
    state MASTER       
    interface eth0
    virtual_router_id 152
    priority 100
    advert_int 5
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        172.17.0.189

配置好之后就可以重启服务了

[root@Backup-03 ~]# systemctl restart keepalived

还是一样查看日志文件查看状态

[root@Master-02 ~]# tail -fn 30 /var/log/messages
May 11 06:40:30 8be7506dd805 Keepalived_vrrp[6728]: VRRP_Instance(VI_1) Transition to MASTER STATE
May 11 06:40:35 8be7506dd805 Keepalived_vrrp[6728]: VRRP_Instance(VI_1) Entering MASTER STATE
May 11 06:40:35 8be7506dd805 Keepalived_vrrp[6728]: VRRP_Instance(VI_1) setting protocol VIPs.
May 11 06:40:35 8be7506dd805 Keepalived_vrrp[6728]: Sending gratuitous ARP on eth0 for 172.17.0.188
May 11 06:40:35 8be7506dd805 Keepalived_vrrp[6728]: VRRP_Instance(VI_1) Sending/queueing gratuitous ARPs on eth0 for 172.17.0.188
May 11 06:40:35 8be7506dd805 Keepalived_vrrp[6728]: Sending gratuitous ARP on eth0 for 172.17.0.188
May 11 06:40:35 8be7506dd805 Keepalived_vrrp[6728]: Sending gratuitous ARP on eth0 for 172.17.0.188

172.17.0.2服务器使用的依然还是172.17.0.188的VIP;
再来查看172.17.0.3服务器的日志信息

May 11 06:40:36 b31c0155f7d0 Keepalived_vrrp[6422]: VRRP_Instance(VI_2) Transition to MASTER STATE
May 11 06:40:41 b31c0155f7d0 Keepalived_vrrp[6422]: VRRP_Instance(VI_2) Entering MASTER STATE
May 11 06:40:41 b31c0155f7d0 Keepalived_vrrp[6422]: VRRP_Instance(VI_2) setting protocol VIPs.
May 11 06:40:41 b31c0155f7d0 Keepalived_vrrp[6422]: Sending gratuitous ARP on eth0 for 172.17.0.189
May 11 06:40:41 b31c0155f7d0 Keepalived_vrrp[6422]: VRRP_Instance(VI_2) Sending/queueing gratuitous ARPs on eth0 for 172.17.0.189
May 11 06:40:41 b31c0155f7d0 Keepalived_vrrp[6422]: Sending gratuitous ARP on eth0 for 172.17.0.189
May 11 06:40:41 b31c0155f7d0 Keepalived_vrrp[6422]: Sending gratuitous ARP on eth0 for 172.17.0.189
May 11 06:40:41 b31c0155f7d0 Keepalived_vrrp[6422]: Sending gratuitous ARP on eth0 for 172.17.0.189
May 11 06:40:41 b31c0155f7d0 Keepalived_vrrp[6422]: Sending gratuitous ARP on eth0 for 172.17.0.189

172.17.0.3服务器使用的是v2实例的172.17.0.189 VIP;
通过ip addr 命令查看VIP是否出现冲突的情况;

[root@Master-02 ~]# ip addr |grep -Eo "([0-9]{1,3}.){3}[0-9]{1,3}"
127.0.0.1
172.17.0.2
172.17.255.255
172.17.0.188

[root@Backup-03 ~]# ip addr |grep -Eo "([0-9]{1,3}.){3}[0-9]{1,3}"
127.0.0.1
172.17.0.3
172.17.255.255
172.17.0.189

3.2 模拟服务宕机

继续试下服务宕机后,显示的结果是怎么样的
将第一台服务器的nginx服务给关闭了

[root@Master-02 ~]# pkill nginx
[root@Backup-03 ~]# ip addr |grep -Eo "([0-9]{1,3}.){3}[0-9]{1,3}"
127.0.0.1
172.17.0.3
172.17.255.255
172.17.0.189
172.17.0.188

可以看到两个VIP都跑到了第二台服务器上,那么这时就会有人问了,两个VIP都在一个服务器上,是否会出错;理论上是不会的,可以在网页上查看这两个VIP显示的结果。

[root@VM-12-17-centos ~]# curl 172.17.0.188
0.3IP server 
[root@VM-12-17-centos ~]# curl 172.17.0.189
0.3IP server 

这时将第一台服务器的服务恢复后,188的VIP会重新的绑定在172.17.0.2服务器上。

[root@Master-02 ~]# /usr/sbin/nginx
[root@Master-02 ~]# systemctl start keepalived;tail -fn 30 /var/log/messages
May 11 07:00:47 8be7506dd805 Keepalived_vrrp[8605]: Opening file '/etc/keepalived/keepalived.conf'.
May 11 07:00:47 8be7506dd805 Keepalived_vrrp[8605]: VRRP_Instance(VI_2) Entering BACKUP STATE
May 11 07:00:47 8be7506dd805 Keepalived_vrrp[8605]: VRRP sockpool: [ifindex(88), proto(112), unicast(0), fd(10,11)]
May 11 07:00:47 8be7506dd805 Keepalived_vrrp[8605]: VRRP_Script(check_nginx) succeeded
May 11 07:00:49 8be7506dd805 Keepalived_vrrp[8605]: VRRP_Instance(VI_1) Transition to MASTER STATE
May 11 07:00:54 8be7506dd805 Keepalived_vrrp[8605]: VRRP_Instance(VI_1) Entering MASTER STATE
May 11 07:00:54 8be7506dd805 Keepalived_vrrp[8605]: VRRP_Instance(VI_1) setting protocol VIPs.
May 11 07:00:54 8be7506dd805 Keepalived_vrrp[8605]: Sending gratuitous ARP on eth0 for 172.17.0.188
May 11 07:00:54 8be7506dd805 Keepalived_vrrp[8605]: VRRP_Instance(VI_1) Sending/queueing gratuitous ARPs on eth0 for 172.17.0.188
May 11 07:00:54 8be7506dd805 Keepalived_vrrp[8605]: Sending gratuitous ARP on eth0 for 172.17.0.188
May 11 07:00:54 8be7506dd805 Keepalived_vrrp[8605]: Sending gratuitous ARP on eth0 for 172.17.0.188

3.3 双主企业架构需要注意的地方

Nginx+keepalived双主企业架构,在日常维护及管理过程中需要如下几个方面:

  • Keepalived主配置文件必须设置不同的VRRP名称,同时优先级和VIP设置也各不相同;
  • Nginx网站总访问量为两台Nginx服务器之和,可以写脚本自动统计访问量;
  • 两台Nginx为Master,存在两个VIP地址,用户从外网访问VIP,需配置域名映射到两个VIP上方可。
  • 通过外网DNS映射不同VIP的方法也称为DNS负载均衡模式; 可以通过Zabbix实时监控VIP访问状态是否正常。

总结

Keepalived+Nginx的高可用配置起来还是比较容易的,需要注意的是,配置时,要将id号对应,并且优先级上也要决定好是哪台机器作为主,哪台作为备,若觉得以上内容还行的,可以点赞支持一下!
在这里插入图片描述

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。