Nginx+Keepalived高可用

Keepalived 是一种高性能的服务器高可用或热备解决方案, Keepalived 可以用来防止服务器单点故障的发生,通过配合 Nginx 可以实现 web 前端服务的高可用。

Keepalived 以 VRRP 协议为实现基础。 VRRP(Virtual RouterRedundancy Protocol)协议是用于实现路由器冗余的协议, 它将两台或多台路由器设备虚拟成一个设备,对外提供虚拟路由器 IP(一个或多个),而在路由器组内部,如果实际拥有这个对外 IP 的路由器如果工作正常就是 MASTER,或者是通过算法选举产生, MASTER 实现针对虚拟路由器 IP 的各种网络功能,其他设备不拥有该虚拟 IP,状态是 BACKUP,除了接收 MASTER 的VRRP 状态通告信息外,不执行对外的网络功能。

当主机失效时, BACKUP 将接管原先 MASTER 的网络功能。VRRP 协议使用多播数据来传输 VRRP 数据, VRRP 数据使用特殊的虚拟源 MAC 地址发送数据而不是自身网卡的 MAC 地址, VRRP 运行时只有 MASTER 路由器定时发送 VRRP 通告信息,表示 MASTER 工作正常以及虚拟路由器 IP(组), BACKUP 只接收 VRRP 数据,不发送数据,如果一定时间内没有接收到 MASTER 的通告信息,各 BACKUP 将宣告自己成为 MASTER,发送通告信息,重新进行 MASTER 选举状态。

安装nginx

$ cd /usr/local/src/
$ wget http://nginx.org/download/nginx-1.13.0.tar.gz
$ tar -zxvf nginx-1.13.0.tar.gz
$ cd nginx-1.13.0
$ ./configure --prefix=/usr/local/nginx
$ make && make install

安装完成后,检查并连接nginx

# /usr/local/nginx/sbin/nginx -v
nginx version: nginx/1.13.0
# ln /usr/local/nginx/sbin/nginx /usr/local/bin/

连接完成后就可以直接使用命令nginx

配置nginx.conf,模拟简单的负载均衡,这里采用baidu和360两个地址做测试。
修改/usr/local/nginx/conf/nginx.conf文件,参照下面的内容。

worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    gzip  on;
   
    upstream  api  {
        server   61.135.169.121:80 max_fails=1; #baidu.com
        server   42.236.9.70:80 max_fails=1;  #so.com
    }

    server {
        listen  80;
        location / {
        proxy_next_upstream error timeout http_500 http_502 http_504;
                proxy_read_timeout 10s;
                proxy_pass        http://api;
                proxy_set_header   Host             $host;
                proxy_set_header   X-Real-IP        $remote_addr;
                proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
    }
    }
}

修改完了,重启nginx,nginx -s reload
然后在浏览器上输入对应机器的IP,此时应该看到地址切换效果。

防火墙开放端口
若不能访问此机器,则可能是防火墙没有开放80端口,可以打开端口或关闭防火墙
下面我们打开80端口

firewall-cmd --list-all #检查 80 端口
firewall-cmd --zone=public --add-port=80/tcp  #开放80端口
firewall-cmd --reload

安装keepalived

$ yum -y install keepalived

这样安装版本较低,下载最新版http://www.keepalived.org/download.html

设置 keepalived 服务开机启动

$ chkconfig keepalived on

配置/etc/keepalived/keepalived.conf,加上以下内容:

global_defs {
    #这里发邮件只对内网
    notification_email {
      xxx@qq.com #邮件报警
    }
    notification_email_from xxx@163.com #指定发件人
    smtp_server smtp.163.com   #指定smtp服务器地址
    smtp_connect_timeout 30    #指定smtp连接超时时间
    router_id LVS_DEVEL  #负载均衡标识,在局域网内应该是唯一的。
}

vrrp_script chk_nginx {
    script "/etc/keepalived/nginx_check.sh"
    #每2秒检测一次nginx的运行状态
    interval 2
    #失败一次,将自己的优先级调整为-20
    weight  -20
}

# virtual_ipaddress vip
# vrrp-虚拟路由冗余协议
# vrrp_instance 用来定义对外提供服务的VIP区域及其相关属性
vrrp_instance VI_1 {
    state BACKUP #指定该keepalived节点的初始状态
    interface enp0s3 #@@vrrp实例绑定的接口,用于发送VRRP包
    virtual_router_id 51 #取值在0-255之间,用来区分多个instance的VRRP组播, 同一网段中该值不能重复,并且同一个vrrp实例使用唯一的标识
    priority 150 #@@指定优先级,优先级高的将成为MASTER
    nopreempt #设置为不抢占。默认是抢占的
    authentication {
        auth_type PASS
        auth_pass 11111
    }
    ###采用单播通信,避免同一个局域网中多个keepalived组之间的相互影响
    unicast_src_ip 172.19.165.254  ##@@本机ip
    unicast_peer { #@@采用单播的方式发送VRRP通告,指定单播邻居的IP地址
        172.19.165.222
    }
    virtual_ipaddress { #@@指定VIP地址
        172.19.165.251
    }
    #nginx存活状态检测脚本
    track_script {
        chk_nginx
    }
    #提示如:I'm the MASTER! Whup whup
    notify "/container/service/keepalived/assets/notify.sh"
    #节点变为master时执行
    notify_master "/etc/keepalived/send_mail.sh"
}
vrrp_instance VI_2 {
    state BACKUP
    interface enp0s3
    virtual_router_id 52
    priority 99
    nopreempt
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    ###采用单播通信,避免同一个局域网中多个keepalived组之间的相互影响
    unicast_src_ip 172.19.165.254  ##本机ip
    unicast_peer { #采用单播的方式发送VRRP通告,指定单播邻居的IP地址
        172.19.165.222
    }
    virtual_ipaddress {
         172.19.165.252
    }
    #nginx存活状态检测脚本
    track_script {
        chk_nginx
    }
    notify "/container/service/keepalived/assets/notify.sh"
    #节点变为master时执行
    notify_master "/etc/keepalived/send_mail.sh"
}

注意,标@@的地方是要修改的。

同时,我们还需要2个脚本,一个用来监视nginx,另一个用来发送报警邮件。
nginx_check.sh

#!/bin/bash  
A=`ps -C nginx -no-header |wc -l`
if [ $A -eq 1 ];then
        pkill keepalived
fi

send_mail.sh

#!/usr/bin/perl -w  
use Net::SMTP_auth;
use strict;
#smtp服务器
my $mailhost = 'smtp.163.com';
#发送邮件的邮箱
my $mailfrom = 'xxx@163.com';
#接收邮件的邮箱
my @mailto   = ('xxx@qq.com');
#邮件主题
my $subject  = 'keepalived up on backup';
#邮件正文
my $text = "正文\n nginx-1服务器宕机!!nginx-2变为master!!!";
#发送邮件的用户名
my $user   = 'xxx@163.com';
#发送邮件的邮箱--163授权码
my $passwd = 'xxx';
&SendMail();
##############################
# Send notice mail
##############################
sub SendMail() {
    my $smtp = Net::SMTP_auth->new( $mailhost, Timeout => 120, Debug => 1 )
      or die "Error.\n";
    $smtp->auth( 'LOGIN', $user, $passwd );
    foreach my $mailto (@mailto) {
        $smtp->mail($mailfrom);
        $smtp->to($mailto);
        $smtp->data();
        $smtp->datasend("To: $mailto\n");
        $smtp->datasend("From:$mailfrom\n");
        $smtp->datasend("Subject: $subject\n");
        $smtp->datasend("\n");
        $smtp->datasend("$text\n\n");
        $smtp->dataend();
    }
    $smtp->quit;
}

给这2个脚本添加执行权限

# chmod +x send_mail.sh  nginx_check.sh

注意,调用的send_mail.sh脚本为使用Perl编写的,需要安装环境:

$ yum -y install perl-CPAN
$ cpan Net::SMTP_auth

写完脚本,可以直接测试发邮件,执行./send_mail.sh

重启keepalived服务,则可发现接收到相关邮件提醒,因为state发生改变。

$ service keepalived restart

同样的方式,再部署另一台,依次修改的地方为:

  • interface
  • priority(减1)
  • unicast_src_ip
  • unicast_peer
    修改完成后,重启服务。

验证keepalived高可用
在浏览器上输入虚拟IP,如输入http://172.19.165.251会自动切换到MASTER的机器上,可以查看虚拟IP绑定在哪台机器上,输入 命令ip addr

image.png

可以看到MASTER真实IP下面绑定了2个虚拟IP
再看下SLAVE有没有绑定虚拟IP
image.png

从图上看到SLAVE上并没有绑定虚拟IP

当关掉MASTER,可以收到相关邮件

[root@localhost ~]# nginx -s stop

然后,也看到虚拟IP绑定也发生了改变。


image.png

image.png

当MASTER再次启动,由于是非抢占模式,所以它仍然是BACKUP状态。
keepalived也要启动

systemctl start keepalived
#service keepalived start

注意,上面的nginx_check.sh会关闭keepalived,当nginx停止时keepalived也会停止,所以启动nginx也要一起启动keepalived.

keepalived不能自动切换原因

  1. 查看keepalived是否启动
    ps -ef|grep keepalived
  2. 防火墙放行keepalived
    centos7是firewall,之前的是iptables
# firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 \
  --in-interface enp0s8 --destination 172.19.165.222 --protocol vrrp -j ACCEPT
success
# firewall-cmd --direct --permanent --add-rule ipv4 filter OUTPUT 0 \
  --out-interface enp0s8 --destination 172.19.165.222 --protocol vrrp -j ACCEPT
success
# firewall-cmd --reload
success
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,367评论 6 512
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,959评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,750评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,226评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,252评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,975评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,592评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,497评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,027评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,147评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,274评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,953评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,623评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,143评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,260评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,607评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,271评论 2 358

推荐阅读更多精彩内容