Keepalived服務詳解
1. VRRP協議
1.1 VRRP協議概述
- VRRP協議的出現是為了解決靜態路由的單點故障,它是通過一種競選機制來將路由任務交給某個vrrp路由器的
- 在VRRP物理結構中,有多個物理的VRRP路由器,其中有一台稱為「master」(主節點路由器),其他的都是「backup」(備節點路由器)
- master和backup的身份,是通過他媽的優先級來定義競選的
- 在VRRP虛擬結構中,虛擬路由都是通過「MAC+VRID」的形式來標識的,如「00-00-5E-00-01-{VRID}」
- 只有master節點才會發送VRRP廣告包(vrrp advertisement message)
- 當master節點宕掉的時候,backup中優先級最高的VRRP設備會搶佔並升級為master
1.2 VRRP的術語
- 虛擬路由器
- 由一個Master路由器和多個Backup路由器組成,主機將虛擬路由器當做默認網關(將Master和Backup看做一個整體)
- VRID
- 虛擬路由器的標識,有相同的VRID的一組路由器構成一個虛擬路由器
- Master路由器
- 虛擬路由器中承擔報文轉發任務的路由器
- Backup路由器
- 虛擬路由器中備份節點路由器
- 虛擬IP地址
- 虛擬路由器的IP地址,一個虛擬路由器可以擁有一個或多個IP地址
- VIP
- IP地址擁有者,接口IP地址與虛擬IP地址相同的路由器被稱為IP地址擁有者
- VMAC
- 虛擬MAC地址,一個虛擬路由器擁有一個虛擬MAC地址,通常情況下,虛擬路由器回應ARP請求使用的是虛擬MAC地址
- 優先級
- VRRP根據優先級來確定虛擬路由器中每台路由器的地位
- 非搶佔式
- 如果backup路由器工作在此模式下,則若Master路由器沒有出現故障,backup即使隨後被配置了更高的優先級也不會成為Master
- 搶佔式
- 如果backup路由器工作在搶佔方式下,當它收到VRRP報文後,會將主機的優先級與通告報文中的優先級進行比較,
- 如果主機的優先級比當前的Master路由器的優先級高,就會主動搶佔成為Master路由器,否則,將保持Backup狀態
1.3 VRRP的工作過程
- 虛擬路由器中的路由器根據優先級選舉出Master
- Master路由器通過發送免費ARP報文,將主機的虛擬MAC地址通知給它連接的設備或者主機,從而承擔報文轉發任務
- Master路由器周期性發送VRRP報文,以公布其配置信息(優先級等)和工作狀況
- 如果Master路由器出現故障,虛擬路由器中的Backup路由器將根據優先級重新選舉出新的Master
- 虛擬路由器狀態切換時,Master路由器由一台設備切換為另一台設備
- 新的Master路由器發送一個攜帶虛擬路由器的MAC地址和虛擬IP地址信息的免費ARP報文,以更新與它連接的主機中的ARP相關的信息
- 網路中的主機感知不到Master路由器已經切換為另外一台設備
- Backup路由器的優先級高於Master路由器時,由Backup路由器的工作方式(搶佔方式和非搶佔方式)決定是否重新選舉Master
- 為了保證Master路由器和Backup路由器能夠協調工作,VRRP需要實現以下功能
- Master路由器的選舉
- Master路由器狀態的通告
- 為了提高安全性,VRRP還提供了認證功能
1.4 Master路由器的選舉
- VRRP根據優先級來確定虛擬路由器中每台路由器的角色(Master路由器或Backup路由器),優先級越高,則越有可能成為Master路由器
- 初始創建的路由器在Backup狀態,通過VRRP報文獲知虛擬路由器中其他成員的優先級
- 如果VRRP報文中Master路由器的優先級高於自己的優先級,則路由器保持在Backup狀態
- 如果VRRP報文中Master路由器的優先級低於自己的優先級
- 採用搶佔工作方式的路由器將搶佔成為Master狀態,周期性的發送VRRP報文
- 採用非搶佔式工作方式的路由器仍保持Backup狀態
- 如果在一定時間內沒有收到VRRP報文,則路由器切換為Master狀態
- VRRP優先級的取值範圍為0到255(數值越大優先級越高),可配置的範圍是1到254
- 優先級0為系統保留給路由器放棄Master位置時候使用,255則是系統保留給IP地址擁有者使用
- 當路由器為IP地址擁有者時,其優先級始終為255,因此當虛擬路由器內存在IP地址擁有者時,只要其工作正常,則為Master路由器
1.5 Master路由器狀態的通告
- Master路由器周期性發送VRRP報文,在虛擬路由器中公布其配置信息(優先級等)和工作狀況
- Backup路由器通過接收到VRRP報文的情況來判斷Master路由器是否工作正常
- Master路由器主動放棄Master地位(如Master路由器退出虛擬路由器)時
- 會發送優先級為0的VRRP報文,致使Backup路由器快速切換變成Master路由器,這個切換時間稱為Skew time
- 計算方式為(256-Backup路由器的優先級)/256,單位為秒
- 當Master路由器因故障不能發送VRRP報文時,Backup路由器並不能立即知道其工作狀況
- Backup路由器等待一段時間後,如果還沒接收到VRRP報文,那麼會認為Master路由器無法正常工作,而把自己升級為Master路由器,周期性發送VRRP報文,如果此時多個Backup路由器競爭Master路由器的位置,將通過優先級來選舉Master路由器,Backup路由器默認等待的時間稱為Master_Down_Interval,取值為:(3*VRRP報文的發送時間間隔)+Skewtime,單位為秒
- 說明
- 在性能不夠穩定的網絡中,Backup路由器可能因為網絡堵塞而在Master_Down_Interval期間沒有收到Master路由器的報文而主動搶佔為Master位置,如果此時原Master路由器的報文又到達了,就會出現虛擬路由器的成員頻繁的進行Master搶佔現象,為了緩解這種現象的發生,特制定了延遲等待定時器,它可以使得Backup路由器在等待了Master_Down_Interval後,再等待延遲等待時間,如在此期間仍然沒有收到VRRP報文,此時Backup路由器才會切換為Master路由器,對外發送VRRP報文
1.6 認證方式
1)無認證
- 不進行任何VRRP報文的合法性認證,不提供安全性保障
2)簡單字符認證
- 在一個有可能受到安全威脅的網絡中,可以將認證方式設置為簡單字符認證(一般就採用這種認證)
- 發送VRRP報文的路由器將認證字填入到報文中,而收到VRRP報文的路由器會將收到的VRRP報文中的認證字和本地配置的認證字進行比較,如果認證字相同,則認為接受到的報文是合法的VRRP報文,否則認為接收到的報文是一個非法報文
3)MD5認證
- 在一個非常不安全的網絡中,可以將認證方式設置為MD5認證
- 發送VRRP報文的路由器利用認證字和MD5算法對VRRP報文進行加密,加密後的報文保存在Authentication Header(認證頭)中,收到VRRP報文的路由器會利用認證字解密報文,檢查該報文的合法性
2. keepalived
2.1 keepalived概述
1)keepalived的功能
- 對後端RealServer進行健康狀況檢查,支持4層、5層和7層協議進行健康檢查
- 對負載均衡器進行高可用,防止Director單點故障
2)keepalived的運作
- 通過VRRP(Virtual Router Redundancy Protocol)虛擬路由冗餘協議來實現故障轉移。
- keepalived正常工作時,主節點(master)會不斷的發送心跳信息給備節點(backup)
- 當備節點在一定時間內沒有收到主節點的心跳信息時,備節點會認為主節點宕了,就會接管主節點上的資源,並繼續向外提供服務保證其可用性
- 當主節點恢復時,備節點會自動讓出資源並再次自動成為備節點
3)keepalived監控LVS
- 使用keepalived監控、高可用LVS集群時(keepalived+lvs),並不需要在Director上使用ipvsadm額外配置ipvs規則。
- 因為keepalived中集合了管理ipvs規則的組件(ipvs wrapper),可以直接在keepalived的配置文件中配置ipvs相關規則,在解析配置文件時會通過特定的組件將規則發送給到內核中的ipvs模塊。
2.2 keepalived軟件結構
1)VRRP協議
- vrrp協議在Linux主機上以守護進程方式的實現,原生設計目的是為了高可用ipvs服務
- 能夠根據配置文件生成ipvs規則,並對各RS的健康做檢測
- vrrp_script
- vrrp_track
- 基於vrrp協議完成地址滾動
- 為vip地址所在的節點生成ipvs規則(在配置文件中預先定義)
- 基於腳本調用接口通過執行腳本完成腳本中定義的功能,進而影響集群事務
2)keepalived的組件
- keepalived服務啟動時,將產生三個相關進程,一個父進程和兩個子進程
- 主進程:Watchdog看門狗主進程
- 子進程1:VRRP Child
- 子進程2:Healthchecking Child
- 兩個子進程都會開啟本地套接字Unix Domain Socket
- 當keepalived服務啟動後,父進程會通過unix domain socket每隔5秒發送一個hello消息給子進程
- 如果父進程無法發送消息給子進程,將認為子進程出現問題,於是會重啟子進程
- 核心組件
- Watchdog
- 看門狗,負責fork和監控子進程,對Checkers和vrrp stack進行監控
- Checkers
- 負責RealServer的健康狀況檢查,並在LVS的拓撲中移除、添加RealServer
- 它支持layer4/5/7層的協議檢查,該組件使用獨立的子進程負責,但被父進程監控
- VRRP Stack
- 提供Director的故障轉移功能從而實現Director的高可用
- 該組件可獨立提供功能,無需LVS的支持,該組件使用獨立的子進程負責,但被父進程監控
- System Call
- 提供讀取自定義腳本的功能,該組件在使用時,將臨時產生一個子進程來執行任務
- IPVS wrapper
- 負責將配置文件中的IPVS相關規則發送到內核的ipvs模塊
- Netlink Reflector
- 用來設定、監控vrrp的ip地址
- Watchdog
- IO復用器
- 內存管理
- 配置文件分析器
3)工作模型
- 主備:單虛擬路由器
- 主主:主/備(虛擬路由器1)+ 備/主(虛擬路由器2)
3. keepalived的配置和使用
3.1 使用前的配置
- 各節點時間要同步
- 確保iptables和selinux不會成為阻礙
- 確保各節點的用於集群服務的接口支持MULTICAST通信
- 開啟網卡的多播功能:ip link set multicast on dev ens33
- D類地址:224-239(多播地址的範圍)
- 各節點之間可通過主機名互相通信(可選)
- 節點的名稱設定與hosts文件中解析的主機名都要保持一致
- uname -n 獲得的主機,與解析的主機名要相同
- 各節點之間基於密鑰認證的方式通過ssh互相通信(可選)
3.2 程序環境
- 主程序文件
- /usr/sbin/keepalived
- Unit file
- /usr/lib/systemd/system/keepalived.service
- Unix file 的配置文件:/etc/sysconfig/keepalived
- 配置文件
- /etc/keepalived/keepalived.conf
3.3 配置文件概述
# 全局配置(全局配置有Global definitions和Static routes/address,全局定義和靜態路由) # GLOBAL CONFIGURATION: global_defs # Block id { ... } # 配置vrrp實例(VRRP實例和VRRP同步組) # VRRPD CONFIGURATION: vrrp instance # 虛擬路由器,VRRP實例 vrrp_instance NAME { ... } vrrp synchronization group # VRRP同步組 vrrp_sync_group NAME { ... } # ipvs的相關配置 # LVS CONFIGURATION: # 集群服務,服務內的RS Virtual server groups Virtual server #ipvs集群的vs和rs
- 如果多個實例同進同退,那麼就要把他們配置成一個同步組(高可用LVS的NAT模式時)
- 如下圖所示,當vip1在網卡1上時,vip2必須要在網卡2上,所以vip1和vip2必須同進同退
- vip1在哪個節點上,vip2就應該在哪個節點上
3.4 配置文件詳解
1)全局配置
### 全局配置 ### global_defs { # 全局部分定義郵件報警系統,可以不用定義 notification_email { # 定義郵件發送目標,收件人郵箱地址 [email protected] [email protected] } notification_email_from [email protected] # 定義發件人郵箱地址 smtp_server 192.168.200.1 # 定義郵件發送服務器IP,本地發送寫localhost smtp_connect_timeout 30 # 定義郵件服務器建立連接的超時時長 router_id c7_node_03 # 標識keepalived服務器的字符串,物理節點的標識符;建議使用主機名 vrrp_skip_check_adv_addr # 如果通告與接收的上一個通告來自相同的master路由器,則不執行檢查 !vrrp_strict # 嚴格遵守VRRP協議,這一項最好關閉(加感嘆號),若不關閉,可用vip無法被ping通 vrrp_garp_interval 0.001 # 在一個接口發送的兩個免費ARP之間的延遲,可以精確到毫秒級(默認是0) vrrp_mcast_group4 225.0.0.18 # IPV4多播地址,默認224.0.0.18,要改一改 # 可以在多播地址上抓包來看vrrp報文:tcpdump -i ens33 -nn host 224.0.0.18 }
2)vrrp實例配置
### VRRP實例配置 ### vrrp_instance NAME { state MASTER # 定義實例的角色狀態是master還是backup,在當前VRRP實例中此節點的初始狀態 interface eth0 # 定義vrrp綁定的接口,即接收或發送心跳通告的接口,即HA監測接口 virtual_router_id 51 # 虛擬路由標識(VRID),同一實例該數值必須相同,即master和backup中該值要相同 # 同一網卡上的不同vrrp實例,該值一定不能相同,取值範圍為0-255,默認為51 priority 100 # 該vrrp實例中本機的keepalived的優先級,優先級最高的為master(可用範圍0-255) # 該選項的優先級高於state選項, # 即若state指定的是backup,但這裡設置的值最高,則仍為master advert_int 1 # 心跳信息發送和接收時間間隔,單位為秒 authentication { # 認證方式,同一實例中這個配置必須完全一樣才可通過認證,只建議使用PASS認證 auth_type PASS # 使用簡單字符認證的方式 auth_pass 1111 # 最多支持8字符,超過8字符將只取前8字符 } virtual_ipaddress { # 設置的VIP,當master出現故障後,VIP會故障轉移到backup # 這些vip默認配置在interface指定的接口別名上,可使用dev選項來指定配置接口 # 使用ip add的方式添加,若要被ifconfig查看,在IP地址後加上label即可 192.168.200.16 label eth0:1 192.168.200.17 192.168.200.19/24 dev eth1 # 格式:<IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPE> label <LABEL> } # 使用非搶佔模式 nopreempt # 使用延遲搶佔模式 preempt_delay TIME }
3)定義通知腳本
- 定義格式:可以通過notify參數來實現master和backup的切換,且可以附加執行通知腳本
vrrp_instance { ... notify_master <STRING>|<QUOTED-STRING> # 當切換到master模式時,執行此腳本 notify_backup <STRING>|<QUOTED-STRING> # 當切換到backup模式時,執行此腳本 notify_fault <STRING>|<QUOTED-STRING> # 當切換到fault模式時,執行此腳本 notify <STRING>|<QUOTED-STRING> }
- 定義示例
vrrp_instance { ... notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault" }
- 腳本示例
#!/bin/bash # Author: hgzerowzh # Description: An notify script # contact='root@localhost' notify() { mailsubject="$(hostname) to be $1: vip floating" mailbody="$(date +'%F %H:%M:%S'): vrrp transition, $(hostname) changed to be $1" echo $mailbody | mail -s "$mailsubject" $contact } case $1 in master) notify master exit 0 ;; backup) notify backup exit 0 ;; fault) notify fault exit 0 ;; *) echo "Usage: $(basename $0) {master|backup|fault}" exit 1 ;; esac
3.5 雙主配置示例
1)配置圖示
2)配置示例
### node1:### vrrp_instance VI_1 { state MASTER interface eno16777736 virtual_router_id 101 priority 100 advert_int 1 authentication { auth_type PASS auth_pass ZPNnTQ6F } virtual_ipaddress { 172.16.100.9/16 } } vrrp_instance VI_2 { state BACKUP interface eno16777736 virtual_router_id 102 priority 99 advert_int 1 authentication { auth_type PASS auth_pass IWyijM5Q } virtual_ipaddress { 172.16.100.10/16 } } ### node2:### vrrp_instance VI_1 { state BACKUP interface eno16777736 virtual_router_id 101 priority 99 advert_int 1 authentication { auth_type PASS auth_pass ZPNnTQ6F } virtual_ipaddress { 172.16.100.9/16 } } vrrp_instance VI_2 { state MASTER interface eno16777736 virtual_router_id 102 priority 100 advert_int 1 authentication { auth_type PASS auth_pass IWyijM5Q } virtual_ipaddress { 172.16.100.10/16 } }
4. keepalived中配置ipvs
4.1 ipvs配置語法格式
1)定義Virtual Server
virutal_server vip port { # 虛擬服務地址和端口,使用空格分隔,其中地址為VIP ... } virtual_server fwmark int { # 可以使用防火牆標記來定義 ... } ### 常用的參數 ### delay_loop <INT> # 對後端主機做檢測,每隔多長時間發一次請求 lb_algo rr|wrr|lc|wlc|lblc|sh|dh # 調度算法 lb_kind NAT|DR|TUN # 集群類型 persistence_timeout <INT> # 持久連接時長 protocol TCP # 1.3.0版本之前只支持TCP sorry_server <IPADDR> <PORT> # 當所有的RS都掛掉,則使用這裡定義的主機提供服務
2)定義Real Server & 健康狀態檢測
real_server <IPADDR> <PORT> { ### 常用的參數 ### weight <INT> # 權重 notify_up <STRING>|<QUOTED-STRING> # 上線腳本 notify_down <STRING>|<QUOTED-STRING> # 下線腳本 ... ### 健康狀態檢測機制(web應用層檢測) HTTP_GET|SSL_GET { # 檢測參數 url { path <STRING> # 對哪個url做檢測,使用path指明url status_code <INT> # 要獲得什麼響應碼才算正確 digest <STRING> # 獲取內容的校驗碼跟所期望的一樣 } nb_get_retry <INT> # get請求的重試次數 delay_before_retry <INT> # 兩次重試之間的時間間隔 connect_timeout <INTEGER> # 連接超時時長,默認為5s warmup <INT> # 健康狀態檢測延遲 } ### 傳輸層健康狀態檢測(tcp協議層) TCP_CHECK { # 檢測參數 connect_timeout <INTEGER> # 每次發起連接時的超時時間 nb_get_retry <INT> # get請求的重試次數 delay_before_retry <INT> # 兩次重試之間的時間間隔 connect_timeout <INTEGER> # 連接超時時長,默認為5s warmup <INT> # 健康狀態檢測延遲 # 其它參數 connect_ip <IP ADDRESS> # 向哪個地址的哪個端口做檢測 connect_port <PORT> bindto <IP ADDRESS> # 自己使用固定的地址當源地址發請求 bind_port <PORT> } }
4.2 keepalived + LVS(NAT)
1)主節點的配置
! Configuration File for keepalived global_defs { notification_email { 492540654@qq.com 2469822904@qq.com } notification_email_from hgzero@localhost smtp_server localhost smtp_connect_timeout 30 router_id c7_node_03 vrrp_skip_check_adv_addr ! vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0 vrrp_mcast_group4 225.0.0.18 } vrrp_instance VI_1 { state MASTER interface ens37 virtual_router_id 66 priority 100 advert_int 1 authentication { auth_type PASS auth_pass niba } virtual_ipaddress { 172.168.1.99/24 # 這個虛擬ip是流動網關地址 } } vrrp_instance VI_2 { state MASTER interface ens33 virtual_router_id 67 priority 100 advert_int 1 authentication { auth_type PASS auth_pass taba } virtual_ipaddress { 10.0.0.11/24 # 這個虛擬ip是外網訪問的浮動ip } } # 將VI_1和VI_2做成一個同步組,在這個節點上,VI_1和VI_2同進退 vrrp_sync_group VG_1 { group { VI_1 VI_2 } } # 虛擬服務地址和端口,使用空格分隔,其中地址為外網VIP virtual_server 10.0.0.11 80 { delay_loop 2 # 健康檢查時間間隔 lb_algo rr # 定義負載均衡LB的算法,這裡使用的是rr輪詢調度算法 lb_kind NAT # lvs的模型,有NAT、DR、TUN三種 ! persistence_timeout 3 # 持久會話保持時長 protocol TCP # 監控服務的協議類型,1.3.0版本之前只支持tcp,之後還支持udp real_server 172.168.1.101 80 { # 定義後端的real_server部分,地址和端口使用空格分隔 weight 1 # lvs權重 HTTP_GET { # 監控狀況檢查的檢查方式,常見的有HTTP_GET、SSL_GET、TCP_CHECK、MISC_CHECK url { path / # 指定http_get健康狀況檢查的路徑,例如檢查index.html是否正常 status_code 200 # 健康狀況需要狀態碼,可以是status_code、digest、或者digest+status_code # digest值用keepalived的genhash命令生成,一般使用status_code即可 # curl -s //172.168.0.6 | md5sum # genhash -s 172.168.0.6 -p 80 -u /index.html } connect_timeout 2 nb_get_retry 3 delay_before_retry 1 } } real_server 172.168.1.102 80 { weight 1 HTTP_GET { url { path / status_code 200 } connect_timeout 2 # 表示3秒無響應就超時,即此realserver不健康,需重試連接 nb_get_retry 3 # 表示重試3次,3次之後都超時就是宕機,防止誤傷(nb=number) delay_before_retry 1 # 重試的時間間隔 } # 時間如果太久,應改小 } }
2)備節點的配置
! Configuration File for keepalived global_defs { notification_email { 492540654@qq.com 2469822904@qq.com } notification_email_from hgzero@localhost smtp_server localhost smtp_connect_timeout 30 router_id c7_node_04 vrrp_skip_check_adv_addr ! vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0 vrrp_mcast_group4 225.0.0.18 } vrrp_instance VI_1 { state BACKUP interface ens37 virtual_router_id 66 priority 99 advert_int 1 authentication { auth_type PASS auth_pass niba } virtual_ipaddress { 172.168.1.99/24 } } vrrp_instance VI_2 { state BACKUP interface ens33 virtual_router_id 67 priority 99 advert_int 1 authentication { auth_type PASS auth_pass taba } virtual_ipaddress { 10.0.0.11/24 } } vrrp_sync_group VG_1 { group { VI_1 VI_2 } } virtual_server 10.0.0.11 80 { delay_loop 2 lb_algo rr lb_kind NAT ! persistence_timeout 3 protocol TCP real_server 172.168.1.101 80 { weight 1 HTTP_GET { url { path / status_code 200 } connect_timeout 2 nb_get_retry 3 delay_before_retry 1 } } real_server 172.168.1.102 80 { weight 1 HTTP_GET { url { path / status_code 200 } connect_timeout 2 nb_get_retry 3 delay_before_retry 1 } } }
4.3 keepalived + LVS(DR)
1)主節點的配置
! Configuration File for keepalived global_defs { notification_email { 492540654@qq.com 2469822904@qq.com } notification_email_from hgzero@localhost smtp_server localhost smtp_connect_timeout 30 router_id c7_node_03 vrrp_skip_check_adv_addr ! vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0 vrrp_mcast_group4 225.0.0.16 } vrrp_instance VI_1 { state MASTER interface ens33 virtual_router_id 66 priority 100 advert_int 1 authentication { auth_type PASS auth_pass niba } virtual_ipaddress { 10.0.0.10 } } virtual_server 10.0.0.10 80 { delay_loop 2 lb_algo wrr lb_kind DR ! persistence_timeout 3 protocol TCP real_server 10.0.0.205 80 { weight 2 HTTP_GET { url { path / status_code 200 } connect_timeout 2 nb_get_retry 3 delay_before_retry 1 } } real_server 10.0.0.206 80 { weight 1 HTTP_GET { url { path / status_code 200 } connect_timeout 2 nb_get_retry 3 delay_before_retry 1 } } }
2)備節點的配置
! Configuration File for keepalived global_defs { notification_email { 492540654@qq.com 2469822904@qq.com } notification_email_from hgzero@localhost smtp_server localhost smtp_connect_timeout 30 router_id c7_node_04 vrrp_skip_check_adv_addr ! vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0 vrrp_mcast_group4 225.0.0.16 } vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 66 priority 99 advert_int 1 authentication { auth_type PASS auth_pass niba } virtual_ipaddress { 10.0.0.10 } } virtual_server 10.0.0.10 80 { delay_loop 2 lb_algo wrr lb_kind DR ! persistence_timeout 3 protocol TCP real_server 10.0.0.205 80 { weight 2 HTTP_GET { url { path / status_code 200 } connect_timeout 2 nb_get_retry 3 delay_before_retry 1 } } real_server 10.0.0.206 80 { weight 1 HTTP_GET { url { path / status_code 200 } connect_timeout 2 nb_get_retry 3 delay_before_retry 1 } } }
3)在DR模式中各個Real Server上的自定義腳本
- 要在每個Real Server上執行此腳本
#!/bin/bash vip=10.0.0.10 mask='255.255.255.255' case $1 in start) echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce ifconfig lo:0 $vip netmask $mask broadcast $vip up route add -host $vip dev lo:0 ;; stop) ifconfig lo:0 down echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce ;; *) echo "Usage $(basename $0) start|stop" exit 1 ;; esac
5. keepalived高可用nginx
5.1 keepalived高可用其他服務
1)原理
- keepalived調用外部的輔助腳本進行資源監控,並根據監控的結果狀態能實現優先動態調整
2)步驟
- 定義一個腳本
vrrp_script <SCRIPT_NAME> { # 腳本名,後面要基於腳本名來進行調用 script "/script.sh" # 執行的命令或腳本 interval INT # 每隔多少時間,這個監控腳本要執行一次 weight -INT # 萬一失敗了,當前節點的權重要減去多少,一般來講講,減去後的值要小於備用節點 }
- 調用此腳本
# 在某個vrrp的示例中去調用腳本實例 track_script { SCRIPT_NAME_1 SCRIPT_NAME_2 ... }
5.2 keepalived高可用nginx
1)配置keepalived.conf文件
global_defs { notification_email { root@localhost } notification_email_from keepalived@localhost smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id node1 vrrp_mcast_group4 224.0.100.19 } # 如果想要調整某個keepalived主機,只需要在keepalived目錄下創建一個down文件 # 通過監測這個文件的存在與否,即可將該節點權重降低,從而可以去配置調整它 # 如果不想讓它降權了,就將down文件刪除 vrrp_script chk_down { # 如果這個文件存在就錯誤退出,否則就正常退出 script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0" # 注意,這裡最好將腳本寫入shell文件中,然後在這裡調用shell腳本文件,注意用全路徑 interval 1 weight -5 # 一旦上面的文件存在(錯誤退出),就將這個節點降權 fall 1 rise 1 } vrrp_script chk_nginx { script "killall -0 nginx && exit 0 || exit 1" # 這裡killall -0表示檢測nginx進程是否存在 # 注意,這裡最好將腳本寫入shell文件中,然後在這裡調用shell腳本文件,注意用全路徑 interval 1 # 每隔一秒檢測一次上面的腳本是否能成功執行 weight -5 # 如果腳本執行失敗就將權重-2 fall 3 # 如果失敗3次失敗,才確認為失敗 rise 3 # 需要成功的次數,如果3次檢查都成功,那麼就立即將減去的權重加回去 } vrrp_instance VI_1 { state MASTER interface eno16777736 virtual_router_id 14 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 571f97b2 # 如果有多個vrrp實例,這裡的密碼一定不能相同 } vritual_ipaddress { 10.1.0.93/16 dev eno16777736 } track_script { # 在這裡來調用之前的腳本 chk_down chk_nginx } notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault" }
2)定義notify腳本
#!/bin/bash # contact='root@localhost' notify() { local mailsubject="$(hostname) to be $1, vip floating" local mailbody="$(date + '%F %T' ): vrrp transition, $(hostname) changed to be $1" echo "$mailbody" | mail -s "$mailsubject" $contact } case $1 in master) # 噹噹前節點變成主節點的時候,就啟用nginx服務 systemctl start nginx.service notify master ;; backup) # 噹噹前節點變成備用節點的時候,要啟用nginx,防止備節點也被降權,導致vip沒有被轉移 systemctl start nginx.service notify backup ;; fault) # 噹噹前節點出錯時,就停掉nginx服務(但是如果做nginx的雙主,即使fault也不能停掉nginx) systemctl stop nginx.service notify fault ;; *) echo "Usage: $(basename $0) { master|backup|fault}" exit 1 ;; esac
3)其他相關
# 監控關注的網絡接口 track_interface { IFACE_NAME_1 IFACE_NAME_2 } # 在nginx上配置反向代理: upstream websrvs { server 192.168.10.11:80; server 192.168.10.12:80; } location / { proxy_pass http:/websrvs; }