CentOS7 實現 Keepalived + Nginx 實現高可用 Web 負載均衡

strivechao發表於2020-07-23

一、基礎環境

系統版本 nginx版本 keepalived版本 ip 作用
CentOS Linux release 7.6 nginx/1.18.0 keepalived-2.1.5 192.168.86.135 master
CentOS Linux release 7.6 nginx/1.18.0 keepalived-2.1.5 192.168.86.136 slave

VIP:192.168.86.137

二、編譯環境安裝

yum -y install make zlib zlib-devel gcc-c++ libtool  openssl openssl-devel  pcre  pcre-devel


掛映象到系統

mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak

mv /etc/yum.repos.d/CentOS-Debuginfo.repo /etc/yum.repos.d/CentOS-Debuginfo.repo.bak

mv /etc/yum.repos.d/CentOS-Vault.repo /etc/yum.repos.d/CentOS-Vault.repo.bak

cp /etc/yum.repos.d/CentOS-Media.repo /etc/yum.repos.d/CentOS-Media.repo.bak

sed -i 's#file:///media/cdrom/##g' /etc/yum.repos.d/CentOS-Media.repo

sed -i 's#file:///media/cdrecorder/##g' /etc/yum.repos.d/CentOS-Media.repo

sed -i 's/^ *enabled *=.*$/enabled=1/g' /etc/yum.repos.d/CentOS-Media.repo

sed -i 's#^ *baseurl *=.*$#baseurl=file:///mnt/centos/#g' /etc/yum.repos.d/CentOS-Media.repo



mount -t iso9660 -o loop /tools/CentOS-7-x86_64-DVD-1908.iso /mnt/centos

三、安裝nginx

  1. 安裝nignx

    #進入目錄
    cd /tools    #上傳安裝檔案,並解壓
    tar -zxvf nginx-1.18.0.tar.gz
    #進入安裝目錄
    cd nginx-1.18.0
    #檢查配置
    ./configure --prefix=/usr/local/nginx  --with-stream
     
    make&&make install


  2. 修改nginx配置檔案

    修改 Nginx 歡迎首頁內容(用於後面測試, 用於區分兩個節點的 Nginx):

    • master

      echo 'this is master 135' > /usr/local/nginx/html/index.html
    • slave

      echo 'this is slave 136' >  /usr/local/nginx/html/index.html
    • 修改nginx.conf

    • # vi /usr/local/nginx/conf/nginx.conf
    • user root;
      worker_processes 1;
      #error_log logs/error.log;
      #error_log logs/error.log notice;
      #error_log logs/error.log info;
      #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;
      	#keepalive_timeout 0;
      	keepalive_timeout 65;
      	#gzip on;
      	server {
      		listen 88;
      		server_name localhost;
      		#charset koi8-r;
      		#access_log logs/host.access.log main;
      		location / {
      			root html;
      			index index.html index.htm;
      		}
      		#error_page 404 /404.html;
      		# redirect server error pages to the static page /50x.html
      		error_page 500 502 503 504 /50x.html;
      		location = /50x.html {
      			root html;
      		}
      	}
      }
    • #user  nobody;
      worker_processes  2;
      error_log  logs/error.log;
      error_log  logs/error.log  debug;
      error_log  logs/error.log  info;
      #pid        logs/nginx.pid;
      worker_rlimit_nofile 65535;
      events {
          use epoll;
          multi_accept on;
          accept_mutex on;
          worker_connections  65535;
      }
      stream{
          upstream tcp21001{
              server 192.168.10.130:11001 weight=1 max_fails=2 fail_timeout=30s;#負載均衡的主機IP與埠 weight權重 代表分到資源的比例  max_fails=2 失敗超過2次,剔除  fail_timeout=30s 30秒不會在連線些服務
          }    
          server{
              #listen [::1]:7777  #IPV6
              listen 7777;#監聽本機埠號IPV4
              proxy_pass tcp11001;
              proxy_connect_timeout 3s;  #服務不通時 超時時間
              proxy_timeout 3600s;  #無資料傳送,超時時間
    •    upstream tcp21002{
              server 192.178.17.130:11002 weight=1 max_fails=2 fail_timeout=30s;#負載均衡的主機IP與埠 weight權重 代表分到資源的比例  max_fails=2 失敗超過2次,剔除  fail_timeout=30s 30秒不會在連線些服務
          }   
          server{
              #listen [::1]:8888  #IPV6
              listen 8888;#監聽本機埠號IPV4
              proxy_pass tcp11002;
              proxy_connect_timeout 3s;  #服務不通時 超時時間
              proxy_timeout 3600s;  #無資料傳送,超時時間
          }
      }
  3. 啟動nginx

    systemctl start nginx
  4. 測試nginx啟動

    curl localhost
    this is master135


4.CentOS 7設定Nginx開機啟動


第一步:在/lib/systemd/system目錄下建立nginx.service檔案
第二步:編輯nginx.service檔案:
vi /lib/systemd/system/nginx.service
[Unit]
Description=nginx 
After=network.target 
   
[Service] 
Type=forking 
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx reload
ExecStop=/usr/local/nginx/sbin/nginx quit
PrivateTmp=true 
   
[Install]
WantedBy=multi-user.target
[Unit]:服務的說明
Description:描述服務
After:描述服務類別
[Service]服務執行引數的設定
Type=forking是後臺執行的形式
ExecStart為服務的具體執行命令
ExecReload為重啟命令
ExecStop為停止命令
PrivateTmp=True表示給服務分配獨立的臨時空間
注意:[Service]的啟動、重啟、停止命令全部要求使用絕對路徑
[Install]執行級別下服務安裝的相關設定,可設定為多使用者,即系統執行級別為3
#賦予指令碼執行許可權
chmod +x /usr/lib/systemd/system/nginx.service
第三步:加入開機啟動
# systemctl enable nginx.service
取消開機自啟動
#systemctl disable nginx.service
啟動nginx服務
#systemctl start nginx.service
停止nginx服務
#systemctl stop nginx.service
重啟nginx服務
#systemctl restart nginx.service
檢視所有以啟動的服務
#systemctl list-units --type=service
檢視服務當前狀態
#systemctl status nginx.service
遇到的錯誤
Warning: nginx.service changed on disk. Run 'systemctl daemon-reload' to reload units.
按照提示執行命令systemctl daemon-reload即可。

生成系統service管理檔案

vvim /usr/lib/systemd/system/nginx.service

[Unit]
Description=nginx-The High-performance HTTP Server After=network.target

[Service]
Type=forking PIDFile= /usr/local/nginx/logs/nginx.pid ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf ExecReload=/usr/local/nginx/sbin/nginx -s reload ExecStop=/usr/local/nginx/sbin/nginx -s stop PrivateTmp=true

[Install]
WantedBy=multi-user.target



6.加防火牆

新增

firewall-cmd --zone=public --add-port=88/tcp --permanent 

刪除

firewall-cmd --zone=public --remove-port=80/tcp --permanent

更新防火牆規則: 
firewall-cmd --reload

檢視所有開啟的埠: 
firewall-cmd --zone=public --list-ports



四、安裝keepalived

1、 建立依賴環境

yum -y install libnl libnl-devel gcc openssl-devel libnl3-devel pcre-devel net-snmp-agent-libs libnfnetlink-devel curl
wget 

2、安裝keepalived

tar -zxvf keepalived-2.1.5.tar.gz
cd keepalived-2.1.5
./configure --prefix=/usr/local/keepalived-2.1.5
 make && make install

3、建立啟動檔案

ln -s /usr/local/keepalived-2.1.5 /usr/local/keepalived
mkdir /etc/keepalived/ 
cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
cp /usr/local/keepalived-2.1.5/etc/sysconfig/keepalived /etc/sysconfig/
ln -s /usr/local/keepalived-2.1.5/sbin/keepalived /usr/sbin/
 下面檔案要從keepalived原始碼目錄複製,安裝目錄中沒有cp 
 cp /tools/keepalived-2.1.5/keepalived/keepalived.service /etc/systemd/system/
 cp /tools/keepalived-2.1.5/keepalived/etc/init.d/keepalived /etc/init.d/

4、建立配置檔案

  1. master

    cat > /etc/keepalived/keepalived.conf << EOF
    ! Configuration File for keepalived
    global_defs {
        #一個沒重複的名字即可
        router_id xxoo_master
    }
    # 檢測nginx是否執行
    vrrp_script chk_nginx {
            script "/etc/keepalived/nginx_check.sh"
            interval 2
            weight -20}
    vrrp_instance VI_1 {
        # 此處不設定為MASTER,透過priority來競爭master
        state BACKUP
        # 網路卡名字,文章下方會給出如何獲取網路卡名字的方法    interface enp0s3
        # 同一個keepalived叢集的virtual_router_id相同
        virtual_router_id 51
        # 權重,master要大於slave
        priority 100
        # 主備通訊時間間隔
        advert_int 1
        # 如果兩節點的上聯交換機禁用了組播,則採用vrrp單播通告的方式
        # 本機ip
        unicast_src_ip 192.168.0.182
        unicast_peer {
            # 其他機器ip        192.168.0.189
        }
        # 設定nopreempt防止搶佔資源
        nopreempt
        # 主備保持一致
        authentication {
            auth_type PASS
            auth_pass 1111
        }
        # 與上方nginx執行狀況檢測呼應
        track_script {
            chk_nginx
        }
        virtual_ipaddress {
            # 虛擬ip地址(VIP,一個尚未佔用的內網ip即可)        192.168.0.180
        }
    }
    EOF
  2. slave

    cat > /etc/keepalived/keepalived.conf << EOF
    ! Configuration File for keepalived
    global_defs {
        #一個沒重複的名字即可
        router_id xxoo_slave
    }
    # 檢測nginx是否執行
    vrrp_script chk_nginx {
            script "/etc/keepalived/nginx_check.sh"
            interval 2
            weight -20}
    vrrp_instance VI_1 {
        # 此處不設定為MASTER,透過priority來競爭master
        state BACKUP
        # 網路卡名字,文章下方會給出如何獲取網路卡名字的方法    interface enp0s3
        # 同一個keepalived叢集的virtual_router_id相同
        virtual_router_id 51
        # 權重,master要大於slave
        priority 90
        # 主備通訊時間間隔
        advert_int 1
        # 如果兩節點的上聯交換機禁用了組播,則採用vrrp單播通告的方式
        # 本機ip
        unicast_src_ip 192.168.0.189
        unicast_peer {
            # 其他機器ip        192.168.0.182
        }
        # 設定nopreempt防止搶佔資源
        nopreempt
        # 主備保持一致
        authentication {
            auth_type PASS
            auth_pass 1111
        }
        # 與上方nginx執行狀況檢測呼應
        track_script {
            chk_nginx
        }
        virtual_ipaddress {
            # 虛擬ip地址(VIP,一個尚未佔用的內網ip即可)        192.168.0.180
        }
    }
    EOF

5、啟編寫Nginx 狀態檢測指令碼

      編寫 Nginx 狀態檢測指令碼 /etc/keepalived/nginx_check.sh (已在 keepalived.conf 中配置)指令碼要求:如果 nginx 停止執行,

嘗試啟動,如果無法啟動則殺死本機的 keepalived 程式, keepalied將虛擬 ip 繫結到 BACKUP 機器上。 內容如下:


cat > /etc/keepalived/nginx_check.sh << EOF
#!/bin/bash
A=`ps -C nginx --no-header | wc -l`
if [ $A -eq 0 ];
then
systemctl start nginx 
 #  /usr/local/nginx/sbin/nginx    #嘗試重新啟動nginx
sleep 2  #睡眠2秒
if [ `ps -C nginx --no-header | wc -l` -eq 0 ];
then
killall keepalived
fi
fi

儲存後,給指令碼賦執行許可權:

# chmod +x /etc/keepalived/nginx_check.sh

每5秒執行一次指令碼

crontab -e

* * * * * /etc/keepalived/nginx_check.sh >>/etc/keepalived/check_nginx.log

* * * * * sleep 5;/etc/keepalived/nginx_check.sh >>/etc/keepalived/check_nginx.log
* * * * * sleep 10;/etc/keepalived/nginx_check.sh >>/etc/keepalived/check_nginx.log
* * * * * sleep 15;/etc/keepalived/nginx_check.sh >>/etc/keepalived/check_nginx.log
* * * * * sleep 20;/etc/keepalived/nginx_check.sh >>/etc/keepalived/check_nginx.log
* * * * * sleep 25;/etc/keepalived/nginx_check.sh >>/etc/keepalived/check_nginx.log
* * * * * sleep 30;/etc/keepalived/nginx_check.sh >>/etc/keepalived/check_nginx.log
* * * * * sleep 35;/etc/keepalived/nginx_check.sh >>/etc/keepalived/check_nginx.log
* * * * * sleep 40;/etc/keepalived/nginx_check.sh >>/etc/keepalived/check_nginx.log
* * * * * sleep 45;/etc/keepalived/nginx_check.sh >>/etc/keepalived/check_nginx.log
* * * * * sleep 50;/etc/keepalived/nginx_check.sh >>/etc/keepalived/check_nginx.log

* * * * * sleep 55; /etc/keepalived/nginx_check.sh >>/etc/keepalived/check_nginx.log


systemctl reload crond

systemctl restart crond

6、啟動keepalived

systemctl start keepalived
systemctl enable keepalived

7、日誌處理

1.編輯配置檔案/etc/sysconfig/keepalived,將第14行的KEEPALIVED_OPTIONS="-D"修改為KEEPALIVED_OPTIONS="-D -d -S 0"
    
# 說明:
# --dump-conf -d 匯出配置資料
# --log-detail -D 詳細日誌資訊
# --log-facility -S 設定本地的syslog裝置,編號0-7# -S 0 表示指定為local0裝置
2.修改rsyslog的配置檔案 vi /etc/rsyslog.conf,在結尾加入如下2行內容,將local0裝置的所有日誌都記錄到/var/log/keepalived.log檔案
echo  "local0.*    /var/log/keepalived.log"  >> /etc/rsyslog.conf
在42行第一列尾加入";local0.none",表示來自local0裝置的所有日誌資訊不再記錄於/var/log/messages裡
3.重啟rsyslog服務
systemctl restart rsyslog
4.測試keepalived日誌記錄結果。重啟keepalived服務,檢視日誌資訊。
 tail -f /var/log/keepalived.log
systemctl start keepalived.service
配置日誌輪轉
/var/log/keepalived/*.log {  #切分的兩個檔名
    daily        #按天切分
    rotate 7     #保留7份
    create 0644 haproxy haproxy  #建立新檔案的許可權、使用者、使用者組
    compress     #壓縮舊日誌
    delaycompress  #延遲一天壓縮
    missingok    #忽略檔案不存在的錯誤
    dateext      #舊日誌加上日誌字尾
    sharedscripts  #切分後的重啟指令碼只執行一次
    postrotate   #切分後執行指令碼過載rsyslog,讓rsyslog向新的日誌檔案中輸出日誌
    /bin/kill -HUP $(/bin/cat /var/run/syslogd.pid 2>/dev/null) &>/dev/null
    endscript
}

防止出現腦裂現象(主備同時獲取了VIP地址)

# 指定keepalived配置的網路卡:enp0s3,固定的VRRP廣播地址:224.0.0.18
firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface ens192 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
firewall-cmd --direct --permanent --add-rule ipv4 filter OUTPUT 0 --out-interface ens192 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
firewall-cmd --reload
# 檢視配置的規則
firewall-cmd --direct --get-rules ipv4 filter INPUT
firewall-cmd --direct --get-rules ipv4 filter OUTPUT
# 清除規則
firewall-cmd --direct  --permanent --remove-rule ipv4 filter INPUT 0 --in-interface ens192 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
firewall-cmd --direct  --permanent --remove-rule ipv4 filter OUTPUT 0 --out-interface ens192 --destination 224.0.0.18 --protocol vrrp -j ACCEPT



五、測試

1、在兩臺伺服器上測試

  1. master

    $ curl localhost
    this is master
    root@centos7[14:46:07]:~
    $ curl 192.168.86.135
    this is master
    root@centos7[15:03:29]:~
  2. slave

    $ curl localhost
    this is slave
    root@centos7[15:03:59]:/etc/keepalived
    $ curl 192.168.86.136
    this is master

2、關閉master的keepalived模仿down機

  1. master關閉keepalived

    $ systemctl stop keepalived
  2. 在slave上面進行測試
$  curl localhost
this is slave
root@centos7[15:10:29]:/etc/keepalived
$ curl 192.168.86.136
this is slave

到此keepalived完成


4.NetworkManager-nmcli管理網路

nmcli general status #顯示NetworkManager的整體狀態
nmcli connection show #顯示所有的連線
nmcli connection show -a #顯示活動的連線
nmcli device status #顯示NetworkManager識別的裝置列表和它們當前的狀態
nmcli device disconnect/connect eno16777736 #停止/啟動網路卡==ifup/down

4、關閉NetworkManager服務

#停止服務

service NetworkManager stop   

#禁用服務,下次不自動啟動
chkconfig NetworkManager off  


問題處理:

【keepalived】關於keepalived配置中的 mcast_src_ip 和 unicast_src_ip


https://blog.csdn.net/mofiu/article/details/76644012

keepalived 配置檔案引數詳解



找到你要虛擬的網路卡對應的域,並且開啟vrrp協議即可,命令為

sudo firewall-cmd --zone=public --add-protocol=vrrp --permanent
#過載配置
sudo firewall-cmd --reload


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25469263/viewspace-2706365/,如需轉載,請註明出處,否則將追究法律責任。

相關文章