Nginx+Keepalive builds load balancing and high availability

1, Prepare

  • 10.117.201.80 and 10.117.201.81 two physical machines

2, Installation

  • Skip the installation of Nginx. 80 and 81 need to be installed here. Refer to the previous installation documents

  • The above two physical machines should be installed

  • Download keepalived-2.0.15 tar. gz

  • Unzip to / usr/local /

    tar -xf  keepalived-2.0.15.tar.gz
    mv keepalived-2.0.15 keepalived
    cd keepalived
    ./configure
    make
    

    Throw exception

    *** WARNING - this build will not support IPVS with IPv6. Please install libnl/libnl-3 dev libraries to support IPv6 with IPVS.
    

    solve

    yum -y install libnl libnl-devel
    

    Recheck the configuration/ configure

    Compile make

    Throw exception error

     cd . && /bin/sh /data/keepalived-2.0.19/missing automake-1.15 --foreign Makefile
    /data/keepalived-2.0.19/missing: line 81: automake-1.15: command not found
    WARNING: 'automake-1.15' is missing on your system.
             You should only need it if you modified 'Makefile.am' or
             'configure.ac' or m4 files included by 'configure.ac'.
             The 'automake' program is part of the GNU Automake package:
             <http://www.gnu.org/software/automake>
             It also requires GNU Autoconf, GNU m4 and Perl in order to run:
             <http://www.gnu.org/software/autoconf>
             <http://www.gnu.org/software/m4/>
             <http://www.perl.org/>
    make: *** [Makefile.in] Error 127
    

    solve

    yum install automake -y
    autoreconf -ivf
     Execute again make
    make install
    

    View startup file

    [root@mon-longi system]# pwd
    /usr/lib/systemd/system
    [root@mon-longi system]# vi keepalived.service
    [Unit]
    Description=LVS and VRRP High Availability Monitor
    After= network-online.target syslog.target
    Wants=network-online.target
    
    [Service]
    Type=forking
    PIDFile=/var/run/keepalived.pid
    KillMode=process
    EnvironmentFile=-/usr/local/etc/sysconfig/keepalived
    ExecStart=/usr/local/sbin/keepalived $KEEPALIVED_OPTIONS
    ExecReload=/bin/kill -HUP $MAINPID
    
    [Install]
    WantedBy=multi-user.target
    

    View the keepalived profile

    [root@mon local]# whereis keepalived.conf
    keepalived: /usr/local/sbin/keepalived /usr/local/etc/keepalived /usr/local/keepalived
    [root@mon local]# cd etc/keepalived/
    [root@mon keepalived]# ll
     Total consumption 8
    -rw-r--r-- 1 root root 3550 4 June 20-14:24 keepalived.conf
    drwxr-xr-x 2 root root 4096 4 June 20-14:24 samples
    [root@mon keepalived]# vi keepalived.conf
    

    81 master node configuration file interpretation kept Conf, path / usr / local / etc / kept

    ! Configuration File for keepalived
    #global variable
    global_defs {
       #addressee
       notification_email {
         xxx@163.com
       }
       #Mail sender
       notification_email_from Alexandre.Cassen@firewall.loc
       #Mail server address
       smtp_server 192.168.200.1
       #Timeout
       smtp_connect_timeout 30
       #Route ID note router here_ ID is the load balancing ID, which should be unique in the LAN
       router_id lvs_81
    }
    
    vrrp_script check_ngx { #Method, need and VI_ Track in 1_ Corresponding method name in script
       script "/usr/local/etc/keepalived/check_ngx.sh" #Location of execution file              
       interval 1  #time interval                
    }
    #Identifier of the virtual route
    vrrp_instance VI_1 {
        #There are only two statuses: MASTER and BACKUP, which should be capitalized. MASTER is in working status and BACKUP is in standby status         
        state MASTER
        #Network interface used for communication
        interface eth0
        #The ID number of the virtual route is the last address of the virtual route MAC
        virtual_router_id 51
        #The priority of this node and the primary node should be higher than other nodes
        priority 100
        #Notification interval
        advert_int 1
        #Authentication configuration
        authentication {
            #Authentication mode
            auth_type PASS
            #Authentication password
            auth_pass 1111
        }
        #There can be multiple virtual ip addresses, each of which occupies one line and does not need a subnet mask. At the same time, this ip must be consistent with the vip we set on the lvs client    
        virtual_ipaddress {
            10.117.201.88/32 --Set it yourself
        }
        track_script { #Configure the method to be executed
          check_ngx   #Method name
        }
    }
    }
    
    

    80 standby nodes kept Conf configuration file parsing

    ! Configuration File for keepalived
    #global variable
    global_defs {
       #addressee
       notification_email {
         xxx@163.com
       }
       #Mail sender
       notification_email_from Alexandre.Cassen@firewall.loc
       #Mail server address
       smtp_server 192.168.200.1
       #Timeout
       smtp_connect_timeout 30
       #Route ID note router here_ ID is the load balancing ID, which should be unique in the LAN
       router_id lvs_80
     
    }
    vrrp_script check_ngx { #Method, need and VI_ Track in 1_ Corresponding method name in script
       script "/usr/local/etc/keepalived/check_ngx.sh" #Location of execution file            
       interval 1  #time interval                
    }
    
    #Identifier of the virtual route
    vrrp_instance VI_1 {
        #There are only two statuses: MASTER and BACKUP, which should be capitalized. MASTER is in working status and BACKUP is in standby status         
        state BACKUP
        #Network interface used for communication
        interface eth0
        #The ID number of the virtual route is the last address of the virtual route MAC
        virtual_router_id 51
        #The priority of this node and the primary node should be higher than other nodes
        priority 50
        #Notification interval
        advert_int 1
        #Authentication configuration
        authentication {
            #Authentication mode
            auth_type PASS
            #Authentication password
            auth_pass 1111
        }
        #There can be multiple virtual ip addresses, each of which occupies one line and does not need a subnet mask. At the same time, this ip must be consistent with the vip we set on the lvs client    
        virtual_ipaddress {
            10.117.201.88/32
        }
        track_script { #Configure the method to be executed
          check_ngx   #Method name
        }
    }
    }
    
    

    Start to see the effect

    [root@mon keepalived]# systemctl start keepalived.service
    [root@mon keepalived]# ps -ef|grep keep
    root      609038       1  0 11:00 ?        00:00:00 /usr/local/sbin/keepalived -f /usr/local/etc/keepalived/keepalived.conf -D -S 0
    root      609039  609038  0 11:00 ?        00:00:00 /usr/local/sbin/keepalived -f /usr/local/etc/keepalived/keepalived.conf -D -S 0
    root      609040  609038  0 11:00 ?        00:00:01 /usr/local/sbin/keepalived -f /usr/local/etc/keepalived/keepalived.conf -D -S 0
    root      645454  639793  0 11:55 pts/1    00:00:00 grep --color=auto keep
    

    Check whether the virtual ip is generated

    [root@mon 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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 52:54:00:4d:d6:c0 brd ff:ff:ff:ff:ff:ff
        inet 10.117.201.81/24 brd 10.117.201.255 scope global eth0
           valid_lft forever preferred_lft forever
        inet 10.117.201.88/32 scope global eth0 --fictitious ip Already generated
           valid_lft forever preferred_lft forever
        inet6 fe80::5054:ff:fe4d:d6c0/64 scope link 
           valid_lft forever preferred_lft forever
    

    Modifying the configuration file of the standby node and starting it will not generate virtual IP. If it is generated, there is an error in the configuration file. The standby node and the primary node compete for IP resources. This phenomenon is called "brain splitting".

    [root@mon-longi 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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 52:54:00:a1:fd:3f brd ff:ff:ff:ff:ff:ff
        inet 10.117.201.80/24 brd 10.117.201.255 scope global eth0
           valid_lft forever preferred_lft forever
        inet6 fe80::5054:ff:fea1:fd3f/64 scope link 
           valid_lft forever preferred_lft forever
    

    Conduct the switching experiment of highly available primary and standby servers

    First stop the keepalived service of the primary node and check whether the standby node will generate a virtual IP: 10.117.201.88/32

    Master node run command
    [root@mon ~]# systemctl stop keepalived.service
     Standby node view virtual ip
    [root@mon-longi 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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 52:54:00:a1:fd:3f brd ff:ff:ff:ff:ff:ff
        inet 10.117.201.80/24 brd 10.117.201.255 scope global eth0
           valid_lft forever preferred_lft forever
        inet 10.117.201.88/32 scope global eth0
           valid_lft forever preferred_lft forever
        inet6 fe80::5054:ff:fea1:fd3f/64 scope link 
           valid_lft forever preferred_lft forever
    

    It can be seen from the above that the standby node does generate a virtual ip, then start the primary node, look at the virtual ip of the primary node and the standby node, and the primary node should compete back.

    Start master node
    [root@mon ~]# systemctl start keepalived.service
     View master virtual node ip
    [root@mon ~]# 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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 52:54:00:4d:d6:c0 brd ff:ff:ff:ff:ff:ff
        inet 10.117.201.81/24 brd 10.117.201.255 scope global eth0
           valid_lft forever preferred_lft forever
        inet 10.117.201.88/32 scope global eth0
           valid_lft forever preferred_lft forever
        inet6 fe80::5054:ff:fe4d:d6c0/64 scope link 
           valid_lft forever preferred_lft forever
     View standby node virtual ip
    [root@mon-longi 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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 52:54:00:a1:fd:3f brd ff:ff:ff:ff:ff:ff
        inet 10.117.201.80/24 brd 10.117.201.255 scope global eth0
           valid_lft forever preferred_lft forever
        inet6 fe80::5054:ff:fea1:fd3f/64 scope link 
           valid_lft forever preferred_lft forever
    

    The upper master node did compete for the IP back.

3, High availability with nginx

Nginx configuration: the above two physical machines should be configured with nginx. Go to the installation directory of nginx. The installation directories of 80 and 81 machines are under / application. Modify nginx Conf file.

[root@mon ~]# cd /application
[root@mon application]# ls
nginx  nginx-1.16.1
[root@mon application]# cd nginx-1.16.1/
[root@mon nginx-1.16.1]# ll
 Total consumption 0
drwx------  2 root root   6 4 October 20:19 client_body_temp
drwxr-xr-x  2 root root 333 4 June 20-17:16 conf
drwx------  2 root root   6 4 October 20:19 fastcgi_temp
drwxr-xr-x  2 root root  40 4 October 20:15 html
drwxr-xr-x  2 root root  58 4 November 21:00 logs
drwx------ 12 root root  96 4 June 20-17:22 proxy_temp
drwxr-xr-x  2 root root  19 4 October 20:15 sbin
drwx------  2 root root   6 4 October 20:19 scgi_temp
drwx------  2 root root   6 4 October 20:19 uwsgi_temp
[root@mon nginx-1.16.1]# vi conf/nginx.conf
user  root;
worker_processes  auto;
error_log  logs/error.log  error;
pid        logs/nginx.pid;

events {
    worker_connections  1024;
}
http {
    include       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  logs/access.log  main;
    sendfile        on;
    tcp_nopush     on;
    tcp_nodelay   on;   
    keepalive_timeout  65;
    upstream lvs_test {
        server 10.117.201.82:80 weight=1;
        server 10.117.201.83:80 weight=2;
    }

    server {
        listen       80;
        server_name  localhost;
        #access_log  logs/host.access.log  main;

        location / {
            proxy_set_header Host $host;
            proxy_pass http://lvs_test;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

Both machines modify the same.

Configure nginx detection script check ngx. Sh. check VI in / usr / local / etc / kept / ngx. sh

#!/bin/bash
A=`ps -C nginx --no-header |wc -l`
if [ $A -eq 0 ];then
 /application/nginx-1.16.1/sbin/nginx

 if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
        systemctl stop keepalived.service
 fi
fi
#if [ `ps aux | grep nginx | grep -v grep | wc -l` -ne 17 ];then
#systemctl stop keepalived.service
#fi

Both machines have the same configuration, except that - ne 17 in the comment section represents the sum of CPU cores of this machine + 1. 80 is 8 + 1 and 81 is 16 + 1 Actually, it's similar to nginx Worker in conf file_ Processes is related to the auto parameter. If it is set to auto, the work thread will be started according to the number of CPU cores.

The high availability of Nginx is mainly to ensure that Nginx can restart immediately after it hangs. If Nginx really can't get up, turn off kept. Achieve failover.

Let's access the configured virtual IP path.

http://10.117.201.88/

Let's test that the nginx of the 81 master node is turned off artificially. See if our self-test script works.

[root@mon ~]# ps -ef|grep nginx
root      609046       1  0 11:00 ?        00:00:00 nginx: master process /application/nginx-1.16.1/sbin/nginx
root      609047  609046  0 11:00 ?        00:00:00 nginx: worker process
root      609048  609046  0 11:00 ?        00:00:00 nginx: worker process
root      609050  609046  0 11:00 ?        00:00:00 nginx: worker process
root      609051  609046  0 11:00 ?        00:00:00 nginx: worker process
root      609052  609046  0 11:00 ?        00:00:00 nginx: worker process
root      609054  609046  0 11:00 ?        00:00:00 nginx: worker process
root      609056  609046  0 11:00 ?        00:00:00 nginx: worker process
root      609057  609046  0 11:00 ?        00:00:00 nginx: worker process
root      609058  609046  0 11:00 ?        00:00:00 nginx: worker process
root      609059  609046  0 11:00 ?        00:00:00 nginx: worker process
root      609060  609046  0 11:00 ?        00:00:00 nginx: worker process
root      609061  609046  0 11:00 ?        00:00:00 nginx: worker process
root      609062  609046  0 11:00 ?        00:00:00 nginx: worker process
root      609063  609046  0 11:00 ?        00:00:00 nginx: worker process
root      609064  609046  0 11:00 ?        00:00:00 nginx: worker process
root      609065  609046  0 11:00 ?        00:00:00 nginx: worker process
root      755929  755666  0 14:14 pts/1    00:00:00 grep --color=auto nginx
[root@mon ~]# /application/nginx-1.16.1/sbin/nginx -s stop
[root@mon ~]# ps -ef|grep nginx
root      756417       1  0 14:14 ?        00:00:00 nginx: master process /application/nginx-1.16.1/sbin/nginx
root      756418  756417  0 14:14 ?        00:00:00 nginx: worker process
root      756419  756417  0 14:14 ?        00:00:00 nginx: worker process
root      756421  756417  0 14:14 ?        00:00:00 nginx: worker process
root      756422  756417  0 14:14 ?        00:00:00 nginx: worker process
root      756424  756417  0 14:14 ?        00:00:00 nginx: worker process
root      756426  756417  0 14:14 ?        00:00:00 nginx: worker process
root      756427  756417  0 14:14 ?        00:00:00 nginx: worker process
root      756428  756417  0 14:14 ?        00:00:00 nginx: worker process
root      756429  756417  0 14:14 ?        00:00:00 nginx: worker process
root      756430  756417  0 14:14 ?        00:00:00 nginx: worker process
root      756431  756417  0 14:14 ?        00:00:00 nginx: worker process
root      756432  756417  0 14:14 ?        00:00:00 nginx: worker process
root      756433  756417  0 14:14 ?        00:00:00 nginx: worker process
root      756434  756417  0 14:14 ?        00:00:00 nginx: worker process
root      756435  756417  0 14:14 ?        00:00:00 nginx: worker process
root      756436  756417  0 14:14 ?        00:00:00 nginx: worker process
root      756482  755666  0 14:14 pts/1    00:00:00 grep --color=auto nginx

It can be seen that it will be closed immediately and take effect immediately. Because heartbeat detection is detected every second, that is, the script runs every second.

Add the following command:

systemctl stop keepalived.service stop it keepalived service
systemctl start keepalived.service open keepalived service
systemctl restart keepalived.service restart keepalived service 
systemctl status keepalived.service see keepalived Service status
/application/nginx-1.16.1/sbin/nginx -s stop stop it nginx service
/application/nginx-1.16.1/sbin/nginx start-up nginx service
/application/nginx-1.16.1/sbin/nginx -s reload restart nginx service

Common error References: Solve the problem of "fail to start LVS and VRRP Availability Monitor" started by kept

Keywords: Load Balance Nginx keepalived

Added by vanzkee on Thu, 17 Feb 2022 20:24:19 +0200