4

使用Docker-compose搭建nginx-keepalived双机热备来实现高可用nginx集群

 1 year ago
source link: https://v3u.cn/a_id_117
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

使用Docker-compose搭建nginx-keepalived双机热备来实现高可用nginx集群

首页 - Mac & Linux/2019-10-18

    最近同学出去面试经常会被问到一个问题。

    面试官:你说你们公司使用nginx反向代理tornado,部署了多少多少台机器,好像很牛逼的样子,但是我问你,如果主机也就是部署了nginx那台机器并发过大导致宕机了怎么办?

    答曰:不考虑带宽峰值的话,比较新的 CPU 跑 nginx 单核每秒能接近 2 万请求,而且nginx如果纯做 HTTP 转发的话,Nginx 的性能高到恐怖,会挂掉很不科学。。。。

    面试官:好吧,算你会忽悠,那如果插头被扫地大妈踢掉了怎么办,因为没电导致服务器宕机

    答曰:阿里云机房会断电。。。你特么在逗我吧。。

    其实负责转发的主机宕机概率很小,但是绝对不是没有,任何事都不是绝对,所谓的高可用架构就是体现在容灾机制上,如果主机宕机我们必须要做预案,万无一失才叫高可用架构,这里我们使用docker-compose来部署nginx-keepalived双机热备机制,vip主机可以进行漂移,这样主机挂掉了,还有备用机可以顶上

    Keepalived是Linux下面实现VRRP备份路由的高可靠性运行件。基于Keepalived设计的服务模式能够真正做到主服务器和备份服务器故障时IP瞬间无缝交接。二者结合,可以构架出比较稳定的软件LB方案。

    简单点说,就是keepalived可以将下面这种简单的负载均衡模式

    

20191018001744_76893.png

    改造成下面这种高可用的架构

    

20191018001813_79219.png

    当有主机挂掉的时候,服务能瞬间切换到备用机

    首先,安装docker和docker-compose按下不表,可以参考这篇文章,在centos7.6上利用docker-compose统一管理容器和服务    

    建立nginx_keepalived文件夹

    建立Dockerfile文件,这里我们使用alpine作为基础镜像,原因很简单,因为它体积小啊

FROM nginx:1.13.5-alpine

RUN apk update && apk upgrade

RUN apk add --no-cache bash curl ipvsadm iproute2 openrc keepalived && 
    rm -f /var/cache/apk/* /tmp/*

COPY entrypoint.sh /entrypoint.sh

RUN chmod +x /entrypoint.sh

CMD ["/entrypoint.sh"]

     然后建立docker-compose.yml文件,这里我们仿照线上环境,部署一台主机和一台从机,分别安装nginx

version: "3"
services:
  nginx_master:
    build:
      context: ./
      dockerfile: ./Dockerfile
    volumes:
      - ./index-master.html:/usr/share/nginx/html/index.html
      - ./favicon.ico:/usr/share/nginx/html/favicon.ico
      - ./keepalived-master.conf:/etc/keepalived/keepalived.conf
    networks:
      static-network:
        ipv4_address: 172.20.128.2
    cap_add: 
      - NET_ADMIN
  nginx_slave:
    build:
      context: ./
      dockerfile: ./Dockerfile
    volumes:
      - ./index-slave.html:/usr/share/nginx/html/index.html
      - ./favicon.ico:/usr/share/nginx/html/favicon.ico
      - ./keepalived-slave.conf:/etc/keepalived/keepalived.conf
    networks:
      static-network:
        ipv4_address: 172.20.128.3
    cap_add: 
        - NET_ADMIN
  proxy:
    image: haproxy:1.7-alpine
    ports:
      - 8000:6301
    volumes:
      - ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg
    networks:
      - static-network

networks:
  static-network:
    ipam:
      config:
        - subnet: 172.20.0.0/16

     随后,撰写nginx配置文件,keepalived-master.conf 这里由于我们没有后端tornado服务,所以使用虚拟代理服务

vrrp_script chk_nginx {
    script "pidof nginx"
    interval 2
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 33
    priority 200
    advert_int 1
    unicast_src_ip 172.20.128.2
    unicast_peer {
        172.20.128.3
    }
    
    authentication {
        auth_type PASS
        auth_pass letmein
    }
    
    virtual_ipaddress {
        172.20.128.4/24 dev eth0
    }

    track_script {
        chk_nginx
    }
}

    同理再复制一份从机的nginx配置keepalived-slave.conf

vrrp_script chk_nginx {
    script "pidof nginx"
    interval 2
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 33
    priority 100
    advert_int 1
    unicast_src_ip 172.20.128.3
    unicast_peer {
        172.20.128.2
    }
    
    authentication {
        auth_type PASS
        auth_pass letmein
    }
    
    virtual_ipaddress {
        172.20.128.4/24 dev eth0
    }
    
    track_script {
        chk_nginx
    }
}

    随后为后端服务做两个网页,一个主机index-master.html一个从机index-slave.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>主机</title>
<style>

#box{ 
    margin: 0px auto;
    font-family: 'Times New Roman', Times, serif; 
    font-size: 30px;
    font-style: initial;
    color: aliceblue;
    }

body{
    background-color: black
}

</style>
</head>
<body>

    <div id="box">

        主机

    </div>
    
</body>
</html>

     从机的复制一份,将主机改成从机即可

     因为我们要模拟后台服务,所以需要haproxy.cfg配置文件

global
    log 127.0.0.1 local0
    maxconn 4096
    daemon
    nbproc 4

defaults
    log 127.0.0.1 local3
    mode http
    option dontlognull
    option redispatch
    retries 2
    maxconn 2000
    balance roundrobin
    timeout connect 5000ms
    timeout client 5000ms
    timeout server 5000ms

frontend main
    bind *:6301
    default_backend webserver

backend webserver
    server ngxin_master 172.20.128.4:80 check inter 2000 rise 2 fall 5

     最后,撰写服务的shell脚本entrypoint.sh

#!/bin/sh

/usr/sbin/keepalived -n -l -D -f /etc/keepalived/keepalived.conf --dont-fork --log-console &

nginx -g "daemon off;"

    整个项目结构如下:

    

20191018003404_17382.png

    现在我们来启动容器集群,输入命令:docker-compose up

    发现容器已经启动

    

20191018003503_34389.png

    另外一个命令行,输入:docker ps

    

20191018003541_88696.png

    可以看到,后台分别三个容器正在启动,两台nginx反向代理8000端口的后台服务,访问 localhost:8000

    

20191018003725_19549.png

    现在我们来模仿一下nginx主机宕机的情况

docker pause nginx_keepalive_nginx_master_1

   再次访问 localhost:8000

    发现已经自动无缝切换到备用机,整个过程非常流畅

    

20191018003915_99804.png

    高可用架构的特性就体现在这里,所以在面试中,对于面试官提出的问题要不断的总结,对于不熟悉不知道的问题,一定要深入研究一下,这样才可以在面试中无往而不胜。

    最后附上项目地址:https://gitee.com/QiHanXiBei/nginx_keepalive


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK