1. 程式人生 > >docker 部署nginx 使用keepalived 部署高可用

docker 部署nginx 使用keepalived 部署高可用

一.體系架構

在Keepalived + Nginx高可用負載均衡架構中,keepalived負責實現High-availability (HA) 功能控制前端機VIP(虛擬網路地址),當有裝置發生故障時,熱備伺服器可以瞬間將VIP自動切換過來,實際執行中體驗只有2秒鐘切換時間,DNS服務可以負責前端VIP的負載均衡。
nginx負責控制後端web伺服器的負載均衡,將客戶端的請求按照一定的演算法轉發給後端Real Server處理,而Real Server將響應直接返回給客戶端。
Centos 7部署docker+nginx+keepalived實現高可用web叢集

二.簡單原理

NGINX_MASTER、NGINX_BACKUP兩臺伺服器均通過keepalived軟體把ens32網絡卡綁上一個虛擬IP(VIP)地址192.168.2.242,此VIP當前由誰承載著服務就繫結在誰的ens32上,當NGINX_MASTER發生故障時,NGINX_BACKUP會通過/etc/keepalived/keepalived.conf檔案中設定的心跳時間advert_int 1檢查,無法獲取NGINX_MASTER正常狀態的話,NGINX_BACKUP會瞬間繫結VIP來接替nginx_master的工作,當NGINX_MASTER恢復後keepalived會通過priority引數判斷優先權將虛擬VIP地址192.168.2.242重新繫結給NGINX_MASTER的ens32網絡卡。
使用此方案的優越性


1.實現了可彈性化的架構,在壓力增大的時候可以臨時新增web伺服器新增到這個架構裡面去;
2.upstream具有負載均衡能力,可以自動判斷後端的機器,並且自動踢出不能正常提供服務的機器;
3.相對於lvs而言,正則分發和重定向更為靈活。而Keepalvied可保證單個nginx負載均衡器的有效性,避免單點故障;
4.用nginx做負載均衡,無需對後端的機器做任何改動。
5.nginx部署在docker容器裡,即大量地節約開發、測試、部署的時間,又可以在出現故障時通過映象快速恢復業務。

三、系統環境

兩臺負載機器安裝:centos7.5+docker+nginx+keepalived,分別命名為:NGINX_MASTER,NGINX_BACKUP。
後端web伺服器,可以是提供web服務的任何架構,分別命名為:WEB_1,WEB_2。
後端資料庫機器可任意架構,只要能提供資料庫服務即可。

伺服器 作業系統 IP地址 安裝軟體
NGINX_MASTER Centos 7.5 64位 192.168.2.228 docker+nginx+keepalived
NGINX_BACKUP Centos 7.5 64位 192.168.2.229 docker+nginx+keepalived
WEB_1 Centos 7.5 64位 192.168.2.226 docker+apache+php
WEB_2 Centos 7.5 64位 192.168.2.227 docker+apache+php
資料庫叢集 Centos 7.5 64位   mysql叢集

四、web伺服器部署

web伺服器我這裡用的是LAMP架構,具體的安裝部署請參考我的另一篇博文《Centos 7使用docker部署LAMP搭建wordpress部落格系統》,http://blog.51cto.com/andyxu/2177116

五、安裝配置nginx

分別在NGINX_MASTER、NGINX_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
(2)複製nginx主配置檔案到本地

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

(4)建立執行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:latest

注:--restart=always是重啟策略,當docker服務重啟後,容器也會自動啟動
(5)啟動nginx容器
sh docker_nginx.sh
(6)修改nginx主配置檔案
vim /data/docker/nginx/conf/nginx.conf

user  nginx;
worker_processes  4;   #工作程序數,為CPU的核心數或者兩倍

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虛擬主機配置檔案目錄 }

(7)建立upstream配置檔案
vim /data/docker/nginx/conf/conf.d/myhost.conf

upstream xuad {
  ip_hash;  #會話保持
  server 192.168.2.226  max_fails=1 fail_timeout=60s;
  server 192.168.2.227  max_fails=1 fail_timeout=60s;
}

(8)建立虛擬主機配置檔案
vim /data/docker/nginx/conf/conf.d/xuad.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://xuad; } # 檢視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 }

(9)重啟nginx容器
docker restart nginx

六、安裝配置keepalived

分別在NGINX_MASTER、NGINX_BACKUP兩臺伺服器上操作
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 {
   notification_email {
     [email protected]
   }
   notification_email_from [email protected]
   smtp_server mail.xuad.com
   smtp_connect_timeout 30
   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 ens32 virtual_router_id 51 priority 100 #備份服務上將100改為小於100,可配置成90 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.2.242 #有多個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服務,然後NGINX_BACKUP主機會自動接替NGINX_MASTER的工作。
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、當NGINX_MASTER、NGINX_BACKUP伺服器nginx均正常工作時
在NGINX_MASTER上:
Centos 7部署docker+nginx+keepalived實現高可用web叢集
在NGINX_BACKUP上:
Centos 7部署docker+nginx+keepalived實現高可用web叢集
master伺服器ens32網絡卡正常繫結VIP,而backup卻沒有繫結,通過瀏覽器可正常訪問網站。
2、關閉NGINX_MASTER的nginx容器
Centos 7部署docker+nginx+keepalived實現高可用web叢集
當nginx容器停止後,馬上就又啟起來了,nginx啟動指令碼沒問題
3、關閉NGINX_MASTER的keepalived服務
在NGINX_MASTER上:
Centos 7部署docker+nginx+keepalived實現高可用web叢集
在NGINX_BACKUP上:
Centos 7部署docker+nginx+keepalived實現高可用web叢集
NGINX_BACKUP的ens32網絡卡已瞬間繫結VIP,通過瀏覽器訪問網站正常。
4、將NGINX_MASTER的keepalived服務啟動
在NGINX_MASTER上:
Centos 7部署docker+nginx+keepalived實現高可用web叢集
在NGINX_BACKUP上:
Centos 7部署docker+nginx+keepalived實現高可用web叢集
NGINX_MASTER的ens32網絡卡重新繫結VIP,通過瀏覽器訪問網站正常。
5、關閉WEB_1伺服器,通過瀏覽器訪問網站正常。

附1:配置時間同步

1、在NGINX_MASTER和NGINX_BACKUP上安裝ntp
yum -y install ntp
2、在NGINX_MASTER上修改ntp配置檔案
新增以下兩行

server 127.127.1.0 iburst local clock #新增使用本地時間 restrict 192.168.2.0 mask 255.255.255.0 nomodify #允許更新的IP地址段

3、在NGINX_MASTER上啟動ntp服務,並加入開機啟動

systemctl start ntpd
systemctl enable ntpd

4、在NGINX_MASTER上新增防火牆策略
只允許192.168.2.229訪問ntp服務

firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.2.229" port protocol="udp" port="123" accept" firewall-cmd --reload

5、在NGINX_BACKUP上同步NGINX_MASTER的時間
ntpdate 192.168.2.228
Centos 7部署docker+nginx+keepalived實現高可用web叢集
6、在NGINX_BACKUP上設定計劃任務,每天凌晨5點01分同步時間

crontab -e
1 5 * * * /usr/sbin/ntpdate 192.168.2.228 >> /var/log/upClock.log
©著作權歸作者所有:來自51CTO部落格作者xuad88的原創作品,如需轉載,請註明出處,否則將追究法律責任