主頁 > 軟體設計 > keepalived高可用

keepalived高可用

2021-10-30 11:46:38 軟體設計

文章目錄

          • 1.keepalived高可用介紹
          • 2.keepalived功能
          • 3.keepalived高可用故障轉移原理
          • 4.keepalived作業原理
          • 5.keepalived組態檔
            • 5.2自定義keepalived主組態檔
            • 5.3自定義keepalived實體
          • 6.腦裂
          • 7.keepalived實作nginx負載均衡高可用

高可用集群:keepalived
只要不是云主機,就可以直接使用keepalived,因為有VIP,如果是云主機的話,就需要買slb,slb是一個服務具有負載均衡和高可用的功能,
1.keepalived高可用介紹

keepalived官網
keepalived高可用指的是比如有倆臺主機作為調度器,分別連接著n臺服務器,當主調度器上發生問題,備用調度器的這臺機器立馬替換上去進行作業,(其中客戶訪問的vip是由keepalived生成的)
keepalived 最初是為LVS負載軟體設計的,用來管理lvs集群的各個節點的狀態,后加入實作高可用的VRRP協議功能,所以Keepalived既可以管理lvs軟體,還可以作為其它服務(nginx,Haproxy,MYSQL等)高可用解決方案,

VRRP(virtual route redundancy)虛擬路由器冗余協議,主要解決靜態路由單點故障問題,保障少許服務器出現宕機時,整個網路仍然正常運行,

2.keepalived功能
  • 管理LVS負載均衡軟體
  • 管理檢查LVS集群節點的狀態
  • 保證系統網路服務的高可用性
3.keepalived高可用故障轉移原理

keepalived高可用故障轉移是通過VRRP協議實作的,主要解決靜態路由故障,通過一種競選機制將路由的任務交給某個vrrp路由器,保證網路正常運行,
keepalived作業時,主節點會不斷的向備節點發送(多個廣播信號方式)稱心跳資訊,告訴備節點自己還在作業,不要想我不要自己作業,如果突然主節點發送了故障后,就不能發送心跳資訊,備節點就不能收到來著主節點的資訊了,開始呼叫接管程式,接管ip資源以及服務,代替主節點的作業,而當主節點恢復正常后,備節點釋放所有的ip資源和服務,恢復之前的備用節點狀態,

4.keepalived作業原理

在這里插入圖片描述
4.1想要深入了解keepalived,就要從vrrp通信來看

  • VRRP,全稱 Virtual Router Redundancy Protocol,中文名為虛擬路由冗余協議,VRRP的出現是為了解決靜態路由的單點故障,
  • VRRP是通過一種竟選協議機制來將路由任務交給某VRRP路由器的,
  • VRRP用 ip協議廣播的方式(默認多播地址:224.0.0.18)實作高可用對之間通信,
  • 作業時主節點發包,備節點接包,當備節點接收不到主節點發的資料包的時候,就啟動接管程式接管主節點的開源,備節點可以有多個,通過優先級競選,但一般 Keepalived系統運維作業中都是一對,
  • VRRP使用了加密協議加密資料,但Keepalived官方目前還是推薦用明文的方式配置認證型別和密碼,

4.2Keepalived服務的作業原理
在 Keepalived 服務之間,只有作為主節點會一直發送 VRRP 廣播包,告訴備它還活著,此時備節點不會槍占主,當主不可用時,即備監聽不到主發送的廣播包時,就會啟動相關服務接管資源,保證業務的連續性.接管速度最快可以小于1秒,


5.keepalived組態檔
#keepalived的主組態檔:/etc/keepalived/keepalived.conf(以下是默認內容)
global_defs {						    			
   notification_email {                   		#收件人郵箱       
     acassen@firewall.loc                  
     failover@firewall.loc
     sysadmin@firewall.loc
  }
   notification_email_from Alexandre.Cassen@firewall.loc #發件人郵箱
   smtp_server 192.168.200.1		#郵箱服務器地址
   smtp_connect_timeout 30			#定義超時時間
   router_id LVS_DEVEL    			#路由器id(每臺路由器不一樣)
   vrrp_skip_check_adv_addr	
   vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

vrrp_instance VI_1 {			//定義實體
    state MASTER				//初始化狀態,可選{MASTER|BACKUP}
    interface eth0        //VRRP系結的介面名稱,用來發送VRRP包
    virtual_router_id 51     //虛擬路由器id(同集群型別服務才能設定一樣)
    priority 100			//優先級
    nopreempt					//設定不搶占
    advert_int 1				//檢查的間隔(發送心跳包資訊的時間)
    authentication {
        auth_type PASS				//認證用戶和密碼
        auth_pass 1111
    }
    virtual_ipaddress {				//配置要使用的VIP地址
        192.168.200.16
    }
}
			#以下是配置虛擬服務器
virtual_server 192.168.200.16 443 {	//虛擬VIP(也就是上面配置的VIP,)
    delay_loop 6					 //443:代表https,這里可以修改為其它的服務,如mysql,nginx等,來進行高可用
    lb_algo rr					//rr輪循演算法
    lb_kind NAT					//默認nat模式,進行埠映射,
    persistence_timeout 50   //資料寫到硬碟的超時時間,單位秒
    protocol TCP			//四層協議
    
      sorry_server 192.168.200.200 1358	 //定義備用服務器,當所有RS都故障時用sorry_server來回應

    real_server 192.168.201.100 443 {	//真實服務器ip和埠,只有是nat模式才可以進行埠映射
        weight 1  //服務器設定權重
        SSL_GET {  			#httpd服務的話就是HTTP_GET,https服務則是SSL_GET
            url {
              path /
              digest ff20ad2481f97b1754ef3e12ecd3a9cc
            }
            url {
              path /mrtg/
              digest 9b3a0c85a887a256d6939da88aabd8cd
            }
            connect_timeout 3  //連接超時的時間
            retry 3		//get嘗試次數
            delay_before_retry 3	//嘗試之前延遲多長時間
        }
    }
}
#組態檔至少存在倆個real_server,分別指的是主和備服務器
[root@master ~]# rpm -ql keepalived
/etc/keepalived
/etc/keepalived/keepalived.conf   //主配置目錄
/etc/sysconfig/keepalived
/usr/bin/genhash
/usr/lib/systemd/system/keepalived.service   //服務控制檔案
5.2自定義keepalived主組態檔
vrrp_instance欄位配置
nopreempt  //設定為不搶占,默認是搶占狀態的,使用此功能,狀態必須為BACKUP,就是主和備均為backup,
preempt_delay   //設定延遲搶占,單位為秒,范圍0-1000,默認為0,多少秒后開始搶占
vrrp_script欄位配置
//添加的腳本為周期性執行,靜態碼會被呼叫它的vrrp instance記錄
vrrp_script <script_name>{
	    script "/path/...."        #腳本的路徑
	    interval <INTEGER>         #腳本執行的間隔,單位秒,默認為1s
	    timeout <INTEGER>    	   #指定的 多少秒后,腳本被認為執行失敗
	    weight  <-254 --- 254>     #調整優先級,默認為2,在用來的優先級情況下進行操作
	    rise <INTEGER> 			   #執行多少次才認為成功
	    fall <INTEGER>             #執行多少次才認為失敗
	    user <USERNAME> [GROUPNAME]   #運行腳本的用戶和組
	    init_fail 					#設定初始化腳本狀態為失敗
}
real_server欄位配置
weight <INT>			#服務器設定權重,默認為1
inhibit_on_failure      //當服務器健康檢查失敗時,將其weight設定為0, \
                        //而不是從Virtual Server中移除
notify_up <STRING>      //當服務器健康檢查成功時,執行的腳本
notify_down <STRING>    //當服務器健康檢查失敗時,執行的腳本
uthreshold <INT>        //到這臺服務器的最大連接數
lthreshold <INT>        //到這臺服務器的最小連接數
tcp_check欄位配置
connect_ip <IP ADDRESS>     //連接的IP地址,默認是real server的ip地址
connect_port <PORT>         //連接的埠,默認是real server的埠
bindto <IP ADDRESS>         //發起連接的介面的地址,
bind_port <PORT>            //發起連接的源埠,
connect_timeout <INT>       //連接超時時間,默認是5s,
fwmark <INTEGER>            //使用fwmark對所有出去的檢查資料包進行標記,
warmup <INT>    //指定一個隨機延遲,最大為N秒,可防止網路阻塞,如果為0,則關閉該功能,
retry <INIT>                //重試次數,默認是1次,
delay_before_retry <INT>    //默認是1秒,在重試之前延遲多少秒,
5.3自定義keepalived實體
global_defs {
    router_id LVS_Server         //實體名字
}
vrrp_instance VI_1 {
    state BACKUP                 //狀態
    interface ens33             //介面
    virtual_router_id 51       //虛擬id(同一集群保證一樣)
    priority 150                   //優先級
    nopreempt					//不搶占
    advert_int 1              //重繪間隔
    authentication {			//認證
        auth_type PASS
        auth_pass wangqing
    }
    virtual_ipaddress {  
        192.168.136.250 dev ens33      //虛擬vip可指定網卡
    }
}
virtual_server 192.168.136.250 80 {
    delay_loop 3 
    lvs_sched rr           //演算法
    lvs_method NAT       //NAT模式
    protocol TCP
    real_server 192.168.136.129 80 {
        weight 1
        TCP_CHECK {
            connect_port 80
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
    real_server 192.168.136.130 8080 {
        weight 1
        TCP_CHECK {
            connect_port 8080
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}

6.腦裂

6.1HA腦裂
HA腦裂:在高可用(HA)系統中,心跳線正常的情況下,倆個節點會互相發送資訊,感知對方是否還存在,如果一旦感知不到了對方的資訊,就認為對方發生故障,從而搶占資源和應用服務,心跳線斷開的情況下,如果倆邊服務均正常或均例外,就會發生嚴重的后果,資源的搶奪,導致資料損壞日志出錯,

針對HA腦裂的決策:

  • 添加心跳線,減少腦裂幾率,一潭訓了,還有多條
  • 啟動磁盤鎖,讓正在服務的機器鎖住共享磁盤,讓對方不能進行搶占磁盤資源,當服務的一方發現心跳線全部斷開則開啟磁盤鎖,一般情況下不上鎖
  • 設定參考的ip(網關),當心跳線全部斷開后,2個節點分別ping參考ip,一端ping不通則證明本端的網路鏈路出現問題,主動放棄爭奪權,讓能夠ping通的一端去跑服務

6.2腦裂產生的原因
1.心跳線鏈路(網路)發生故障,導致無法通信
心跳線(斷了,老化了)
網卡以及驅動壞了,ip配置沖突
設備故障,交換機,路由器
2.高可用服務器開啟了iptable防火墻導致資訊傳輸
3.高可用服務器心跳網卡地址配置不正確,(比如不在一個網段)
4.高可用服務器的配置不正確,心跳方式不同,軟體bug,廣播沖突等
5.keepalived配置的virtual_router_id同一集群配置的id不同,也會發生故障

6.3腦裂的常見解決方案
在實際生產環境中,我們可以從以下幾個方面來防止裂腦問題的發生:

同時使用串行電纜和以太網電纜連接,同時用兩條心跳線路,這樣一條線路壞了,另一個還是好的,依然能傳送心跳訊息
當檢測到裂腦時強行關閉一個心跳節點(這個功能需特殊設備支持,如Stonith、feyce),相當于備節點接收不到心跳消患,通過單獨的線路發送關機命令關閉主節點的電源
做好對裂腦的監控報警(如郵件及手機短信等或值班).在問題發生時人為第一時間介入仲裁,降低損失,例如,百度的監控報警短信就有上行和下行的區別,報警訊息發送到管理員手機上,管理員可以通過手機回復對應數字或簡單的字串操作回傳給服務器.讓服務器根據指令自動處理相應故障,這樣解決故障的時間更短.
  
當然,在實施高可用方案時,要根據業務實際需求確定是否能容忍這樣的損失,對于一般的網站常規業務.這個損失是可容忍的

6.4腦裂的監控

腦裂的監控是針對于備用服務器,添加zabbix自定義監控
監控的主角是 VIP

VIP存在于備用服務器上的倆種情況:

  • 正常的主服務器和備用服務器之間的切換
  • 發生了腦裂

因此只要備用服務器上存在VIP,則證明主服務器掛掉了
利用zabbix監控腦裂見文章:


7.keepalived實作nginx負載均衡高可用

高可用虛擬VIP:192.168.136.250(公司內應為公網)

系統ip名稱
centos8192.168.136.232master(主)
centos8192.168.136.233slave(備)

關閉防火墻

[root@master ~]# systemctl disable --now  firewalld.service 
[root@master ~]# setenforce 0
[root@slave ~]# systemctl disable --now firewalld
[root@slave ~]# setenforce 0


keepalived安裝

[root@master ~]# yum list all|grep keepalived
keepalived.x86_64                                      2.1.5-6.el8                                            appstream 
[root@master ~]# yum -y install keepalived
[root@slave ~]#  yum -y install keepalived

master和slave服務器上分別安裝nginx

[root@master ~]# yum -y install nginx
[root@slave ~]# yum -y install nginx

master和slave服務器上配置nginx網頁

[root@master ~]# cd /usr/share/nginx/html/
[root@slave html]# ls
404.html  50x.html  index.html  nginx-logo.png  poweredby.png
[root@master html]# mv index.html{,.back}
[root@master html]# echo 'SLAVE' > index.html
[root@master html]# ls
404.html  50x.html  index.html  index.html.back  nginx-logo.png  poweredby.png
[root@master html]# systemctl enable --now nginx
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.
[root@master html]# ss -antl
State       Recv-Q      Send-Q            Local Address:Port             Peer Address:Port      Process      
LISTEN      0           128                     0.0.0.0:80                    0.0.0.0:*                      
LISTEN      0           128                     0.0.0.0:22                    0.0.0.0:*                      
LISTEN      0           128                        [::]:80                       [::]:*                      
LISTEN      0           128                        [::]:22                       [::]:*   

[root@slave ~]# cd /usr/share/nginx/html/
[root@slave html]# ls
404.html  50x.html  index.html  nginx-logo.png  poweredby.png
[root@slave html]# mv index.html{,.back}
[root@slave html]# echo 'SLAVE' > index.html
[root@slave html]# ls
404.html  50x.html  index.html  index.html.back  nginx-logo.png  poweredby.png
[root@slave html]# systemctl enable --now nginx
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.
[root@slave html]# ss -antl
State       Recv-Q      Send-Q            Local Address:Port             Peer Address:Port      Process      
LISTEN      0           128                     0.0.0.0:80                    0.0.0.0:*                      
LISTEN      0           128                     0.0.0.0:22                    0.0.0.0:*                      
LISTEN      0           128                        [::]:80                       [::]:*                      
LISTEN      0           128                        [::]:22                       [::]:*   

在這里插入圖片描述
在這里插入圖片描述

主keepalived配置

#先備份主組態檔
[root@master ~]# cd /etc/keepalived/
[root@master keepalived]# ls
keepalived.conf
[root@master keepalived]# mv keepalived.conf{,.back}
[root@master keepalived]# ls
keepalived.conf.back

#組態檔
[root@master keepalived]# cat keepalived.conf
! Configuration File for keepalived

global_defs {
   router_id lb01   #第一個
}

vrrp_instance VI_1 {
    state MASTER
    interface ens33   #網路介面名稱
    virtual_router_id 99  #倆邊服務器的id必須要一樣
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass caicai666  #密碼最好8位數
    }
    virtual_ipaddress {
        192.168.136.250  #vip
    }
}

virtual_server 192.168.136.250 80 {  #同vip一樣,80服務埠
    delay_loop 6
    lb_algo rr
    lb_kind DR
    persistence_timeout 50
    protocol TCP

 real_server 192.168.136.232 80 {  #主keepalived主機ip地址
        weight 1
        TCP_CHECK {
            connect_port 80
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }

    real_server 192.168.136.233 80 { #備keepalived主機ip地址
        weight 1
        TCP_CHECK {
            connect_port 80
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}

備keepalived配置

#先備份主組態檔
[root@slave ~]# cd /etc/keepalived/
[root@slave keepalived]# ls
keepalived.conf
[root@slave keepalived]# mv keepalived.conf{,.back}
[root@slave keepalived]# ls
keepalived.conf.back

#組態檔
[root@slave keepalived]# vim keepalived.conf
! Configuration File for keepalived

global_defs {
   router_id lb02   #第二個
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33   #網路介面名稱
    virtual_router_id 99  #倆邊服務器的id必須要一樣
    priority 90    //優先級90
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass caicai666  #密碼
    }
    virtual_ipaddress {
        192.168.136.250  #vip
     }
}

virtual_server 192.168.136.250 80 {  #同vip一樣,80服務埠
    delay_loop 6
    lb_algo rr
    lb_kind DR
    persistence_timeout 50
    protocol TCP

 real_server 192.168.136.232 80 {  #主keepalived主機ip地址
        weight 1
        TCP_CHECK {
            connect_port 80
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }  
    real_server 192.168.136.233 80 { #備keepalived主機ip地址
        weight 1
        TCP_CHECK {
            connect_port 80
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}         

啟動keepalived服務,查看VIP

#master服務器上啟動服務,查看vip
[root@master ~]# systemctl enable --now keepalived.service 
[root@master ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:b4:c8:df brd ff:ff:ff:ff:ff:ff
    inet 192.168.136.232/24 brd 192.168.136.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet 192.168.136.250/32 scope global ens33   	 #VIP自動生成了出來
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:feb4:c8df/64 scope link 
       valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 52:54:00:be:03:cf brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
       valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel master virbr0 state DOWN group default qlen 1000
    link/ether 52:54:00:be:03:cf brd ff:ff:ff:ff:ff:ff

#slave服務器上啟動服務,查看vip
[root@slave ~]# systemctl enable --now keepalived.service 
Created symlink /etc/systemd/system/multi-user.target.wants/keepalived.service → /usr/lib/systemd/system/keepalived.service.
[root@slave ~]# ss -antl
State       Recv-Q      Send-Q            Local Address:Port             Peer Address:Port      Process      
LISTEN      0           128                     0.0.0.0:80                    0.0.0.0:*                      
LISTEN      0           128                     0.0.0.0:22                    0.0.0.0:*                      
LISTEN      0           128                        [::]:80                       [::]:*                      
LISTEN      0           128                        [::]:22                       [::]:*                      
[root@slave ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:90:1f:fa brd ff:ff:ff:ff:ff:ff
    inet 192.168.136.233/24 brd 192.168.136.255 scope global dynamic noprefixroute ens33
       valid_lft 1260sec preferred_lft 1260sec
    inet6 fe80::314b:11d8:7c1b:d9bb/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever      
  //只有當主服務器掛了后,備上才會有VIP

#把master服務器的keepalived服務關了
[root@master ~]# systemctl stop keepalived.service 
#自然master服務器沒有了vip,而slave服務器有了VIP
[root@slave ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:90:1f:fa brd ff:ff:ff:ff:ff:ff
    inet 192.168.136.233/24 brd 192.168.136.255 scope global dynamic noprefixroute ens33
       valid_lft 1540sec preferred_lft 1540sec
    inet 192.168.136.250/32 scope global ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::314b:11d8:7c1b:d9bb/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

客戶訪問的是主服務器上的VIP地址,因此主機器和備機器的keepliaved的服務保證開啟,
主服務器的nginx要保證運行中,而備服務器的nginx服務要關閉,
當主上的nginx服務掛掉后keepalived也要相應的關閉,這時VIP會轉到備用主機上,這時備用的nginx服務則要開啟保證服務的正常運行,
但是問題來了,我們不會一直盯著它出現問題再手動進行配置,
針對上述描述,因此腳本是最好的選擇!!!

修改內核引數,開啟監聽VIP功能

[root@master ~]# echo 'net.ipv4.ip_nonlocal_bind = 1' >>/etc/sysctl.conf
[root@master ~]# sysctl -p
net.ipv4.ip_nonlocal_bind = 1
[root@master ~]# cat /proc/sys/net/ipv4/ip_nonlocal_bind
1
[root@slave ~]# echo 'net.ipv4.ip_nonlocal_bind = 1' >> /etc/sysctl.conf 
[root@slave ~]# sysctl -p
net.ipv4.ip_nonlocal_bind = 1
[root@slave ~]# cat /proc/sys/net/ipv4/ip_nonlocal_bind 
1

keepalived通過腳本來控制nginx負載均衡
master服務器上撰寫腳本

[root@master ~]# cd /scripts/
[root@master scripts]# chmod +x check_n.sh
[root@master scripts]# vim check_n.sh 
#!/bin/bash
#!/bin/bash
nginx_status=$(ps -ef|grep -Ev "grep|$0"|grep -c "nginx")
if [ $nginx_status -lt 1 ];then
            systemctl stop keepalived
fi


//check_n.sh腳本的功能:當檢查nginx的行程沒有則代表nginx服務已經掛掉,自動會把keepalived服務關閉

[root@master scripts]# chmod +x notify.sh
[root@master scripts]# cat notify.sh 
#!/bin/bash
#!/bin/bash
VIP=$2
sendmail (){
        subject="${VIP}'s server keepalived state is translate"
        content="`date +'%F %T'`: `hostname`'s state change to master"
        echo $content | mail -s "$subject" xxxxxx@qq.com
}
case "$1" in
  master)
        nginx_status=$(ps -ef|grep -Ev "grep|$0"|grep '\bnginx\b'|wc -l)
        if [ $nginx_status -lt 1 ];then
            systemctl start nginx
        fi
        sendmail
  ;;
  backup)
        nginx_status=$(ps -ef|grep -Ev "grep|$0"|grep '\bnginx\b'|wc -l)
        if [ $nginx_status -gt 0 ];then
            systemctl stop nginx
        fi
  ;;
  *)
        echo "Usage:$0 master|backup VIP"
  ;;
esac
#notify.sh腳本功能:當本機器為master主機時如果nginx服務關閉則會開啟nginx服務,當本機器為backup主機時(也就是沒有了keepalived服務時)會關閉nginx服務,發生故障的狀態資訊,會發送郵件

[root@master ~]# yum -y install mailx postfix
[root@master ~]# systemctl enable --now postfix

slave服務器上撰寫腳本

#同master服務器的notify腳本一樣
[root@slave ~]# mkdir /scripts
[root@slave ~]# cd /scripts/
[root@slave scripts]# chmod +x notify.sh
[root@slave scripts]# cat notify.sh 
subject="${VIP}'s server keepalived state is translate"
        content="`date +'%F %T'`: `hostname`'s state change to master"
        echo $content | mail -s "$subject" 1481583607@qq.com
}
case "$1" in
[root@slave ~]# yum -y install mailx postfix
[root@slave ~]# systemctl enable --now postfix

check_x.sh中的x代表服務,如chck_m.sh代表mysql的服務腳本

配置keepalived加入監控腳本的配置
master服務器上(添加倆處內容)

[root@master ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
  
global_defs {
   router_id lb01
}
vrrp_script nginx_check {            //定義檢查的腳本            
    script "/scripts/check_n.sh"     //指定腳本路徑
    interval 1						//重繪間隔
    weight -20						//優先級減20
}

vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 99
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass caicai666
    }
    virtual_ipaddress {
        192.168.136.250
    }
    track_script {
        nginx_check
    }
    notify_master "/scripts/notify.sh master 192.168.136.250"    //通知腳本的方式
    notify_backup "/scripts/notify.sh backup 192.168.136.250"
}

virtual_server 192.168.136.250 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    persistence_timeout 50
    protocol TCP

 real_server 192.168.136.232 80 {
        weight 1
        TCP_CHECK {
            connect_port 80
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }

    real_server 192.168.136.233 80 {
        weight 1
        TCP_CHECK {
            connect_port 80
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}
#可以多重啟倆次
[root@master scripts]# systemctl start  nginx.service keepalived.service 
[root@master scripts]# systemctl start  nginx.service keepalived.service 

slave服務器上(添加一處內容)

backup時無需檢測nginx是否正常,當升級為MASTER時啟動nginx,當降級為BACKUP時關閉

[root@slave keepalived]# vim keepalived.conf
! Configuration File for keepalived

global_defs {
   router_id lb02   
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33  
    virtual_router_id 99  
    priority 90  
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass caicai666  
    }
    virtual_ipaddress {
        192.168.136.250  
     }
    notify_master "/scripts/notify.sh master 192.168.136.250"  //添加此條
    notify_backup "/scripts/notify.sh backup 192.168.136.250"  //添加此條
}

virtual_server 192.168.136.250 80 {  #
    delay_loop 6
    lb_algo rr
    lb_kind DR
    persistence_timeout 50
    protocol TCP

 real_server 192.168.136.232 80 {  
        weight 1
        TCP_CHECK {
            connect_port 80
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }  
    real_server 192.168.136.233 80 { 
        weight 1
        TCP_CHECK {
            connect_port 80
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}         
[root@slave ~]# systemctl restart keepalived.service 

效果流程:
1.查看主和備服務器的服務情況

#master服務器開啟了nginx服務和keepalived服務,存在VIP
[root@master ~]# ss -antl
State       Recv-Q      Send-Q            Local Address:Port             Peer Address:Port      Process      
LISTEN      0           32                192.168.122.1:53                    0.0.0.0:*                      
LISTEN      0           128                     0.0.0.0:22                    0.0.0.0:*                      
LISTEN      0           5                     127.0.0.1:631                   0.0.0.0:*                      
LISTEN      0           128                     0.0.0.0:111                   0.0.0.0:*                      
LISTEN      0           128                     0.0.0.0:80                    0.0.0.0:*                      
LISTEN      0           128                        [::]:22                       [::]:*                      
LISTEN      0           5                         [::1]:631                      [::]:*                      
LISTEN      0           128                        [::]:111                      [::]:*                      
LISTEN      0           128                        [::]:80                       [::]:*                      
[root@master ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:b4:c8:df brd ff:ff:ff:ff:ff:ff
    inet 192.168.136.232/24 brd 192.168.136.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet 192.168.136.250/32 scope global ens33   //vip
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:feb4:c8df/64 scope link 
       valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 52:54:00:be:03:cf brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
       valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel master virbr0 state DOWN group default qlen 1000
    link/ether 52:54:00:be:03:cf brd ff:ff:ff:ff:ff:ff
[root@master ~]# 

#slave服務器開啟了keepalived服務,nginx處于關閉,沒有vip

[root@slave ~]# ss -antl
State       Recv-Q      Send-Q            Local Address:Port             Peer Address:Port      Process      
LISTEN      0           128                     0.0.0.0:22                    0.0.0.0:*                      
LISTEN      0           128                        [::]:22                       [::]:*     
[root@slave ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:90:1f:fa brd ff:ff:ff:ff:ff:ff
    inet 192.168.136.233/24 brd 192.168.136.255 scope global dynamic noprefixroute ens33
       valid_lft 1298sec preferred_lft 1298sec
    inet6 fe80::314b:11d8:7c1b:d9bb/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

2.模擬主服務器上的nginx發生宕機

[root@master ~]# systemctl stop nginx
[root@master ~]# ss -antl
State       Recv-Q      Send-Q            Local Address:Port             Peer Address:Port      Process      
LISTEN      0           32                192.168.122.1:53                    0.0.0.0:*                      
LISTEN      0           128                     0.0.0.0:22                    0.0.0.0:*                      
LISTEN      0           5                     127.0.0.1:631                   0.0.0.0:*                      
LISTEN      0           128                     0.0.0.0:111                   0.0.0.0:*                      
LISTEN      0           128                        [::]:22                       [::]:*                      
LISTEN      0           5                         [::1]:631                      [::]:*                      
LISTEN      0           128                        [::]:111                      [::]:*            

3.查看vip是否出現在備用主機上

[root@slave ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:90:1f:fa brd ff:ff:ff:ff:ff:ff
    inet 192.168.136.233/24 brd 192.168.136.255 scope global dynamic noprefixroute ens33
       valid_lft 1116sec preferred_lft 1116sec
    inet 192.168.136.250/32 scope global ens33 //VIP
       valid_lft forever preferred_lft forever
    inet6 fe80::314b:11d8:7c1b:d9bb/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

4.slave服務器上的nginx服務自動開啟了服務

[root@slave ~]# ss -antl
State       Recv-Q      Send-Q            Local Address:Port             Peer Address:Port      Process      
LISTEN      0           128                     0.0.0.0:80                    0.0.0.0:*                      
LISTEN      0           128                     0.0.0.0:22                    0.0.0.0:*                      
LISTEN      0           100                   127.0.0.1:25                    0.0.0.0:*                      
LISTEN      0           128                        [::]:80                       [::]:*                      
LISTEN      0           128                        [::]:22                       [::]:*                      
LISTEN      0           100                       [::1]:25                       [::]:*                      
[root@slave ~]# 

進行訪問
在這里插入圖片描述
當master的nginx服務修復之后,關閉slave上的nginx服務,則恢復到了之前的狀態,

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/342055.html

標籤:其他

上一篇:MySQL 中 localhost 與 127.0.0.1 的區別

下一篇:nginx配置http和https

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more