nginx

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > nginx > keepalived搭建nginx

keepalived对nginx进行高可用搭建及原理详解

作者:乔克

这篇文章主要为大家介绍了keepalived对nginx进行高可用搭建及原理详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

一、Keepalived介绍

摘抄自官网的介绍:

Keepalived is a routing software written in C. The main goal of this project is to provide simple and robust facilities for loadbalancing and high-availability to Linux system and Linux based infrastructures.

项目地址:github.com/acassen/kee…

所以,Keepalived 一方面具有配置管理LVS的功能,同时还具有对LVS下面节点进行健康检查的功能,另一方面也可实现系统网络服务的高可用功能。

二、Keepalived的应用场景

通过官网的介绍我们可以看到Keepalived提供了两个重要的功能:loadbalancing和high-availability。最初是专门为LVS负载均衡软件设计,可以用来管理并监控LVS集群系统中各个服务节点的状态,后来的版本中又加入了可以实现高可用的VRRP功能。

因此,Keeaplived主要有两种应用场景,一个是通过配置keepalived结合ipvs做到负载均衡(LVS+Keepalived);

另一个是通过自身健康检查、资源接管等功能做高可用(双机热备),实现故障转移,功能近似于Heartbeat。

目前全球监控的分布式MySQL集群,使用了Keeaplived来实现proxy的双机热备功能,所以下面只介绍在高可用场景下的相关知识。

三、Keepalived的工作原理

1 VRRP协议

keepalived是以VRRP协议为实现基础的,VRRP全称Virtual Router Redundancy Protocol,即虚拟路由冗余协议,可以认为是实现路由器高可用的协议。

对应到高可用的场景,实际上就是把路由器换成了服务器或者服务器上的应用: 通常情况下是将两台linux服务器组成一个热备组(master-backup),同一时间热备组内只有一台主服务器(master)提供服务,同时master会虚拟出一个共用IP地址(VIP),这个VIP只存在master上并对外提供服务。 如果keepalived检测到master宕机或服务故障,备服务器(backup)会自动接管VIP成为master,keepalived并将master从热备组移除,当master恢复后,会自动加入到热备组,默认再抢占成为master,起到故障转移功能。

2 核心组件

keepalived是模块化设计,不同模块负责不同的功能,主要有三个模块,分别是core、check和VRRP,其中:

此外还有:

3 分层工作

keepalived做负载均衡时工作在TCP/IP协议的3/4/5层,做高可用时工作在OSI七层协议模型的3/4/7层,基本上是一样的,叫法不同而已

分层功能相关协议
应用层网络服务和最终用户的一个接口TFTP,HTTP,SNMP,DNS,FTP,SMTP,TELNET
表示层数据的表示、安全、压缩无协议
会话层会话的建立、管理、中止无协议
传输层定义传输数据的协议端口号,以及流控和差错校验TCP,UDP
网络层进行逻辑地址寻址,实现不同网络之间的路径选择IP,ICMP,RIP,OSPF,BGP,IGMP
数据链路层建立逻辑连接、硬件地址寻址、差错校验等功能SLIP,CSLIP,PPP,ARP,RARP,MTU
物理层建立、连接、断开物理连接ISO2110,IEEE802,IEEE802.2

具体工作在哪一层的区别就在于用什么样的网络协议来进行健康检查:

Layer3:工作在三层时,keepalived会定期向热备组中的服务器发送一个ICMP数据包,来判断某台服务器是否故障,如果没有响应则将这台服务器从热备组移除。

Layer4:工作在四层时,keepalived以TCP端口的状态判断服务器是否故障,比如检测MySQL的3306端口,如果无法访问则将这台服务器从热备组移除。

Layer7:工作在七层时,keepalived根据用户设定的策略判断服务器上的程序是否正常运行,比如使用HTTP请求的方式,如果返回错误的状态码则将这台服务器从热备组移除。

在Keepalived服务器群之间,只有作为主的服务器不断发送VRRP广播包,告诉备它还活着,此时备不会抢占主,只有当主不可用,既备接受不到主的VRRP广播包,这时候备就会启动相关的服务接管主的任务向外提供服务,以保证服务的正常使用。

4 工作状态

keepalived正常启动的时候,共启动3个进程: 一个是父进程,负责监控其子进程;

一个是VRRP子进程,另外一个是checkers子进程;

两个子进程都被系统watchlog看管,Healthcheck子进程检查各自服务器的健康状况。

如果healthchecks进程检查到master上服务不可用了,就会通知本机上的VRRP子进程,让他删除通告,并且去掉虚拟IP,转换为BACKUP状态。 生产服务器上的keepalived进程

四、Keepalived使用

1 配置介绍

keepalived配置文件按层级模块划分的,每层由"{ }"来界定。在主配置文件中可以通过include来涵盖多个子配置文件。 详细语法说明:官方文档 配置文件包括以下几个模块:

[root@localhost ~]# cat /etc/keepalived/keepalived.conf
! 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_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的端口
        }
    }
}
}

2 使用keepalived对nginx进行高可用搭建

2.1 环境准备

主机ip角色部署软件
192.168.73.135masterkeepalived、nginx
192.168.73.136salvekeepalived、nginx
192.168.73.100虚ip 

|

2.2 nginx软件安装和配置

在192.168.73.136操作为例,135上把index改成135即可

[root@localhost ~]# yum -y install nginx
[root@localhost ~]# cd /usr/share/nginx/html/
[root@localhost html]# mv index.html index.html.back
[root@localhost html]# echo "I am 192.168.73.136" > index.html
[root@localhost html]# systemctl start nginx
[root@localhost html]# curl 192.168.73.136
I am 192.168.73.136

2.3 Keepalived软件安装

[root@localhost ~]# yum install keepalived -y
[root@localhost ~]# rpm -ql keepalived
/etc/keepalived
/etc/keepalived/keepalived.conf  # 主配置文件
/etc/sysconfig/keepalived
/usr/bin/genhash
/usr/lib/systemd/system/keepalived.service
/usr/libexec/keepalived
/usr/sbin/keepalived

2.4 监听存活脚本

[root@localhost ~]# vim /etc/keepalived/check_port.sh
#!/bin/bash
#keepalived 监控端口脚本
#使用方法:
#在keepalived的配置文件中
#vrrp_script check_port {#创建一个vrrp_script脚本,检查配置
#    script "/etc/keepalived/check_port.sh 80" #配置监听的端口
#    interval 2 #检查脚本的频率,单位(秒)
#}
CHK_PORT=$1
if [ -n "$CHK_PORT" ];then
        PORT_PROCESS=`ss -lnt|grep $CHK_PORT|wc -l`
        if [ $PORT_PROCESS -eq 0 ];then
                echo "Port $CHK_PORT Is Not Used,End."
                exit 1
        fi
else
        echo "Check Port Cant Be Empty!"
fi
[root@localhost ~]# chmod  +x /etc/keepalived/check_port.sh

2.5 最终配置文件

(1)Master配置

[root@localhost ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
   router_id 192.168.73.136
}
vrrp_script chk_nginx {
    script "/etc/keepalived/check_port.sh 80"
    interval 2
    weight -20
}
vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 251
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 11111111
    }
    track_script {
         chk_nginx
    }
    virtual_ipaddress {
        192.168.73.100
    }
}

(2)Slave配置

! Configuration File for keepalived
global_defs {
        router_id 192.168.73.135
}
vrrp_script chk_nginx {
        script "/etc/keepalived/check_port.sh 80"
        interval 2
        weight -20
}
vrrp_instance VI_1 {
        state BACKUP
        interface ens33
        virtual_router_id 251
        priority 90
        advert_int 1
        authentication {
                auth_type PASS
                auth_pass 11111111
        }
        track_script {
                chk_nginx
        }
        virtual_ipaddress {
                192.168.73.100
        }
}

2.6 启动主从的Keepalived

[root@localhost ~]]systemctl start keepalived && systemctl enable keepalive

2.7 查看VIP是否启动

[root@localhost keepalived]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:6f:74:0a brd ff:ff:ff:ff:ff:ff
    inet 192.168.73.136/24 brd 192.168.73.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet 192.168.73.100/32 scope global ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::af0e:a936:d997:18da/64 scope link noprefixroute
       valid_lft forever preferred_lft forever

2.8 测试

首先在浏览器中访问vip,可以看到我们访问的是BACKUP上的web地址

关掉master上的nginx,查看VIP是否漂移到备机。

# 关闭主nginx
[root@localhost ~]# systemctl stop nginx
# 查看备上的IP信息,我们发现vip已经偏移到备机上了
[root@localhost ~]# ip addr
1: lo: &lt;LOOPBACK,UP,LOWER_UP&gt; mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: ens33: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:6f:74:0a brd ff:ff:ff:ff:ff:ff
    inet 192.168.73.136/24 brd 192.168.73.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::af0e:a936:d997:18da/64 scope link noprefixroute
       valid_lft forever preferred_lft forever

在浏览器中访问vip,可以看到我们访问的是master上的web地址

五、需要注意的问题:

1 脑裂介绍

在高可用系统中,如果两个节点的心跳线断开,本来两个节点为一个整体、动作协调的一个HA系统,现在由于两个之间的心跳线断开导致它们分裂成了两个单独的个体。由于双方互相失去了联系,都会以为对方出了故障。这时候这两个单独的个体就像"脑裂人"一样互相争抢共享资源、争用应用服务,这样就会造成严重问题:

1.1 产生脑裂的原因

一般来说,脑裂的发生,有以下几种原因:

1.2 常见的解决办法

在实际环境中,我们可以从以下几个方面来防止脑裂的问题:

1.3 Keepalived监控nginx防止脑裂

(1)执行脚本,用来检测

[root@zdd211-11 ~]# vim /etc/keepalived/check_keepalived.sh
#!/bin/bash
NGINX_SBIN="which nginx"
NGINX_PORT=80
function check_nginx(){
     NGINX_STATUS="nmap localhost -p ${NGINX_PORT} | grep "80/tcp open" | awk '{print $2}'"
     NGINX_PROCESS="ps -ef | grep nginx|grep -v grep|wc -l"
}
check_nginx
if [ "$NGINX_STATUS" != "open"  -o  $NGINX_PROCESS -lt 2 ]
then
    ${NGINX_SBIN} -s stop
    ${NGINX_SBIN}
    sleep 3
    check_nginx
    if [ "$NGINX_STATUS" != "open"  -o  $NGINX_PROCESS -lt 2 ];then
        systemctl stop keepalived
    fi
 fi
 [root@localhost ~]# chmod  +x /etc/keepalived/check_port.sh

(2)安装nmap 因为上面脚本有用到这个工具,因此两个主机都需要安装

[root@localhost ~]# yum install nmap -y

(3) 修改master配置

[root@localhost ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
   router_id 192.168.73.136
}
vrrp_script chk_nginx {
    script "/etc/keepalived/check_port.sh 80"
    interval 2
    weight -20
}
vrrp_script chk_nginx {
    script "/etc/keepalived/check_keepalive.sh" # 脚本路径
    interval 2                                  # 执行时间间隔
    weight -5                                   # 计算权重值,脚本结果导致的优先级变更,检测失败(脚本返回非0)则优先级 -5
    fall 3                                      # 检测连续3次失败才算确定是真失败。会用weight减少优先级(1-255之间)
    rise 2                                      # 检测2次成功就算成功。但不修改优先级
vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 251
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 11111111
    }
    track_script {
         chk_nginx
    }
    virtual_ipaddress {
        192.168.73.100
    }
}

(4) 修改Slave配置配置

! Configuration File for keepalived
global_defs {
        router_id 192.168.73.135
}
vrrp_script chk_nginx {
    script "/etc/keepalived/check_keepalive.sh"
    interval 2                     # 执行时间间隔
    weight -5                      # 计算权重值,脚本结果导致的优先级变更,检测失败(脚本返回非0)则优先级 -5
    fall 3                         # 检测连续3次失败才算确定是真失败。会用weight减少优先级(1-255之间)
    rise 2                         # 检测2次成功就算成功。但不修改优先级
vrrp_instance VI_1 {
        state BACKUP
        interface ens33
        virtual_router_id 251
        priority 90
        advert_int 1
        authentication {
                auth_type PASS
                auth_pass 11111111
        }
        track_script {
                chk_nginx
        }
        virtual_ipaddress {
                192.168.73.100
        }
}

2 Keepalived设置故障恢复后不重新抢回VIP

通常生产环境是不允许VIP来回漂移,当主机的业务出问题之后,vip漂移到备机上保证业务不中断,就算故障恢复keepalived也不会把vip切到主机上;

需要进行对应的问题问题,确认主机环境没有问题之后手动重启主机上keepalived服务,让vip切回到主机上。 为

了满足这样的业务场景,可以使用nopreempt参数,不抢占VIP的机制实现 修改master配置如下

[root@localhost ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
   router_id 192.168.73.136
}
vrrp_script chk_nginx {
    script "/etc/keepalived/check_keepalive.sh" # 脚本路径
    interval 2                                  # 执行时间间隔
    weight -5                                   # 计算权重值,脚本结果导致的优先级变更,检测失败(脚本返回非0)则优先级 -5
    fall 3                                      # 检测连续3次失败才算确定是真失败。会用weight减少优先级(1-255之间)
    rise 2                                      # 检测2次成功就算成功。但不修改优先级
}
vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 251
    priority 100
    advert_int 1
    nopreempt    ##不抢VIP 机制
    authentication {
        auth_type PASS
        auth_pass 11111111
    }
    track_script {
         chk_nginx
    }
    virtual_ipaddress {
        192.168.73.100
    }
}

可以自己重启keepalived,然后停止web,然后再启动web,验证是否能够自动漂移回主机

3 组播地址冲突问题

当在同一个局域网内部署了多组keepalived服务器时,可能会发生高可用接管的严重故障问题。 因为keepalived高可用功能是通过VRRP协议实现的,VRRP协议默认通过IP多播的形式实现高可用对之间的通信,如果同一个局域网内存在多组Keepalived服务器对,就会造成IP多播地址冲突问题,导致接管错乱. 不同组的keepalived都会使用默认的224.0.0.18作为多播地址。此时的解决办法是,在同组的keepalived服务器所有的配置文件里指定独一无二的多播地址,配置如下:

global_defs
{
  ``router_id LVS_19
  ``vrrp_mcast_group4 224.0.0.19` `#指定多播地址
}

以上就是keepalived对nginx进行高可用搭建及原理详解的详细内容,更多关于keepalived搭建nginx的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文