Nginx+Keepalived實現站點高可用
vrrp
虛擬路由冗余協議(Virtual Router Redundancy Protocol,簡稱VRRP)是由IETF提出的解決局域網中配置靜態網關出現單點失效現象的路由協議,1998年已推出正式的RFC2338協議標準。VRRP廣泛應用在邊緣網絡中,它的設計目標是支持特定情況下IP數據流量失敗轉移不會引起混亂,允許主機使用單路由器,以及及時在實際第一跳路由器使用失敗的情形下仍能夠維護路由器間的連通性。
1、vrrp相關術語,摘自H3C VRRP白皮書
虛擬路由器:由一個 Master 路由器和多個 Backup 路由器組成。主機將虛擬路由器當作默認網關。
VRID:虛擬路由器的標識。有相同 VRID 的一組路由器構成一個虛擬路由器。
Master 路由器:虛擬路由器中承擔報文轉發任務的路由器。
Backup 路由器: Master 路由器出現故障時,能夠代替 Master 路由器工作的路由器。
虛擬 IP 地址:虛擬路由器的 IP 地址。一個虛擬路由器可以擁有一個或多個IP地址。
IP 地址擁有者:接口 IP 地址與虛擬 IP 地址相同的路由器被稱為IP地址擁有者。
虛擬 MAC 地址:一個虛擬路由器擁有一個虛擬MAC地址。虛擬MAC地址 的格式為 00-00-5E-00-01-{VRID}。通常情況下,虛擬路由器回應 ARP 請求使用的是虛擬MAC地址,只有虛擬路由器做特殊配置的時候,才回應接口的真實 MAC 地址。
優先級: VRRP 根據優先級來確定虛擬路由器中每臺路由器的地位。
非搶占方式:如果 Backup 路由器工作在非搶占方式下,則只要 Master 路由器沒有出現故障, Backup 路由器即使隨后被配置了更高的優先級也不會成為Master 路由器。
搶占方式:如果 Backup 路由器工作在搶占方式下,當它收到 VRRP 報文后,會將自己的優先級與通告報文中的優先級進行比較。如果自己的優先級比當前的 Master 路由器的優先級高,就會主動搶占成為 Master 路由器;否則,將保持 Backup 狀態。
VRRP的工作過程為:
1) 虛擬路由器中的路由器根據優先級選舉出 Master。Master路由器通過發送免費ARP報文,將自己的虛擬MAC地址通知給與它連接的設備或者主機,從而承擔報文轉發任務
2) Master 路由器周期性發送 VRRP 報文,以公布其配置信息(心跳,優先級等)和工作狀況;
3) 如果 Master 路由器出現故障,虛擬路由器中的 Backup 路由器將根據優先級重新選舉新的 Master;
4) 虛擬路由器狀態切換時, Master 路由器由一臺設備切換為另外一臺設備,新的 Master 路由器只是簡單地發送一個攜帶虛擬路由器的 MAC 地址和虛擬 IP地址信息的免費 ARP 報文,這樣就可以更新與它連接的主機或設備中的ARP 相關信息。網絡中的主機感知不到 Master 路由器已經切換為另外一臺設備。
5) Backup 路由器的優先級高于 Master 路由器時,由 Backup 路由器的工作方式(搶占方式和非搶占方式)決定是否重新選舉 Master。
VRRP的功能:
Master 路由器的選舉;
Master 路由器狀態的通告;心跳,優先級等;
提高安全性的認證功能;簡單字符認證,MD5認證
VRRP工作模式:
1、主備備份;主備備份方式表示業務僅由Master路由器承擔。當Master路由器出現故障時,才會由選舉出來的Backup路由器接替它工作。初始情況下, Device A是Master路由器并承擔轉發任務, Device B和Device C是Backup路由器且都處于就緒監聽狀態。如果Device A發生故障,則虛擬路由器內處于Backup狀態的Device B和Device C路由器將根據優先級選出一個新的Master路由器,這個新Master路由器繼續為網絡內的主機轉發數據。如下圖;
2、主主備份;在路由器的一個接口上可以創建多個虛擬路由器,使得該路由器可以在一個虛擬路由器中作為Master路由器,同時在其他的虛擬路由器中作為Backup路由器。多臺路由器同時承擔業務,式需要兩個或者兩個以上的虛擬路由器,每個虛擬路由器都包括一個Master路由器和若干個Backup路由器,各虛擬路由器的Master路由器可以各不相同,實現負載分擔。如下圖;
Keepalived介紹
Keepalived是一個基于VRRP協議來實現的服務高可用方案,可以利用其來避免IP單點故障,原生設計的目的為了高可用ipvs服務:實現基于vrrp協議完成地址流動,根據配置文件中的定義為vip地址所在的節點生成ipvs規則,為ipvs集群的各RS做健康狀態檢測,基于腳本調用接口通過執行腳本完成腳本中定義的功能,進而影響集群事務;
程序組件:
1、核心組件
2、控制組件:配置文件分析器
3、IO復用器
4、內存管理組件
核心組件如下;
Watch dog:高可用監視器
checkers:健康狀態檢測器(TCP、HTTP、SSL、MISC… …)
smtp:支持發送郵件通告機制
System call:支持系統調用機制,作出管理操作
vrrp stack:VRRP棧的實現,實現VRRP協議調用
Netlink Reflectior:VRRP借助于Netlink監控網絡,實現網絡功能配置
ipvs wrapper:ipvs控制
keepalived高可用集群配置前提
1)各節點時間要同步;必須不能超過一秒,一般使用網絡時間同步服務器(ntp, chrony)
2)確保iptables及selinux不會成為障礙;
3)各節點之間可通過主機名互相通信(對KA并非必須);節點的名稱設定與hosts文件中解析的主機名都要保持一致; #uname -n 獲得的主機,與解析的主機名要相同;建議使用/etc/hosts文件實現
4)各節點之間的root用戶可以基于密鑰認證的ssh服務完成互相通信;(并非必須)
keepalived程序環境配置
keepalived在CentOS 6.4+收錄到發行版光盤內,否則需要編譯安裝或者第三方RPM包
程序環境:
1)配置文件:/etc/keepalived/keepalived.conf
2)主程序:/usr/sbin/keepalived
3)Unit File:keepalived.service
配置文件組件部分:
1)GLOBALCONFIGURATION:全局配置有兩個組件組成 Global definitions:全局定義 Static routes/addresses:靜態路由配置 2)VRRPDCONFIGURATION:配置vrrp VRRP synchronization group(s):VRRP同步組 VRRP instance(s):VRRP實例,即定義虛擬路由器 3)LVSCONFIGURATION:ipvs的相關配置集群服務,服務內的RS; Virtual server group(s):虛擬服務組 Virtual server(s):虛擬服務示例的定義
GLOBALCONFIGURATION:全局配置
常用配置參數: notification_email{…}:收件人郵箱地址 notification_email_from:發件人郵箱地址 smtp_server:郵件發送服務器IP; smtp_connect_timeout:郵件服務器建立連接的超時時長;默認30秒 router_id LVS_DEVEL:物理節點的標識符;建立使用主機名; vrrp_mcast_group4:IPV4多播地址,默認224.0.0.19;
VRRPDCONFIGURATION:配置vrrp實例
配置語法: 配置虛擬路由器: vrrp_instance <STRING> { .... } 常用配置參數: state MASTER|BACKUP:當前節點在此虛擬路由器上的初始狀態;只能有一個是MASTER,余下的都應該為BACKUP; interface IFACE_NAME:綁定為當前虛擬路由器使用的物理接口; virtual_router_id VRID:當前虛擬路由器的惟一標識,范圍是0-255; priority 100:當前主機在此虛擬路徑器中的優先級;范圍1-254; advert_int 1:vrrp通告的時間間隔; 認證方式配置 authentication{ # Authentication block #PASS||AH #PASS - Simple Passwd (suggested) 推薦使用簡單字符串認證 #AH - IPSEC (not recommended)) 不推薦使用高級認證機制 auth_typePASS #Password for accessing vrrpd. #should be the same for all machines. #Only the first eight (8) characters are used. auth_pass1234 認證密鑰不能超過8個字符,如果超過八個字符,則只有前八個字符生效 } 虛擬IP配置: irtual_ipaddress { <IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPE> label <LABEL> 192.168.200.17/24 dev eth1 192.168.200.18/24 dev eth2 label eth2:1 } 配置參數: <IPADDR>:ip地址,可以只有ip <MASK>:掩碼 brd <IPADDR>:廣播地址 dev <STRING>:配置在哪個設備上 scope <SCOPE>:生效作用域:表示只能與本機通信還是要與外部通信,一般默認都是能夠與外部通信 label <LABEL>:需要的時候可以定義到網卡別名上。一般之間指定到設備上就ok 監控網絡設備接口配置:配置要監控的網絡接口,一旦接口出現故障,則轉為FAULT狀態并且重新觸發選舉; track_interface { eth0 eth1 ... } 對于轉為FAULT狀態的網絡接口恢復的時候的模式定義配置;默認為搶占模式 nopreempt:定義工作模式為非搶占模式; preempt_delay 300:搶占式模式下,節點上線后觸發新選舉操作的延遲時長; 定義通知腳本的配置: notify_master <STRING>|<QUOTED-STRING>:當前節點成為主節點時觸發的腳本; notify_backup <STRING>|<QUOTED-STRING>:當前節點轉為備節點時觸發的腳本; notify_fault <STRING>|<QUOTED-STRING>:當前節點轉為“失敗”狀態時觸發的腳本; notify <STRING>|<QUOTED-STRING>:通用格式的通知觸發機制,一個腳本可完成以上三種狀態的轉換時的通知;
單主配置示例:需要啟用網卡多播功能,(前提:網卡支持多播):ip link set dev DEVICE multicast on
! Configuration File for keepalived 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 } vrrp_instance VI_1 { state BACKUP interface eno16777736 virtual_router_id 14 priority 98 advert_int 1 authentication { auth_type PASS auth_pass 571f97b2 } virtual_ipaddress { 10.1.0.91/16 dev eno16777736 } }
雙主模型示例:
! Configuration File for keepalived 第一步:node1節點配置 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 } vrrp_instance VI_1 { state MASTER interface eno16777736 virtual_router_id 14 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 571f97b2 } virtual_ipaddress { 10.1.0.91/16 dev eno16777736 } } vrrp_instance VI_2 { state BACKUP interface eno16777736 virtual_router_id 15 priority 98 advert_int 1 authentication { auth_type PASS uth_pass 578f07b2 } virtual_ipaddress { 10.1.0.92/16 dev eno16777736 } } 第二步:node2節點配置 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 } vrrp_instance VI_1 { state BACKUP interface eno16777736 virtual_router_id 14 priority 98 advert_int 1 authentication { auth_type PASS auth_pass 571f97b2 } virtual_ipaddress { 10.1.0.91/16 dev eno16777736 } } vrrp_instance VI_2 { state MASTER interface eno16777736 virtual_router_id 15 priority 100 advert_int 1 authentication { auth_type PASS uth_pass 578f07b2 } virtual_ipaddress { 10.1.0.92/16 dev eno16777736 } }
通知腳本示例:
#!/bin/bash # contact='root@localhost' notify() { mailsubject="$(hostname) to be $1, vip floating" mailbody="$(date +'%F %T'): vrrp transition, $(hostname) changed to be $1" echo "$mailbody" | mail -s "$mailsubject" $contact } case $1 in master) notify master ;; backup) notify backup ;; fault) notify fault ;; *) echo "Usage: $(basename $0) {master|backup|fault}" exit 1 ;; esac 腳本的調用方法: notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault"
keepalived高可用ipvs服務配置:
1.定義集群服務方法
方法1、virtual_server IP port{ ... } 方法2、virtual_server fwmark int{ { ... real_server { ... } ... } 常用參數: delay_loop <INT>:服務輪詢的時間間隔;用來定義做健康狀態檢測的時候每隔多長時間做一次健康狀態檢測 lb_algo rr|wrr|lc|wlc|lblc|sh|dh:定義調度方法; lb_kind NAT|DR|TUN:集群的類型; persistence_timeout <INT>:持久連接時長; protocol TCP:服務協議,僅支持TCP; sorry_server <IPADDR> <PORT>:備用服務器地址;
2.定義RS的方法(應用上下文virutal_server)
常用參數: real_server <IPADDR> <PORT>{ weight #:指明當前RS權重 notify_up <STRING>|<QUOTED-STRING>:定義up腳本 notify_down <STRING>|<QUOTED-STRING>:定義down腳本 HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHECK { ... }:定義當前主機的健康狀態檢測方法; }
keepalived健康狀態檢測機制
1.web應用層檢測
檢測參數; HTTP_GET|SSL_GET { url { :檢測URL path <URL_PATH>:定義要監控的URL路徑; status_code <INT>:期望返回判斷上述檢測機制為健康狀態的響應碼; digest <STRING>:判斷上述檢測機制為健康狀態的響應的內容的校驗碼; } nb_get_retry <INT>:檢測每隔多長時間的重試次數; delay_before_retry <INT>:每次重試之前的延遲時長; connect_ip <IP ADDRESS>:向當前RS的哪個IP地址發起健康狀態檢測請求 connect_port <PORT>:向當前RS的哪個PORT發起健康狀態檢測請求 bindto <IP ADDRESS>:發出健康狀態檢測請求時使用的源地址; bind_port <PORT>:發出健康狀態檢測請求時使用的源端口; connect_timeout <INTEGER>:連接請求的超時時長; }
2.傳輸層檢測(tcp協議層)
檢測參數; TCP_CHECK { connect_ip <IP ADDRESS>:向當前RS的哪個IP地址發起健康狀態檢測請求 connect_port <PORT>:向當前RS的哪個PORT發起健康狀態檢測請求 bindto <IP ADDRESS>:發出健康狀態檢測請求時使用的源地址; bind_port <PORT>:發出健康狀態檢測請求時使用的源端口; connect_timeout <INTEGER>:連接請求的超時時長; }
keepalived調用外部的輔助腳本進行資源監控,并根據監控的結果狀態能實現優先動態調整;
第一步:在global_defs中定義腳本;可以是直接寫進配置文件中的腳本,也可以調用一個外部腳本
vrrp_script <SCRIPT_NAME> { script "" #指明腳本是什么,可以是個路徑,也可以直接寫在這里 interval INT #每個多長時間執行一次腳本監控 weight -INT #腳本執行失敗后減去權重的值(要確保減去后的優先級低于備用的優先級) }
第二步:在vrrp_instance實例追蹤定義腳本,用于作為實例的當前節點的監控機制
track_script { SCRIPT_NAME_1 SCRIPT_NAME_2 ... }
示例:
在vrrp_instance配置段之外編輯 vrrp_script chk_down { script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0" #判斷是否在/etc/keepalived目錄下有down文件 interval 1 #檢測down文件不在的話就每隔1秒檢測一次 weight -5 #檢測down文件在的話就將權重減5 } 在vrrp_instance配置段之內編輯 track_script{ chk_down #定義追蹤chk_down這個腳本 }
注意:節點1和節點2都需要配置,配置完以后只需在主節點主機的/etc/keepalived目錄下創建一個down文件就可實現動態切換而無需停掉服務,刪除掉down文件后當前節點就可再次成為主節點。
此功能也可以用于實現在nginx服務故障的時候自動切換節點,如在腳本判斷中檢測nginx進程是否存在來進行自動切換
原創文章,作者:M20-1馬星,如若轉載,請注明出處:http://www.www58058.com/58148