keepalived 是 Linux 一個輕量級的高可用解決方案,提供了心跳檢測和資源接管、檢測集群中的系統服務,在集群節點間轉移共享IP 地址的所有者等。
工作原理
keepalived 通過 VRRP(virtual router redundancy protocol)虛擬路由冗余協議來實現高可用。在這個協議里會將多態功能相同的路由組成一個小組,這個小組會有一個 master 角色 和 N(N >=1)個 backup 角色。
Keepalived 有三個模塊:core、check、vrrp。
其中:
core 模塊 為 Keepalived 的核心,負責主進程啟動、維護以及全局配置文件的加載和解析;
check 模塊負責 健康檢查;
vrrp 負責實現 vrrp 協議。
keepalived 的體系結構
keepalived 的體系 結構從整體上分為 兩層,分別是用戶層 (User Space)和 內核空間層(Kernel Space)。
內核空間層處于最底層,它包括 IPVS 和 NETLINK 兩個模塊。IPVS 模塊是 Keepalived 引入 的一個第三方模塊,通過 IPVS 可以實現基于 IP 的負載均衡集群。IPVS 默認包含在 LVS 集群軟件中。而對于 LVS 集群軟件,在 LVS 集群中, IPVS 安裝在 一臺叫 Director Server 的服務器上,同時在 Director Server 上虛擬出一個 IP 地址對外提供服務,而用戶必須通過這個虛擬 IP 地址才能訪問服務。這個虛擬 IP 一般成為 LVS 的 VIP,即 Virtual IP。訪問的請求首先經過 VIP 到達 Director Server ,然后有 Director Server 從服務器集群節點中選取一個 服務節點響應用戶的請求。
Keepalived的配置文件解析
Keepalived的核心組件,包含了一系列功能模塊,主要有WatchDog、Checkers、VRRP Stack、IPVS wrapper 和Netlink Reflector,下面介紹每個模塊所實現的功能如下:
1、WatchDog
WatchDog是計算機可靠性領域中一個極為簡單又非常有效的檢測工具,它的工作原理是針對被監視的目標設置一個計數器和一個閾值,WatchDog會自己增加此計數值,然后等待被監視的目標周期性地重置該計數值。一旦被監控目標發生錯誤,就無法重置此計數值,WatchDog就會檢測到,于是采取對應的恢復措施,例如重啟或關閉。
在linux中很早就引入了WatchDog功能,而Keepalived正是通過WatchDog的運行機制來監控Checkers和VRRP進程的。
2、 Checkers
這是Keepalived最基礎的功能,也是最主要的功能,可實現對服務器運行狀態檢測和故障隔離。
3、 VRRP Stack
這是Keepalived后來引入的VRRP功能,可以實現HA集群中失敗切換(Failover)功能。Keepalived通過VRRP功能再結合LVS負載均衡軟件即可部署一個高性能的負載均衡集群系統。
4、 IPVS wrapper
這是IPVS功能的一個實現。IPVS wrapper模塊可以將設置好的IPVS規則發送到內核空間并提交給IPVS模塊,最終實現IPVS模塊的負載均衡功能。
5、 Netlink Reflector
用來實現高可用集群中Failover時虛擬IP(VIP)的設置和切換。Netlink Reflector的所有請求最后都發送到內核空間層的NETLINK模塊來完成。
配置文件說明
keepalived配置文件按層級和模塊劃分的,每層由"{ }"來界定。 在主配置文件中可以通過include來涵蓋多個子配置文件。 語法說明:
BOOL: on|off|true|false|yes|no
TIMER: 以秒為單位的時間值,包括小數秒,如3,2.71828。計時器的分辨率是微妙。
關于腳本引用:
雙引號"字符串中嵌入其他雙引號或空格,那么字符串將僅在帶引號的字符串之后結束(如:“abcd” efg h jkl “mnop” 等同于 “abcd efg h jkl mnop”;)。
對于使用參數指定腳本,不帶引號的空格將分隔參數。如果參數需要包含空格,則應將其括在單引號(')中
配置文件結構
! Configuration File for keepalived# 全局定義
global_defs {# 指定接收通知的郵箱地址列表notification_email {acassen@firewall.locfailover@firewall.locsysadmin@firewall.loc}# 指定發件人的郵箱地址notification_email_from Alexandre.Cassen@firewall.loc# SMTP 服務器地址,用于發送郵箱通知smtp_server 192.168.200.1# SMTP 連接超時時間smtp_connect_timeout 30# 標識當前節點的唯一 IDrouter_id LVS_DEVEL# 跳過檢查 VRRP 廣播地址vrrp_skip_check_adv_addr# 其余嚴格的 VRRP 模式vrrp_strict# 設置 GARP 的時間間隔vrrp_garp_interval 0# 設置 GNA 的時間間隔vrrp_gna_interval 0
}# VRRP 實例
vrrp_instance VI_1 {# 當前節點的角色 (MASTER 或 BACKUP)。主節點設置為 MASTER,從節點設置為 BACKUPstate MASTER# 綁定的網絡接口(如 eth0)interface eth0# 虛擬路由的 ID(范圍0 - 255),同一組中的所有節點必須使用相同的值virtual_router_id 51# 節點的優先級(范圍1 - 254),數值越高優先級越高priority 100# VRRP 廣播間隔時間(秒)advert_int 1# VRRP 認證信息authentication {# 認證類型(PASS 表示簡單密碼認證)auth_type PASS# 認證密碼auth_pass 1111}# 虛擬 IP 地址列表,這些 IP 將綁定在當前節點的網絡接口上virtual_ipaddress {192.168.200.16192.168.200.17192.168.200.18}
}# 虛擬服務器
# 定義一個虛擬服務器,監聽指定的IP 和端口(如:192.168.200.100 443)
virtual_server 192.168.200.100 443 {# 健康檢查的間隔時間(秒)delay_loop 6# 負載均衡算法(如 rr 表示輪訓)lb_algo rr# 負載均衡模式(如 NAT 表示網絡地址轉換)lb_kind NAT# 會話保持時間(秒)persistence_timeout 50# 協議類型(TCP)protocol TCP# 定義真實后端服務器real_server 192.168.201.100 443 {# 權重值,用于分配流量的比例weight 1# 使用 SSL 請求進行健康檢查SSL_GET {# 檢查的目標 URL 及其 MD5 摘要值url {path /digest ff20ad2481f97b1754ef3e12ecd3a9cc}url {path /mrtg/digest 9b3a0c85a887a256d6939da88aabd8cd}# 連接超時時間connect_timeout 3# 失敗后重試時間retry 3# 重試前的延遲時間delay_before_retry 3}}
}
配置文件包括以下幾個模塊:
1.GLOBAL CONFIGURATION
包含配置文件中的global_defs、static_ipaddress、static_route區域,負責定義郵件的相關配置、route_id、vrrp配置、多播地址、節點的ip和路由信息等
global_defs 全局配置
vrrpd1. vrrp_script添加一個周期性執行的腳本。腳本的退出狀態碼會被調用它的所有的VRRP Instance記錄。2. vrrp_sync_group將所有相關的VRRP實例定義在一起,作為一個VRRP Group,如果組內的任意一個實例出現問題,都可以實現Failover3. garp_group4. vrrp_instance
LVS配置
virtual_serverreal_server
real_server中的健康檢查
HTTP_GET or SSL_GET
TCP_CHECK
TCP_CHECK
DNS_CHECK
DNS_CHECK
全局配置模塊
! Configuration File for keepalived
global_defs { #全局定義部分notification_email { #設置報警郵件地址,可設置多個acassen@firewall.loc #接收通知的郵件地址failover@firewall.loc} notification_email_from test0@163.com #設置 發送郵件通知的地址smtp_server smtp.163.com #設置 smtp server 地址,可是ip或域名.可選端口號 (默認25)smtp_connect_timeout 30 #設置 連接 smtp server的超時時間router_id LVS_DEVEL #主機標識,用于郵件通知vrrp_strict #嚴格執行VRRP協議規范,此模式不支持節點單播script_user keepalived_script #指定運行腳本的用戶名和組。默認使用用戶的默認組。如未指定,默認為keepalived_script 用戶,如無此用戶,則使用rootenable_script_security #如過路徑為非root可寫,不要配置腳本為root用戶執行。
}
2.BFD CONFIGURATION
用于快速檢測系統之間的通信故障,并在出現故障時通知上層應用。
它具有兩優點:
對網絡設備間任意類型的雙向轉發路徑提供快速、輕負荷的故障檢測
用單一的機制對任何介質、任何協議層進行實時檢測,并支持不同的檢測時間與開銷
3. VRRPD CONFIGURATION
包含配置文件中的vrrp_script、vrrp_instance、vrrp_sync_group、garp_group區域,負責定義每個vrrp虛擬路由器
vrrp_script配置
作用:添加一個周期性執行的腳本。腳本的退出狀態碼會被調用它的所有的VRRP Instance記錄。
注意:至少有一個VRRP實例調用它并且優先級不能為0.優先級范圍是1-254.
vrrp_script <SCRIPT_NAME> {...}
選項說明:
script "/path/to/somewhere":指定要執行的腳本的路徑。
interval <INTEGER>:指定腳本執行的間隔。單位是秒。默認為1s。
timeout <INTEGER>:指定在多少秒后,腳本被認為執行失敗。
weight <-254 --- 254>:調整優先級。默認為2.
rise <INTEGER>:執行成功多少次才認為是成功。
fall <INTEGER>:執行失敗多少次才認為失敗。
user <USERNAME> [GROUPNAME]:運行腳本的用戶和組。
init_fail:假設腳本初始狀態是失敗狀態。
解釋:
weight:
1. 如果腳本執行成功(退出狀態碼為0),weight大于0,則priority增加。
2. 如果腳本執行失敗(退出狀態碼為非0),weight小于0,則priority減少。
3. 其他情況下,priority不變
vrrp_instance
命令說明:
state MASTER|BACKUP:指定該keepalived節點的初始狀態。
interface eth0:vrrp實例綁定的接口,用于發送VRRP包。
use_vmac [<VMAC_INTERFACE>]:在指定的接口產生一個子接口,如vrrp.51,該接口的MAC地址為組播地址,通過該接口向外發送和接收VRRP包。
vmac_xmit_base:通過基本接口向外發送和接收VRRP數據包,而不是通過VMAC接口。
native_ipv6:強制VRRP實例使用IPV6.(當同時配置了IPV4和IPV6的時候)
dont_track_primary:忽略VRRP接口的錯誤,默認是沒有配置的。
track_interface {eth0eth1 weight <-254-254>...
}:如果track的接口有任何一個出現故障,都會進入FAULT狀態。
track_script {<SCRIPT_NAME><SCRIPT_NAME> weight <-254-254>
}:添加一個track腳本(vrrp_script配置的腳本。)
mcast_src_ip <IPADDR>:指定發送組播數據包的源IP地址。默認是綁定VRRP實例的接口的主IP地址。
unicast_src_ip <IPADDR>:指定發送單薄數據包的源IP地址。默認是綁定VRRP實例的接口的主IP地址。
version 2|3:指定該實例所使用的VRRP版本。
unicast_peer {<IPADDR>...
}:采用單播的方式發送VRRP通告,指定單播鄰居的IP地址。
virtual_router_id 51:指定VRRP實例ID,范圍是0-255.
priority 100:指定優先級,優先級高的將成為MASTER。
advert_int 1:指定發送VRRP通告的間隔。單位是秒。
authentication {auth_type PASS|AH:指定認證方式。PASS簡單密碼認證(推薦),AH:IPSEC認證(不推薦)。auth_pass 1234:指定認證所使用的密碼。最多8位。
}
virtual_ipaddress {<IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPE> label <LABEL>192.168.200.17/24 dev eth1192.168.200.18/24 dev eth2 label eth2:1
}:指定VIP地址。
nopreempt:設置為不搶占。默認是搶占的,當高優先級的機器恢復后,會搶占低優先級的機器成為MASTER,而不搶占,則允許低優先級的機器繼續成為MASTER,即使高優先級的機器已經上線。如果要使用這個功能,則初始化狀態必須為BACKUP。
preempt_delay:設置搶占延遲。單位是秒,范圍是0---1000,默認是0.發現低優先級的MASTER后多少秒開始搶占。
通知腳本:
notify_master <STRING>|<QUOTED-STRING> [username [groupname]]
notify_backup <STRING>|<QUOTED-STRING> [username [groupname]]
notify_fault <STRING>|<QUOTED-STRING> [username [groupname]]
notify <STRING>|<QUOTED-STRING> [username [groupname]]
# 當停止VRRP時執行的腳本。
notify_stop <STRING>|<QUOTED-STRING> [username [groupname]]
smtp_alert
vrrp_sync_group
作用:將所有相關的VRRP實例定義在一起,作為一個VRRP Group,如果組內的任意一個實例出現問題,都可以實現Failover。vrrp_sync_group VG_1 {group {inside_network # vrrp instance nameoutside_network # vrrp instance name...}...
}
說明:
如果username和groupname沒有指定,則以默認的script_user所指定的用戶和組。
1. notify_master /path/to_master.sh [username [groupname]]作用:當成為MASTER時,以指定的用戶和組執行腳本。
2. notify_backup /path/to_backup.sh [username [groupname]]作用:當成為BACKUP時,以指定的用戶和組執行腳本。
3. notify_fault "/path/fault.sh VG_1" [username [groupname]]作用:當該同步組Fault時,以指定的用戶和組執行腳本。
4. notify /path/notify.sh [username [groupname]]作用:在任何狀態都會以指定的用戶和組執行腳本。說明:該腳本會在notify_*腳本后執行。notify可以使用3個參數,如下:$1:可以是GROUP或INTANCE,表明后面是組還是實例。$2:組名或實例名。$3:轉換后的目標狀態。有:MASTER、BACKUP、FAULT。
5. smtp_alert:當狀態發生改變時,發送郵件。
6. global_tracking:所有的VRRP實例共享相同的tracking配置。
注意:腳本文件要加上x權限,同時指令最好寫絕對路徑。
4.LVS CONFIGURATION
包含配置文件中的virtual_server_group、virtual_server區域,負責lvs集群配置
LVS模塊結構:
virtual_server{… ...real_server{… ...}
}
virtual_server
virtual_server IP Port | virtual_server fwmark int | virtual_server group string {delay_loop <INT>:健康檢查的時間間隔。lb_argo rr|wrr|lc|wlc|lblc|sh|dh:LVS調度算法。lb_kind NAT|DR|TUN:LVS模式。persistence_timeout 360:持久化超時時間,單位是秒。默認是6分鐘。persistence_granularity:持久化連接的顆粒度。protocol TCP|UDP|SCTP:4層協議。ha_suspend:如果virtual server的IP地址沒有設置,則不進行后端服務器的健康檢查。virtualhost <STRING>:為HTTP_GET和SSL_GET執行要檢查的虛擬主機。如virtualhost www.felix.comsorry_server <IPADDR> <PORT>:添加一個備用服務器。當所有的RS都故障時。sorry_server_inhibit:將inhibit_on_failure指令應用于sorry_server指令。alpha:在keepalived啟動時,假設所有的RS都是down,以及健康檢查是失敗的。有助于防止啟動時的誤報。默認是禁用的。omega:在keepalived終止時,會執行quorum_down指令所定義的腳本。quorum <INT>:默認值1. 所有的存活的服務器的總的最小權重。quorum_up <STRING>:當quorum增長到滿足quorum所定義的值時,執行該腳本。quorum_down <STRING>:當quorum減少到不滿足quorum所定義的值時,執行該腳本。
}
real_server
real_server IP Port {weight <INT>:給服務器指定權重。默認是1.inhibit_on_failure:當服務器健康檢查失敗時,將其weight設置為0,而不是從Virtual Server中移除。notify_up <STRING>:當服務器健康檢查成功時,執行的腳本。notify_down <STRING>:當服務器健康檢查失敗時,執行的腳本。uthreshold <INT>:到這臺服務器的最大連接數。lthreshold <INT>:到這臺服務器的最小連接數。
}