keepalievd 高可用以及解決nginx宕機產生腦裂問題


Keepalived高可用

什么是高可用?

一般是指2台機器啟動着完全相同的業務系統,當有一台系統宕機,另外一台服務器就能快速的接管,對於訪問的用戶是無感知的。

舉例

通常做法是給路由器增加一台備節點,那么問題來了,如果我們的主網關master故障了,用戶需要手動指向backup,如果用戶過多修改起來會非常麻煩。

問題一:假設用戶將指向都修改為backup路由器,那么master路由器修好了怎么辦?
問題二:假設Master網關故障,我們將backup網關配置為master網關的ip是否可以?
 
其實是不行的,因為PC第一次通過ARP廣播尋找到Master網關的MAC地址與IP地址后,會將信息寫到ARP的緩存表中,那么PC之后連接都是通過那個緩存表的信息去連接,然后進行數據包的轉發,即使我們修改了IP但是Mac地址是唯一的,pc的數據包依然會發送給master。(除非是PC的ARP緩存表過期,再次發起ARP廣播的時候才能獲取新的backup對應的Mac地址與IP地址)
 
如何才能做到出現故障自動轉移,此時VRRP就出現了,我們的VRRP其實是通過軟件或者硬件的形式在Master和Backup外面增加一個虛擬的MAC地址(VMAC)與虛擬IP地址(VIP),那么在這種情況下,PC請求VIP的時候,無論是Master處理還是Backup處理,PC僅會在ARP緩存表中記錄VMAC與VIP的信息。

常用工具

硬件通常使用:F5
軟件通常使用:keepalived

VRRP協議

VRRP協議會在一個局域網中進行廣播
# 若lb01lb02均有vrrp協議,則相互廣播各自狀態

高可用keepalived核心概念

  • 如何確定主節點(master)和備用節點(backup)
  • 如果master故障,backup自動接管,那么master恢復后是否奪權(搶占式,非搶占式)
  • 如果兩台服務器都認為自己是master會如何?(腦裂)

keepalived搭建

環境准備

主機 IP 身份
lb01 172.16.1.5 Keepalived master
lb02 172.16.1.6 Keepalived backup
web01 172.16.1.7 web端
web02 172.16.1.8 web端
db01 172.16.1.61 數據庫
網卡 10.0.0.8 VIP

1.lb01和lb02

[root@lb01 ~]# yum install keepalived -y
[root@lb02 ~]# yum install keepalived -y

2.編輯配置文件

[root@lb01 ~]# vim /etc/keepalived/keepalived.conf 
! Configuration File for keepalived

# 全局配置
global_defs {
   # 當前keepalived的唯一標識
   router_id lb01
}

# 配置VRRP協議
vrrp_instance VI_1 {
    # 狀態,MASTER和BACKUP
    state MASTER
    # 綁定網卡
    interface eth0
    # 虛擬路由標示,可以理解為分組
    virtual_router_id 50
    # 優先級
    priority 100
    # 監測心跳間隔時間
    advert_int 1
    # 配置認證
    authentication {
        # 認證類型
        auth_type PASS
        # 認證的密碼
        auth_pass 1111
    }
    # 設置VIP
    virtual_ipaddress {
        # 虛擬的VIP地址
        192.168.15.3
    }
}
[root@lb01 ~]# systemctl enable --now keepalived

[root@lb02 ~]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived

# 全局配置
global_defs {
   # 當前keepalived的唯一標識
   router_id lb02
}

# 配置VRRP協議
vrrp_instance VI_1 {
    # 狀態,MASTER和BACKUP
    state BACKUP
    # 綁定網卡
    interface eth0
    # 虛擬路由標示,可以理解為分組
    virtual_router_id 50
    # 優先級
    priority 90
    # 監測心跳間隔時間
    advert_int 1
    # 配置認證
    authentication {
        # 認證類型
        auth_type PASS
        # 認證的密碼
        auth_pass 1111
    }
    # 設置VIP
    virtual_ipaddress {
        # 虛擬的VIP地址
        192.168.15.3
    }
}
 [root@lb02 ~]# systemctl enable --now keepalived

2.lb01和lb02的nginx保持一致

[root@lb01 ~]# ls
anaconda-ks.cfg  init.sh  nginx-1.20.2  nginx-1.20.2.tar.gz
[root@lb01 ~]# scp nginx-1.20.2.tar.gz 172.16.1.6:/root
root@172.16.1.6's password: 
nginx-1.20.2.tar.gz                                           100% 1037KB  20.5MB/s   00:00   

3.編譯安裝nginx,lb02

[root@lb02 ~]# ls
anaconda-ks.cfg  init.sh  nginx-1.20.2.tar.gz
[root@lb02 ~]# tar -xf nginx-1.20.2.tar.gz 
[root@lb02 ~]# ls
anaconda-ks.cfg  init.sh  nginx-1.20.2  nginx-1.20.2.tar.gz
[root@lb02 nginx-1.20.2]# ls
auto  CHANGES  CHANGES.ru  conf  configure  contrib  html  LICENSE  man  README  src
[root@lb02 nginx-1.20.2]# ./configure  --conf-path=/etc/nginx/nginx.conf --with-http_gzip_static_module --with-stream --with-http_ssl_module --with-http_sub_module

# 若執行配置文件結尾出現以下情況

./configure: error: SSL modules require the OpenSSL library.
You can either do not enable the modules, or install the OpenSSL library
into the system, or build the OpenSSL library statically from the source
with nginx by using --with-openssl=<path> option.

# 安裝依賴
[root@lb02 nginx-1.20.2]# yum install openssl openssl-devel zlib zlib-devel -y

# 再次執行
[root@lb02 nginx-1.20.2]# ./configure  --conf-path=/etc/nginx/nginx.conf --with-http_gzip_static_module --with-stream --with-http_ssl_module --with-http_sub_module

[root@lb02 nginx-1.20.2]# make make install
[root@lb02 sbin]# ls
nginx
[root@lb02 sbin]# pwd
/usr/local/nginx/sbin
[root@lb02 sbin]# mv nginx /usr/sbin/

[root@lb02 sbin]# nginx -V
nginx version: nginx/1.20.2
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --conf-path=/etc/nginx/nginx.conf --with-http_gzip_static_module --with-stream --with-http_ssl_module --with-http_sub_module
[root@lb01 ~]# scp /usr/lib/systemd/system/nginx.service root@192.168.15.6:/usr/lib/systemd/system/
[root@lb01 ~]# scp -r ./* 192.168.15.6:/etc/nginx/ teoi
# 若啟動nginx發生以下錯誤
[root@lb02 nginx]# systemctl start nginx
Job for nginx.service failed because the control process exited with error code. See "systemctl

# 查看狀態及報錯
[root@lb02 nginx]# systemctl status nginx.service -l
...
1月 10 18:45:43 lb02 nginx[77789]: nginx: [emerg] getpwnam("www") failed in /etc/nginx/nginx.conf:1
...

# 創建www用戶
[root@lb02 nginx]# id www
id: www: no such user
[root@lb02 nginx]# groupadd www -g 666
[root@lb02 nginx]# useradd www -u 666 -g 666 -M -r
# 重載nginx 
[root@lb02 nginx]# systemctl daemon-reload

# 或者出現以下錯誤
...
1月 10 18:50:44 lb02 nginx[83557]: nginx: [emerg] open() "/var/log/nginx/error.log" failed (2: No such file or directory)
...

# 創建目錄
[root@lb02 nginx]# mkdir /var/log/nginx
[root@lb02 nginx]# chown -R www.www /var/log/nginx
[root@lb02 nginx]# systemctl start nginx.service
# 由於之前做過靜態分離,現在lb02也需要做掛載
[root@lb02 ~]# yum install nfs-utils -y
[root@lb02 ~]# mount -t nfs 172.16.1.31:/opt/img/ /opt/img/
lb01,lb02
[root@lb01 ~]# systemctl start keepalived
[root@lb02 ~]# systemctl start keepalived

# lb01關閉自動切換到lb02,但客戶訪問依舊是 192.168.15.3
[root@lb01 ~]# systemctl stop keepalived

keepalived腦裂問題

兩台高可用服務器在指定時間內,無法互相檢查到對方的心跳而各自啟動故障轉移功能。

即為腦裂

可能出於某種原因,如nginx宕機,防火牆打開... 導致VRRP無法相互廣播各自狀態,lb01和lb02都會產生一個
192.168.15.3的IP,是瀏覽器無法做出選擇。

解決腦裂問題

思想:如何在nginx宕機時將狀態告知keepalived,是keepalived自動關閉,從而啟動故障轉移功能

1、如果Nginx宕機怎么辦?
想辦法告訴keepalived,Nginx的情況。
# ps -ef | grep [n]ginx

$?  : 上一條命令執行的結果。

$? = 0 (nginx 正常啟動)
$? != 0 (nginx 啟動失敗)

# 那么如何讓將nginx狀態告訴keepalived?

VRRP_script
# 編輯腳本

2、局域網之內,keepalived無法相互廣播,怎么辦?
判斷VIP是否可以ping的通

解決nginx無法正常啟動,如何調用keepalived高可用

  • nginx宕機

拓展

#!/bin/bash

# 解決Nginx無法正常啟動
ps -ef | grep -q [n]ginx 

if [ $? -ne 0 ];then
	# 代表Nginx未正常啟動
	systemctl start nginx &>/dev/null
	sleep 2
	ps -ef | grep -q [n]ginx
	if [ $? -ne 0 ];then
		systemctl stop keepalived 
	fi
fi

解釋ping -c 1 $VIP &>/dev/null

舉例:

[root@lb01 conf.d]# ping -c 1 192.168.15.3 &>/dev/null 
[root@lb01 conf.d]# echo $?
0

[root@lb01 conf.d]# ping -c 1 192.168.15.30 &>/dev/null 
[root@lb01 conf.d]# echo $?
1

指定ping次數

[root@lb02 ~]# ping -c 1 192.168.15.3
[root@lb02 ~]# echo $?
0

[root@lb02 ~]# ping -c 1 192.168.15.30
[root@lb02 ~]# echo $?
1

實踐

[root@lb01 ~]# vim check_nginx.sh
#!/bin/bash

# 解決Nginx無法正常啟動
ps -ef | grep -q [n]ginx 

if [ $? -ne 0 ];then
	# 代表Nginx未正常啟動
	systemctl start nginx &>/dev/null
	sleep 2
	ps -ef | grep -q [n]ginx
	if [ $? -ne 0 ];then
		systemctl stop keepalived 
	fi
fi
[root@lb01 ~]# chmod +x check_nginx.sh 
[root@lb01 ~]# systemctl status nginx
[root@lb01 ~]# systemctl status keepalived
[root@lb01 ~]# ip a
'分別啟動nginx keepalived'

[root@lb01 ~]# vim /etc/nginx/nginx.conf
adasdasddas (頂部隨意添加字樣,使nginx運行錯誤)
user  www;
worker_processes  auto;

[root@lb01 ~]# systemctl stop nginx
[root@lb01 ~]# ./checkNG.sh 

至此,解決nginx宕機,實現高可用

此時,再對keepalived配置文件做編輯,與解決nginx宕機腳本連用

[root@lb01 keepalived]# vim /etc/keepalived/keepalived.conf 
! Configuration File for keepalived

# 全局配置
global_defs {
   # 當前keepalived的唯一標識
   router_id lb01
}

# 檢測腳本
vrrp_script check_nginx {
	# 指定腳本路徑
    script "/etc/keepalived/checkNG.sh"
    # 執行間隔
    interval 5
}

# 配置VRRP協議
vrrp_instance VI_1 {
    # 狀態,MASTER和BACKUP
    state MASTER
    # 綁定網卡
    interface eth0
    # 虛擬路由標示,可以理解為分組
    virtual_router_id 50
    # 優先級
    priority 100
    # 監測心跳間隔時間
    advert_int 1
    # 配置認證
    authentication {
        # 認證類型
        auth_type PASS
        # 認證的密碼
        auth_pass 1111
    }
    # 設置VIP
    virtual_ipaddress {
        # 虛擬的VIP地址
        192.168.15.3
    }
    # 調用檢查
    track_script {
        check_nginx
    }
}

[root@lb01 keepalived]# mv checkNG.sh /etc/keepalived/
[root@lb01 keepalived]# scp /etc/keepalived/keepalived.conf /etc/keepalived/checkNG.sh 192.168.15.6:/etc/keepalived/
[root@lb02 ~]# vim /etc/keepalived/keepalived.conf 
! Configuration File for keepalived

# 全局配置
global_defs {
   # 當前keepalived的唯一標識
   router_id lb02
}

# 檢測腳本
 vrrp_script check_nginx {
       # 指定腳本路徑
       script "/etc/keepalived/checkNG.sh"
       # 執行間隔
       interval 5
 }

# 配置VRRP協議
vrrp_instance VI_1 {
    # 狀態,MASTER和BACKUP
    state BACKUP
    # 綁定網卡
    interface eth0
    # 虛擬路由標示,可以理解為分組
    virtual_router_id 50
    # 優先級
    priority 90
    # 監測心跳間隔時間
    advert_int 1
    # 配置認證
    authentication {
        # 認證類型
        auth_type PASS
        # 認證的密碼
        auth_pass 1111
    }
    # 設置VIP
    virtual_ipaddress {
        # 虛擬的VIP地址
        192.168.15.3
    }
    # 調用檢查
    track_script {
        check_nginx
     }
"/etc/keepalived/keepalived.conf" 47L, 867C  

此時,在lb01中關閉nginx,可以看到,如圖所示,由於編輯了腳本,檢測到nginx關閉便會自動啟動

至此,真正實現keepalived高可用


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM