docker+nginx+keepalived部署实现nginx高可用

一.架构

        在Keepalived + Nginx高可用负载均衡架构中,keepalived负责实现High-availability (HA) 功能控制前端机VIP(虚拟网络地址),当有设备发生故障时,热备服务器可以瞬间将VIP自动切换过来,实际运行中体验只有2秒钟切换时间,DNS服务可以负责前端VIP的负载均衡。
        nginx负责后端web服务器的负载均衡,将客户端的请求按照一定的算法转发给后端处理,后端将响应直接返回给客户端。

docker+nginx+keepalived部署实现nginx高可用_第1张图片

二.原理

        MASTER、BACKUP两台服务器均通过keepalived软件把ens33网卡绑上一个虚拟IP(VIP)地址192.168.32.88,此VIP当前由谁承载着服务就绑定在谁的ens33上,当MASTER发生故障时,BACKUP会通过/etc/keepalived/keepalived.conf文件中设置的心跳时间advert_int 1检查,无法获取MASTER正常状态的话,BACKUP会瞬间绑定VIP来接替MASTER的工作,当MASTER恢复后keepalived会通过priority(权重参数:值越大优先使用)参数判断优先权将虚拟VIP地址192.168.32.88重新绑定给MASTER的ens33网卡。

三.优点

1.实现了可弹性化的架构,在并发量大的时候可以临时添加web服务器进去;
2.upstream实现负载均衡,可以自动判断后端的机器,并且自动踢出不能正常提供服务的机器,保证后端服务高可用;
3.Keepalvied相对于lvs而言,正则分发和重定向更为灵活。而Keepalvied可避免单点故障;保证nginx高可用。
4.用nginx做负载均衡,无需对后端的机器做任何改动。
5.nginx部署在docker容器里,即大量地节约开发、测试、部署的时间,又可以在出现故障时通过镜像快速恢复业务。

三、系统环境

4台服务器。

服务器 操作系统 IP地址 安装软件
MASTER Centos 7.5 64位 192.168.32.22 docker+nginx+keepalived
BACKUP Centos 7.5 64位 192.168.32.33 docker+nginx+keepalived
WEB_1 Centos 7.5 64位 192.168.32.44 docker+springboot
WEB_2 Centos 7.5 64位 192.168.32.55 docker+springboot

 

四、操作步骤

(一)安装配置nginx

        分别在MASTER、BACKUP两台服务器上操作

1、部署docker环境
(1)安装docker
注:安装的是docker社区版本

yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum makecache fast
yum -y install docker-ce

(2)修改配置文件,添加私有仓库地址和阿里云镜像地址,并指定docker数据存储目录

mkdir -p /data/docker
mkdir -p /etc/docker
vim /etc/docker/daemon.json
{
  "registry-mirrors": ["https://registry.docker-cn.com"], "graph": "/data/docker",
  "insecure-registries": ["192.168.2.225:5000"]
}

(3)启动docker,并加入开机启动

systemctl start docker 
systemctl enable docker

2、配置nginx容器
(1)下载nginx镜像
docker pull nginx:1.14
(2)复制nginx主配置文件到本地

mkdir -p /data/docker/nginx/conf
docker run --name tmp-nginx-container -d nginx:1.14
docker cp tmp-nginx-container:/etc/nginx/nginx.conf /data/docker/nginx/conf/
docker rm -f tmp-nginx-container

(3)创建运行nginx镜像的脚本
vim docker_nginx.sh

#!/bin/bash
docker run --name nginx --restart=always -p 80:80 \
    -v /data/docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro \
    -v /data/docker/nginx/conf/conf.d:/etc/nginx/conf.d \
    -v /data/docker/nginx/html:/usr/share/nginx/html \
    -v /data/docker/nginx/logs:/var/log/nginx \
    -d nginx:1.14

注:--restart=always是重启策略,当docker服务重启后,容器也会自动启动
(4)启动nginx容器
sh docker_nginx.sh
(5)修改nginx主配置文件
vim /data/docker/nginx/conf/nginx.conf

user  nginx;
worker_processes  4;   #工作进程数,一般为cpu核心数。查看cpu核心数:grep 'core id' /proc/cpuinfo | sort -u | wc -l

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

events {
    use epoll;   #Linux最常用支持大并发的事件触发机制
    worker_connections  65535;
}

http {
    include       /etc/nginx/mime.types;   #设定mime类型,类型由mime.type文件定义
    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  120;

    #gzip  on;
    limit_conn_zone $binary_remote_addr zone=perip:10m;   #添加limit_zone,限制同一IP并发数
    include /etc/nginx/conf.d/*.conf;   #包含nginx虚拟主机配置文件目录
}

(6)创建upstream配置文件
vim /data/docker/nginx/conf/conf.d/myhost.conf

upstream loadblanceserver {
  #ip_hash;  #相同ip会路由到同一个后端服务。会话保持.
  server 192.168.32.44  max_fails=1 fail_timeout=60s;
  server 192.168.32.55  max_fails=1 fail_timeout=60s;
}

(7)创建虚拟主机配置文件
vim /data/docker/nginx/conf/conf.d/loadblanceserver.conf

server {
        listen       80; 
        server_name  localhost; 
        #charset GB2312; 

        location / 
        { 
              proxy_redirect off; 
              proxy_set_header        Host $host; 
              proxy_set_header        X-Real-IP $remote_addr;
              proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for; 
              proxy_pass http://loadblanceserver;#负载均衡。根据upstream中的配置进行路由。如果upstream 使用了ip_hash算法。则同一个ip客户端访问总是会落到一个服务中。
        } 

# 查看nginx的并发连接数配置
        location /NginxStatus
        {
             stub_status             on;
             access_log              off;
             auth_basic              "NginxStatus";
        }

        access_log  off;
        error_page 404  /404.html;
        error_page   500 502 503 504 /404.html;
        location = /404.html {
            root   html;
        }
        limit_conn perip 200;   #同一ip并发数为200,超过会返回503
}

(8)重启nginx容器
docker restart nginx

(二)安装配置keepalived

1.在线并安装keepalived
注:keepalived安装在实体机上

yum install wget make gcc gcc-c++ openssl-devel
wget http://www.keepalived.org/software/keepalived-2.0.7.tar.gz
tar zxvf keepalived-2.0.7.tar.gz
cd keepalived-2.0.7
./configure --prefix=/data/keepalived

如果报以下警告:
*** WARNING - this build will not support IPVS with IPv6. Please install libnl/libnl-3 dev libraries to support IPv6 with IPVS.

不用担心,我们只需要用到VRRP功能,不需要用IPVS功能,所以请确保以下三项是yes就行了。
Use VRRP Framework : Yes
Use VRRP VMAC : Yes
Use VRRP authentication : Yes

make
make install

2、将keepalived 以服务方式启动

mkdir /etc/keepalived
cp /data/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
systemctl enable keepalived

3、修改keepalived配置文件
vim /etc/keepalived/keepalived.conf

! Configuration File for keepalived

global_defs {
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

vrrp_script chk_nginx {
    script "/etc/keepalived/nginx_pid.sh"   # 检查nginx状态的脚本
    interval 2
    weight 3
}

vrrp_instance VI_1 {
    state MASTER     #备份服务器上将MASTER改为BACKUP
    interface ens33  #需要绑定虚拟ip的网卡
    virtual_router_id 51
    priority 100       #备份服务上将100改为小于100,可配置成50
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.32.88    #虚拟ip,有多个vip可在下面继续增加
    }
    track_script {
        chk_nginx
    }
}

4、添加检查nginx状态的脚本
vim /etc/keepalived/nginx_pid.sh

#!/bin/bash
#version 0.0.1
#
A=`ps -C nginx --no-header |wc -l`
if [ $A -eq 0 ];then
     systemctl restart docker
      sleep 3
            if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
                  systemctl stop keepalived
fi 
fi

脚本说明:当nginx进程不存在时,会自动重启docker服务,docker服务启动时会自动启动nginx容器;再次检查nginx进程,如果不存在,就停止keepalived服务,然后BACKUP主机会自动接替MASTER的工作,虚拟ip都会自动切换。
chmod +x /etc/keepalived/nginx_pid.sh
5、配置firewalld防火墙允许vrrp协议
VRRP(Virtual Router Redundancy Protocol,虚拟路由器冗余协议)

firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.2.229" protocol value="vrrp" accept"
firewall-cmd --reload

如果是backup服务器,source address改成master服务器的IP
6、启动keepalived
systemctl start keepalived

五、测试

1、当MASTER、BACKUP服务器nginx均正常工作时

输入指令:ip a

MASTER服务器:可以看到绑定的虚拟vip:192.168.32.88。通过虚拟vip可以正常访问

docker+nginx+keepalived部署实现nginx高可用_第2张图片

BACKUP服务器。ens33网卡没有绑定虚拟vip

docker+nginx+keepalived部署实现nginx高可用_第3张图片

2、停止MASTER的nginx容器 

nginx停止后马上又会启动。 说明nginx启动脚本没问题。

3、关闭MASTER的keepalived服务。(systemctl stop keepalived)

MASTER服务器:虚拟ip没有被绑定了

docker+nginx+keepalived部署实现nginx高可用_第4张图片

BACKUP服务器: 虚拟ip已切换到BACKUP服务器。若再次启动MASTER服务器的keepalived服务。vip会绑定daoMASTER中去。配置信息中(priority):MASTER的权重大于BACKUP。

docker+nginx+keepalived部署实现nginx高可用_第5张图片

4、关闭WEB_1服务器,通过浏览器访问网站正常。 

由于后端单个nginx做了负载均衡。当web_1挂了,会踢出去。继续使用web_2服务。

若两个服务都存活。会根据upstream中的配置规则进行访问。默认是轮回模式。

你可能感兴趣的