美文网首页java高级开发
Nginx+Keepalived高可用

Nginx+Keepalived高可用

作者: 老鼠AI大米_Java全栈 | 来源:发表于2018-11-05 10:34 被阅读14次

    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
    

    相关文章

      网友评论

        本文标题:Nginx+Keepalived高可用

        本文链接:https://www.haomeiwen.com/subject/rfykxqtx.html