實戰 Nginx-keepalived 雙機熱備集羣

一般情況下我們會使用 Nginx 用做路由轉發或者部署我們的靜態資源,那你知道如何什麼是 Nginx 的高可用,並如何實現嗎?

哎~ 這篇文章犧牲了一個美麗的週末,各位大佬,能否給個贊,嘻嘻😝

一、Nginx 高可用

爲了屏蔽負載均衡服務器的宕機,需要建立一個備份機。主服務器和備份機上都運行高可用(High Availability)監控程序,通過傳送諸如 “Iam alive” 這樣的信息來監控對方的運行狀況。當備份機不能在一定的時間內收到這樣的信息時,它就接管主服務器的服務 IP 並繼續提供負載均衡服務;當備份管理器又從主管理器收到 “I am alive” 這樣的信息時,它就釋放服務 IP 地址,這樣的主服務器就開始再次提供負載均衡服務。

二、keepalived

Keepalived 軟件起初是專門爲 LVS(Linux Virtual Server)負載均衡軟件設計的用來管理並監控 LVS 集羣系統中各個服務節點的狀態,後來又加入了可以實現高可用的 VRRP 功能。因此,Keepalived 除了能夠管理 LVS 軟件外,還可以作爲其他服務的高可用解決方案軟件。
Keepalived 軟件主要是通過 VRRP 協議實現高可用功能的, VRRP 是 Virtual Router Redundancy Protocol(虛擬路由器冗餘協議)的縮寫. VRRP 出現的目的就是爲了解決靜態路由單點故障問題的

VRRP 原理

本文 Nginx 災備集羣便是基於 keepalived,利於其機制故障轉移特性來實現 Nginx 的高可用。

三、實操部署

1、環境說明

Nginx 在此次實驗中的定位:資源服務器

2、部署結構圖

3、實操部署

我們事先準備兩臺虛擬機,並且保證網絡暢通,如下圖:

(1)docker 安裝
如下命令可以直接安裝 docker,已經有 docker 環境的可以直接略過該步驟

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

(2)docker-nginx 安裝
兩臺服務器同時安裝 Nginx,所需的配置文件和重啓腳本我都已經準備好了,可在如下地址獲取
https://github.com/Taoey/tao-dockerfiles/tree/master/nginx

在我們的兩臺服務器上分別創建一個目錄存放如上文件,這是我的配置。注意如果 start.sh 沒有執行權限的話,可以使用chmod +x start.sh 爲我們的文件賦權

[root@192 nginx]# pwd
/root/soft/nginx
[root@192 nginx]# ls
conf  html  logs  start.sh

有了如上的文件,直接在該目錄下執行./start.sh ,即可創建一個 docker-nginx 服務,效果如下圖

[root@192 nginx]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
2e90b26259e1        nginx:1.16          "nginx -g 'daemon of…"   6 minutes ago       Up 6 minutes        0.0.0.0:8080->80/tcp   nginx-server

啓動之後的效果:

爲了後期比較直接的區分這兩臺服務器,我們需要編輯剛剛從我的 github 上下載的 nginx 的相關文件:html 文件夾下的 index.html,我們以修改主節點爲例

刷新網頁,修改之後的效果圖:

4、安裝配置 keepalived

(1)安裝 keepalived

#外網環境安裝
yum install -y curl gcc openssl-devel libnl3-devel net-snmp-devel
yum install -y keepalived

(2)修改配置文件
修改配置文件:vi /etc/keepalived/keepalived.conf

需要修改的位置:

只需要修改這 5 處即可,其他可不用修改,部分配置如下:

vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.2.111
    }
}

修改完配置文件之後,重啓 keepalived,重啓命令和其他相關命令如下:

systemctl enable keepalived # 開機自啓動
systemctl start keepalived     # 啓動
systemctl stop keepalived     # 暫停
systemctl restart keepalived  # 重啓
systemctl status keepalived   # 查看狀態

(3)檢查結果
對兩臺服務器分別執行ip a命令:

主節點執行結果:

2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:67:13:0b brd ff:ff:ff:ff:ff:ff
    inet 192.168.2.109/24 brd 192.168.2.255 scope global dynamic ens33
       valid_lft 4718sec preferred_lft 4718sec
    inet 192.168.2.111/32 scope global ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::25d3:a617:69d0:2d52/64 scope link 
       valid_lft forever preferred_lft forever
    inet6 fe80::21f4:56b8:342f:acaf/64 scope link tentative dadfailed 
       valid_lft forever preferred_lft forever

訪問 http://192.168.2.111:8080/ 發現是主節點 IP,keepalived 配置完成

主節點停掉 keepalived 服務的話,systemctl stop keepalived ,可以發現 http://192.168.2.111:8080/ 現在訪問的是備用節點

主節點重啓 keepalived 服務,http://192.168.2.111:8080/ 域名訪問的又是主節點了。

也可以通過:**tail -f /var/log/messages ** 命令來檢查 keepalived 的日誌哦~

5、綁定 Nginx 進程和 Keepalived 服務

上一步我們做的只是 keepalived 虛擬 IP 的配置,還沒有實現真正的 Nginx 的高可用。通過如上配置我們可以知道,虛擬 IP 的切換是通過 keepalived 服務的啓動和停止進行的。

因此,我們需要將 Nginx 進程的健康綁定到 keepalived 上,那如何綁定?我們可以通過 linux 的定時任務進行綁定,配置過程如下:

(1)編寫定時檢查腳本
主備節點都要添加該腳本 ** **vi /etc/keepalived/nginx_check.sh
該腳本的原理是通過檢查 Nginx 進程個數來判斷 Nginx 的健康的,如果你的 docker 容器中有其他 Nginx 進程,需要先把這些 Nginx 關掉。

#!/bin/bash
A=`ps -C nginx --no-header |wc -l`
B=`ps -C keepalived --no-header |wc -l`
# nginx 不在運行狀態 :嘗試重啓nginx,三秒後如果nginx仍然未運行,關閉keepalived,節點切換到備用節點
if [ $A -eq 0 ];then
      /usr/bin/docker restart nginx-server   #正常情況下這裏需要重啓 nginx,注意這是docker容器的重啓命令
      sleep 3
      if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
          ps -ef|grep keepalived|grep -v grep|awk '{print $2}'|xargs kill -9
      fi
fi
# nginx 處於運行狀態,但keepalived處於非運行狀態:重啓keepalived
if [ $A -ne 0 -a $B -eq 0 ];then
    systemctl restart keepalived
fi

(2)配置環境變量
這個配置是一個注意點,之前出現過 linux 定時任務腳本中無法執行 linux 命令的情況,原因是沒有把環境變量添加到 linux 定時腳本中,這裏保險起見需要進行如下配置:

# 將docker所在位置/usr/bin 添加到環境變量中
echo "export PATH=\$PATH:/usr/bin" >> /etc/profile
# 刷新環境變量
source /etc/profile

(3)添加 linux 定時任務

# 編輯定時任務
crontab -e
# 添加/修改自啓配置與如下相同
*/1 * * * * . /etc/profile;/bin/sh  /etc/keepalived/nginx_check.sh #每分鐘進行檢查 解決環境變量問題

到此爲止,我們就實現 Nginx 的高可用啦

四、結語

Nginx 高可用的配置,其實原理還是挺簡單的:

核心觀點就是:

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/XTMoGAr9-KvbPceLv9_nhw