Nginx系列—Nginx + Keepalived构建高可用的负载层

来源:互联网 发布:macbook必装软件 编辑:程序博客网 时间:2024/05/29 05:08

本文基于如下的拓扑图:

                   +-------------+                   |    uplink   |                   +-------------+                          |                          +    MASTER            keep|alived         BACKUP 192.168.1.11         192.168.1.10      192.168.1.12+-------------+    +-------------+    +-------------+|  Nginx VM1  |----|  virtualIP  |----|  Nginx VM2  |+-------------+    +-------------+    +-------------+                          |       +------------------+------------------+       |                  |                  |+-------------+    +-------------+    +-------------+|    web01    |    |    web02    |    |    web03    |+-------------+    +-------------+    +-------------+

一共配置两台服务器:

  • 第一台服务器:Nginx vm1 和 keepalived MASTER;
  • 第二台服务器:Nginx vm2 和 keepalived BACKUP;

一、准备工作

1、准备两台独立工作的 Nginx 系统

在我这里,安装两台 Nginx 的虚拟机IP地址分别是:

  • Nginx VM1:192.168.61.11:80
  • Nginx VM2:192.168.61.12:80

nginx没有什么可配置的,因为它与keepalived并没有联系。但记住,2台nginx服务器上的配置应该是完全一样的(rsync同步),这样才能做到对用户透明,nginx.conf 里面的 server_name 尽量使用域名来代替,然后dns解析这个域名到虚拟IP 192.168.1.10。

还有一点需要特别需要注意的是:Nginx一定要监听到所访问的地址。

附:Nginx服务器的安装配置请参考:

Nginx系列—服务器安装与配置
Nginx系列—虚拟主机配置的三种方式(一)
Nginx系列—虚拟主机配置的三种方式(二)
Nginx系列—虚拟主机配置的三种方式(三)

2、在已安装好 Nginx 的两个虚拟机上分别安装 Keepalived

我的环境是CentOS 7.0 X86_64,直接通过yum方式安装最简单:

[root@bogon /]# yum install -y keepalived[root@bogon /]# keepalived -v[root@bogon /]# Keepalived v1.2.13 (08/03,2017)

附:源码安装:Keepalived服务器的安装配置请参考:Keepalived系列—服务器安装与配置

3、编写 nginx 监控脚本

该脚本检测 ngnix 的运行状态,并在 nginx 进程不存在时尝试重新启动 ngnix,如果启动失败则停止 keepalived,准备让其它机器接管。

[root@bogon /]# vim /etc/keepalived/check_nginx.sh#!/bin/shif [ $(ps -C nginx --no-header | wc -l) -eq 0 ]; then    /usr/local/nginx/sbin/nginxfisleep 2if [ $(ps -C nginx --no-header | wc -l) -eq 0 ]; then    service keepalived stopfi

二、Nginx + Keepalived 最简配置

1、请再次确认前提

(首先,为了保证不会出现额外的问题,请首先关闭防火墙,当然正式环境里面,防火墙不能关闭)

  • 外网进行 Nginx 访问的浮动IP:192.168.1.10;
  • 我们将192.168.1.11这台服务器上运行的 Nginx 作为主要的 Nginx,其上的keepalived 服务我们设置成 Master 方式;
  • 我们将192.168.1.12这台服务器上运行的Nginx作为备用的Nginx服务,其上的keepalived 服务我们设置为 Backup 方式。

2、设置192.168.1.11上的MASTER

我们先来看看192.168.1.11上的原始IP信息:

[root@localhost ~]# ifconfigens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500        inet 192.168.1.11  netmask 255.255.255.0  broadcast 192.168.1.255        inet6 fe80::2a8d:be6:a4a8:ea0  prefixlen 64  scopeid 0x20<link>        ether 00:0c:29:1a:76:7e  txqueuelen 1000  (Ethernet)        RX packets 70  bytes 11009 (10.7 KiB)        RX errors 0  dropped 0  overruns 0  frame 0        TX packets 73  bytes 11927 (11.6 KiB)        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536        inet 127.0.0.1  netmask 255.0.0.0        inet6 ::1  prefixlen 128  scopeid 0x10<host>        loop  txqueuelen 1  (Local Loopback)        RX packets 72  bytes 6252 (6.1 KiB)        RX errors 0  dropped 0  overruns 0  frame 0        TX packets 72  bytes 6252 (6.1 KiB)        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

注意,这个11机器上的网卡设备号是ens33,而不是eth0,这个参数我们将在配置keepalived 的时候使用到。

下面是11上 keepalived 的最简配置:

! Configuration File for keepalived# global setting , notify email settingglobal_defs {    #存在于同一个网段中,一组keepalived的各个节点都有不同的名字    #在全局设置中,我们还可以设置管理员的email信息等。    router_id LVS_V1}#这个是我们在上一小结讲到的nginx检查脚本,我们保存在这个文件中(注意文件权限)vrrp_script chknginx {    script "/etc/keepalived/check_nginx.sh"    #每10秒钟,检查一次    interval 10}#keepalived实例设置,是最重要的设置信息vrrp_instance VI_1 {    #state状态MASTER表示是主要工作节点。    #一个keepalived组中,最多只有一个MASTER节点,当然也可以没有    state MASTER    #实例所绑定的网卡设备,我的网卡设备是ens33。您按照您自己的来    interface ens33    #同一个keepalived组,节点的设置必须一样,这样才会被识别    virtual_router_id 52    #节点优先级,BACKUP的优先级一定要比MASTER的优先级低    priority 100    #组播信息发送间隔,两个节点设置必须一样    advert_int 1    #实际的ens33上的固定ip地址    mcast_src_ip 192.168.1.11    #验证信息,只有验证信息相同,才能被加入到一个组中。    authentication {        auth_type PASS        auth_pass 1111    }    #虚拟地址和绑定的端口,如果有多个,就绑定多个    #dev 是指定浮动IP要绑定的网卡设备号    virtual_ipaddress {        192.168.1.10 dev ens33    }    #设置的检查脚本    #关联上方的“vrrp_script chknginx”    track_script {        chknginx    }}

3、设置192.168.1.12上的BACKUP

再来看看192.168.1.12这个备用节点上 keepalived 的设置:

! Configuration File for keepalived# global setting , notify email settingglobal_defs {    #这里和master节点不同    router_id LVS_V2}#check nginxvrrp_script chknginx {    script "/etc/keepalived/check_nginx.sh"    interval 10}# instance settingvrrp_instance VI_1 {    # 这里和Master节点不一样    state BACKUP    interface ens33    # 这里一定是一样的    virtual_router_id 52    # 这里的优先级比Master节点低    priority 99    advert_int 1    # 这里和Master节点不一样    mcast_src_ip=192.168.1.12    authentication {        auth_type PASS        auth_pass 1111    }    virtual_ipaddress {        192.168.1.10 dev ens33    }    track_script {        chknginx    }}

4、启动主节点和备用节点

以上配置中请注意几个关键点:

  • 注意nginx状态检查的脚本的位置,根据自己创建文件的位置不一样,脚本检查的指定位置也不一样;
  • 注意优先级,MASTER节点的优先级一定要高于所有的BACKUP节点;
  • 注意局域网的组播地址,一定要可用。局域网内所有keepalived节点都是利用组播方式寻找对方;
  • 谁说BACKUP节点只能有一个!?
  • 最后,keepalived一定要注册成服务形式,您可以想象上面所有脚本、配置、命令如果重启后再来一次,会是什么情况。

接下来,我们要开始启动 Master 节点和 Backup 节点了,为了准确的查看日志状态,您需要观察系统日志。系统日志所在的位置:

tail -f /var/log/messages

先启动Master节点:

[root@localhost ~]# service keepalived start

再启动Backup节点:

[root@localhost ~]# service keepalived start

如果设置和启动都是成功的,您不会在日志信息中收到任何的keepalived报错信息。接下来您就可以使用192.168.1.10这个IP访问Nginx了:

这里写图片描述

另外,这个绑定在192.168.1.11上的浮动ip:192.168.1.10,您通过ipconfig命令一般是看不到的,要使用ip addr命令进行查看:

# 使用ip命令配置的地址,ifconfig查看不了[root@bogon system]# ip a|grep ens332: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000    inet 192.168.1.11/24 brd 192.168.1.255 scope global dynamic ens33    inet 192.168.1.12/32 scope global ens33

为了试验,我们主动停止 Master 节点上的 keepalived 服务(注意,杀 Nginx 进程不起作用,因为我们的检查脚本会试图重新启动 Nginx 进程),接下来我们可以看到浮动IP漂移到了12备机上:

这里写图片描述

三、Nginx + Keepalived非抢占模式

通过上面的详细介绍,相信您对Nginx + Keepalived的安装方式有了一个明确的理解。keepalived的切换可以是自动的,但是却做不到毫秒级别,他怎么都需要几秒钟的时间进行切换。

这就有一个问题,虽然在主节点出现问题我们转向备份节点时,这个延时无可避免,但是在我们修复主节点后,实际上并没有必要再马上做一次切换,所以 Keepalived 提供了一种非抢占模式,来满足这个要求。

下面我们就来介绍一下Keepalived的非抢占模式的配置(无MASTER节点,全部依据优先级确定哪个节点进行工作):

1、原来主节点的配置改动

! Configuration File for keepalived# global setting , notify email settingglobal_defs {    router_id LVS_V1}vrrp_script chknginx {    script "/etc/keepalived/check_nginx.sh"    interval 10    # 一旦节点失效,节点的优先级就减少2    # 有多少个keepalived节点,就填写多少数量。    # 这样保证这个节点的优先级比其他节点都低    weight -2    # fall 表示多少次检查失败,就算节点失效。默认1    #fall 1}vrrp_instance VI_1 {    #state状态都是BACKUP表示是主要工作节点。    state BACKUP    interface ens33    virtual_router_id 52    # 这个关键配置项,设置为“非抢占”模式    nopreempt    # 每个节点的优先级一定要不一样    priority 100    advert_int 1    mcast_src_ip=192.168.1.11    authentication {        auth_type PASS        auth_pass 1111    }    #虚拟地址和绑定的端口,如果有多个,就绑定多个    #dev 是指定浮动IP要绑定的网卡设备号    virtual_ipaddress {        192.168.1.10 dev ens33    }    #设置的检查脚本    #关联上方的“vrrp_script chknginx”    track_script {        chknginx    }}

原来的主节点设置更改完成。

2、原来备份节点的配置改动

加入“非抢占”模式的关键字、更改一个确定的优先级,设置检查失败后优先级的递减量,就行了。


附、配置过程中的问题

1、Nginx为什么会停止响应呢?在我的工作经验中,无非有以下几种情况

  • Nginx的所有进程被强行终止(或管理进程);
    这种情况,是我们需要检查和切换的。无论什么情况下进程被终止了,如果它不能重启,我们就要切换到备机。

  • Nginx日志盘的挂载点崩溃或者磁盘写满;
    这个也是我们需要检查和切换的。

  • Nginx已经达到设置的最大连接数,暂时停止响应;
    这种情况下,我们不能进行备机切换,因为通过VIP:192.168.61.100连接过来的用户请求比较多(在我们优化参数后,可以达到65535 / 4的数量),一旦我们进行备机切换,这些用户请求将全部异常。这个问题的解决需要靠增加负载机器,而不是主备切换。

  • Nginx物理机异常关机。
    这个肯定是需要进行检查和切换的。

2、nginx监控脚本

#!/bin/shif [ $(ps -C nginx --no-header | wc -l) -eq 0 ]; then    /usr/local/nginx/sbin/nginxfisleep 2if [ $(ps -C nginx --no-header | wc -l) -eq 0 ]; then    service keepalived stopfi

整个脚本的解释:

第一个判断说明的是,如果当前nginx的进程数量 == 0,那么执行nginx的启动命令,试图重新启动nginx;接下来等待2秒(这是为了给nginx一定的启动时间),然后再次查看Nginx的进程数量,如果仍然 == 0,那么停止这台机器的keepalived服务,以便备用的Keepalived节点检查到Keepalived已经停止这个事件,并将浮动IP切换到备用服务器上。

注意,这段脚本是和我机器上的Nginx安装路径、Keepalived服务的状态有关的,您如果要用的话,请进行相应的更改。

然后具体讲解一下每个命令的含义:

我们大致讲解一下“ps -C nginx –no-header | wc -l”这个命令:

  • ps 这个命令用来进行linux中进程相关的查询,-C 意思是按照进程名称进行查询。查询出来后的结果如下:
[root@bogon /]# ps -C nginx   PID TTY          TIME CMD  3178 ?        00:00:00 nginx  3180 ?        00:00:00 nginx  3181 ?        00:00:00 nginx  3182 ?        00:00:00 nginx  3183 ?        00:00:00 nginx
  • 如果要去掉统计出来的结果表的头部,那么要使用 –no-header 参数,加上参数后,查询结果如下:
[root@bogon /]# ps -C nginx --no-header  3178 ?        00:00:00 nginx  3180 ?        00:00:00 nginx  3181 ?        00:00:00 nginx  3182 ?        00:00:00 nginx  3183 ?        00:00:00 nginx
  • “|”,这是Linux中的管道流命令,将上一个命令的输出结果作为下一个命令的输入。
  • wc 统计命令,-l 参数,代表按行数进行统计。所以整个命令的输出结果为:
[root@bogon /]# ps -C nginx --no-header | wc -l5

3、配置选项说明

global_defs

  • notification_email : keepalived在发生诸如切换操作时需要发送email通知地址,后面的 smtp_server 相比也都知道是邮件服务器地址。也可以通过其它方式报警,毕竟邮件不是实时通知的;
  • router_id : 机器标识,通常可设为hostname。故障发生时,邮件通知会用到。

vrrp_instance

  • state : 指定instance(Initial)的初始状态,就是说在配置好后,这台服务器的初始状态就是这里指定的,但这里指定的不算,还是得要通过竞选通过优先级来确定。如果这里设置为MASTER,但如若他的优先级不及另外一台,那么这台在发送通告时,会发送自己的优先级,另外一台发现优先级不如自己的高,那么他会就回抢占为MASTER;
  • interface : 实例绑定的网卡,因为在配置虚拟IP的时候必须是在已有的网卡上添加的;
  • mcast_src_ip : 发送多播数据包时的源IP地址,这里注意了,这里实际上就是在那个地址上发送VRRP通告,这个非常重要,一定要选择稳定的网卡端口来发送,这里相当于heartbeat的心跳端口,如果没有设置那么就用默认的绑定的网卡的IP,也就是interface指定的IP地址;
  • virtual_router_id : 这里设置VRID,这里非常重要,相同的VRID为一个组,他将决定多播的MAC地址;
  • priority : 设置本节点的优先级,优先级高的为master;
  • advert_int : 检查间隔,默认为1秒。这就是VRRP的定时器,MASTER每隔这样一个时间间隔,就会发送一个advertisement报文以通知组内其他路由器自己工作正常;
  • authentication : 定义认证方式和密码,主从必须一样;
  • virtual_ipaddress : 这里设置的就是VIP,也就是虚拟IP地址,他随着state的变化而增加删除,当state为master的时候就添加,当state为backup的时候删除,这里主要是有优先级来决定的,和state设置的值没有多大关系,这里可以设置多个IP地址;
  • track_script : 引用VRRP脚本,即在 vrrp_script 部分指定的名字。定期运行它们来改变优先级,并最终引发主备切换。

vrrp_script
告诉 keepalived 在什么情况下切换,所以尤为重要。可以有多个 vrrp_script

  • script : 自己写的检测脚本。也可以是一行命令如killall -0 nginx;
  • interval 2 : 每2s检测一次;
  • weight -5 : 检测失败(脚本返回非0)则优先级 -5;
  • fall 2 : 检测连续 2 次失败才算确定是真失败。会用weight减少优先级(1-255之间);
  • rise 1 : 检测 1 次成功就算成功。但不修改优先级。

这里要提示一下script一般有2种写法:

  1. 通过脚本执行的返回结果,改变优先级,keepalived继续发送通告消息,backup比较优先级再决定;
  2. 脚本里面检测到异常,直接关闭keepalived进程,backup机器接收不到advertisement会抢占IP。

上文 vrrp_script 配置部分,killall -0 nginx属于第1种情况,/etc/keepalived/check_nginx.sh属于第2种情况(脚本中关闭keepalived)。个人更倾向于通过shell脚本判断,但有异常时exit 1,正常退出exit 0,然后keepalived根据动态调整的 vrrp_instance 优先级选举决定是否抢占VIP:

  • 如果脚本执行结果为0,并且weight配置的值大于0,则优先级相应的增加;
  • 如果脚本执行结果非0,并且weight配置的值小于0,则优先级相应的减少。

其他情况,原本配置的优先级不变,即配置文件中priority对应的值。

提示:

  1. 优先级不会不断的提高或者降低;
  2. 可以编写多个检测脚本并为每个检测脚本设置不同的weight(在配置中列出就行);
  3. 不管提高优先级还是降低优先级,最终优先级的范围是在[1,254],不会出现优先级小于等于0或者优先级大于等于255的情况;
  4. 在MASTER节点的 vrrp_instance 中 配置 nopreempt ,当它异常恢复后,即使它 prio 更高也不会抢占,这样可以避免正常情况下做无谓的切换。

以上可以做到利用脚本检测业务进程的状态,并动态调整优先级从而实现主备切换。

配置结束

在默认的keepalive.conf里面还有 virtual_server,real_server 这样的配置,我们这用不到,它是为lvs准备的。 notify 可以定义在切换成MASTER或BACKUP时执行的脚本,如有需求请自行google。

阅读全文
0 0