龙空技术网

keepalived+nginx实现高可用web

特立独行的兔子y 347

前言:

如今你们对“nginx与keepalived”大概比较讲究,姐妹们都需要剖析一些“nginx与keepalived”的相关文章。那么小编也在网上汇集了一些关于“nginx与keepalived””的相关内容,希望同学们能喜欢,兄弟们一起来学习一下吧!

一台服务器的硬件配置总是有限的,当服务器上运行的资源超过服务器的承载能力时,必将导致该服务器崩溃。在生产环境中,多数企业会使用多台服务器搭建成一个集群来运行应用程序,这样不仅可以避免单点故障,还能提升服务器的承载能力。

腾讯的QQ软件在国内使用频繁,同时在线人数超过2亿,但我们很少发现它出现故障。这么大体量的应用,不可能在一台或者几台服务器上跑起来,而是有数以万计的服务器在QQ的后端支撑着。据不完全统计,仅QQ这项业务,几乎每天都会有若干台服务器出现故障,但这并没有影响到QQ的使用,这个技术其实就是集群。

集群从功能实现上分为两种:高可用集群和负载均衡集群。高可用,顾名思义,当一台服务器宕机不能提供服务了,还有另外的服务器顶替。就像我们刚刚提到的,QQ所使用的服务器虽然每天都有宕机的,但对于用户来讲是无感知的,并没有影响到使用。负载均衡集群,简单讲就是把用户的请求分摊到多台服务器上,QQ同时在线2亿多,它就是把众多用户分摊在了不同的服务器上,假如说一台服务器上可以承载一万人,那么一万台服务器上就可以承载1亿人。

1. 搭建高可用集群

高可用集群,即“HA集群”,也常称作“双机热备”,用于关键业务。常见实现高可用的开源软件有heartbeat和keepalived,其中keepalived还有负载均衡的功能。这两个软件类似,核心原理都是通过心跳线连接两台服务器,正常情况下由一台服务器提供服务,当这台服务器宕机,备用服务器顶替。

Keepalived 工作原理

在讲述keepalived工作原理之前,大家先来了解一个协议VRRP(Virtual Router Redundancy Protocol,虚拟路由冗余协议)。它是实现路由高可用的一种通信协议,在这个协议里会将多台功能相同的路由器组成一个小组,这个小组里会有1个master(主)角色和N(N>=1)个backup(备用)角色。工作时 master会通过组播的形式向各个backup发送VRRP协议的数据包,当backup收不到master发来的VRRP数据包时,就会认为master宕机了。此时就需要根据各个backup的优先级来决定谁成为新的master。

而keepalived就是采用这种VRRP协议实现的高可用。keepalived要有三个模块,分别是core、check和vrrp。其中core模块为keepalived的核心,负责主进程的启动、维护以及全局配置文件的加载和解析; check模块负责健康检查;vrrp模块用来实现VRRP协议。

实操

目的

准备两个节点,操作系统为centos7.2-1511,关闭防火墙、selinux,修改主机名。都安装keepalived,并分别安装源码编译安装的nginx和yum安装的nginx使他们版本不相同方便后面测试keepalived功能。

原理

准备

主机

IP

服务

master

182.168.200.11

keepalived+编译安装nginx

slave

182.168.200.12

keepalived+yum安装nginx

配置

# master节点修改配置,直接覆盖原配置[root@master ~]# vim /etc/keepalived/keepalived.confglobal_defs {         #全局配置标识,表明这个区域{}是全局配置   notification_email {        1820157360@qq.com   #表示发送通知邮件时邮件源地址是谁   }   notification_email_from root@aaaaa.com    #表示keepalived在发生诸如切换操作时需要发送email通知,以及email发送给哪些邮件地址,邮件地址可以多个,每行一个   smtp_server 127.0.0.1      #表示发送email时使用的smtp服务器地址,这里可以用本地的sendmail来实现   smtp_connect_timeout 30    #连接smtp连接超时时间   router_id LVS_DEVEL      #机器标识}vrrp_script chk_nginx {    script "/usr/local/sbin/check_ng.sh"    #检查服务是否正常,通过写脚本实现,脚本检查服务健康状态    interval 3    #检查时间间断是3秒    }vrrp_instance VI_1 {        #VRRP配置标识 VI_1是实例名称    state MASTER        #定义master相关    interface eno16777736  #通过vrrp协议去通信、去发广播。此为网卡名    virtual_router_id 51   #定义路由器ID ,配置的时候和从机器一致    priority 100   #权重,主角色和从角色的权重是不同的,一般主比从大    advert_int 1  #设定MASTER与BACKUP主机质检同步检查的时间间隔,单位为秒    authentication {        #认证相关信息        auth_type PASS      #认证类型        auth_pass 5201314>g     #密码的形式是一个字符串    }    virtual_ipaddress {     #设置虚拟IP地址 (VIP),又叫做漂移IP地址        192.168.200.100    }    track_script {       #加载脚本        chk_nginx    }}# master节点配置脚本  注意启动方式和自己的nginx安装方式是否匹配[root@master ~]# vim /usr/local/sbin/check_ng.sh#!/bin/bash                                     #时间变量,用于记录日志d=`date --date today +%Y%m%d_%H:%M:%S`#计算nginx进程数量  n=`ps -C nginx --no-heading|wc -l`#如果进程为0,则启动nginx,并且再次检测nginx进程数量    if [ $n -eq "0" ]; then    /etc/init.d/nginx start    n2=`ps -C nginx --no-heading|wc -l`#如果还为0,说明nginx无法启动,此时需要关闭keepalived        if [ $n2 -eq "0"  ]; then            echo "$d nginx down,keepalived will stop" >> /var/log/check_ng.log            systemctl stop keepalived        fifi# 授权[root@master ~]# chmod a+x /usr/local/sbin/check_ng.sh# 启动服务。发现主节点IP会多一个浮动IP [root@master ~]# systemctl start keepalived.service[root@master ~]# ip a1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN     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 forever2: eno16777736: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000    link/ether 00:0c:29:33:f6:eb brd ff:ff:ff:ff:ff:ff    inet 192.168.200.11/24 brd 192.168.200.255 scope global eno16777736       valid_lft forever preferred_lft forever    inet 192.168.200.100/32 scope global eno16777736       valid_lft forever preferred_lft forever    inet6 fe80::20c:29ff:fe33:f6eb/64 scope link        valid_lft forever preferred_lft forever# 测序是否会自动启动服务[root@master ~]# service nginx stop Stopping nginx (via systemctl):                            [  OK  ][root@master ~]# netstat -ntlpActive Internet connections (only servers)Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1470/sshd           tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      2051/master         tcp6       0      0 :::22                   :::*                    LISTEN      1470/sshd           tcp6       0      0 ::1:25                  :::*                    LISTEN      2051/master         [root@master ~]# netstat -ntlp|grep nginxActive Internet connections (only servers)Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      17580/nginx: master # 配置slave  不一样的地方主要有配置标识和权重[root@backup ~]# vim /etc/keepalived/keepalived.confglobal_defs {   notification_email {        1820157360@qq.com   }   notification_email_from root@aaaaa.com   smtp_server 127.0.0.1   smtp_connect_timeout 30   router_id LVS_DEVEL}vrrp_script chk_nginx {    script "/usr/local/sbin/check_ng.sh"    interval 3    }vrrp_instance VI_1 {    state BACKUP    interface eno16777736    virtual_router_id 51    priority 90    advert_int 1    authentication {        auth_type PASS        auth_pass 5201314>g    }    virtual_ipaddress {        192.168.200.100    }    track_script {        chk_nginx    }}[root@backup ~]# vim /usr/local/sbin/check_ng.sh#!/bin/bashd=`date --date today +%Y%m%d_%H:%M:%S`n=`ps -C nginx --no-heading|wc -l`if [ $n -eq "0" ]; then    systemctl start nginx    n2=`ps -C nginx --no-heading|wc -l`    if [ $n2 -eq "0"  ]; then        echo "$d nginx down,keepalived will stop" >> /var/log/check_ng.log        systemctl stop keepalived    fifi[root@backup ~]# chmod a+x /usr/local/sbin/check_ng.sh# 启动服务[root@backup ~]# systemctl start keepalived.service[root@backup ~]# systemctl start nginx[root@master ~]# curl -I 192.168.200.11HTTP/1.1 200 OKServer: nginx/1.17.8Date: Mon, 14 Feb 2022 15:02:04 GMTContent-Type: text/htmlContent-Length: 612Last-Modified: Mon, 14 Feb 2022 14:08:58 GMTConnection: keep-aliveETag: "620a627a-264"Accept-Ranges: bytes[root@master ~]# curl -I 192.168.200.12HTTP/1.1 200 OKServer: nginx/1.20.1Date: Mon, 14 Feb 2022 15:03:47 GMTContent-Type: text/htmlContent-Length: 4833Last-Modified: Fri, 16 May 2014 15:12:48 GMTConnection: keep-aliveETag: "53762af0-12e1"Accept-Ranges: bytes
测试

1、关闭master上的nginx服务

# 首先看VIP是否在master节点[root@master ~]# curl -I 192.168.200.100HTTP/1.1 200 OKServer: nginx/1.17.8Date: Mon, 14 Feb 2022 15:08:13 GMTContent-Type: text/htmlContent-Length: 612Last-Modified: Mon, 14 Feb 2022 14:08:58 GMTConnection: keep-aliveETag: "620a627a-264"Accept-Ranges: bytes# 可以看到nginx版本是1.17的是master节点# 故意关掉nginx ,发现很快nginx服务就会重启,不超过3秒[root@master ~]# service nginx stopStopping nginx (via systemctl):                            [  OK  ][root@master ~]# netstat -ntlpActive Internet connections (only servers)Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      33315/nginx: master 

2、在master节点上增加iptables规则

[root@master ~]# iptables -I OUTPUT -p vrrp -j DROP[root@master ~]# curl -I 192.168.200.100HTTP/1.1 200 OKServer: nginx/1.17.8Date: Mon, 14 Feb 2022 15:20:25 GMTContent-Type: text/htmlContent-Length: 612Last-Modified: Mon, 14 Feb 2022 14:08:58 GMTConnection: keep-aliveETag: "620a627a-264"Accept-Ranges: bytes[root@backup ~]# curl -I 192.168.200.100HTTP/1.1 200 OKServer: nginx/1.20.1Date: Mon, 14 Feb 2022 15:20:38 GMTContent-Type: text/htmlContent-Length: 4833Last-Modified: Fri, 16 May 2014 15:12:48 GMTConnection: keep-aliveETag: "53762af0-12e1"Accept-Ranges: bytes# 确实已经有192.168.200.100这个VIP了,可见我们已经验证成功了,但是这并不完美,因为在master上依旧有VIP,master上虽然被禁掉了VRRP协议,但它并不认为自己宕机了,所以不会释放VIP资源。如果master和backup都绑定了VIP,那么对外提供服务就会紊乱,这叫作“脑裂”,这种情况是不允许发生的。

3、关闭master上的keepalived服务

[root@master ~]# systemctl stop keepalived.service [root@master ~]# ip a1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN     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 forever2: eno16777736: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000    link/ether 00:0c:29:33:f6:eb brd ff:ff:ff:ff:ff:ff    inet 192.168.200.11/24 brd 192.168.200.255 scope global eno16777736       valid_lft forever preferred_lft forever    inet6 fe80::20c:29ff:fe33:f6eb/64 scope link        valid_lft forever preferred_lft forever[root@master ~]# curl -I 192.168.200.100HTTP/1.1 200 OKServer: nginx/1.20.1Date: Mon, 14 Feb 2022 15:27:26 GMTContent-Type: text/htmlContent-Length: 4833Last-Modified: Fri, 16 May 2014 15:12:48 GMTConnection: keep-aliveETag: "53762af0-12e1"Accept-Ranges: bytes# 发现VIP浮动到了slave# 再启动master上的keepalived# 发现还会浮动回来[root@master ~]# systemctl start keepalived.service [root@master ~]# curl -I 192.168.200.100HTTP/1.1 200 OKServer: nginx/1.17.8Date: Mon, 14 Feb 2022 15:28:37 GMTContent-Type: text/htmlContent-Length: 612Last-Modified: Mon, 14 Feb 2022 14:08:58 GMTConnection: keep-aliveETag: "620a627a-264"Accept-Ranges: bytes# 如果一台机器宕机,keeplived服务必然会停掉,所以这样去验证keepalived的高可用是没有任何问题的。

标签: #nginx与keepalived