解讀 Linux 系統(tǒng) Keepalived 健康檢查機(jī)制
在進(jìn)行負(fù)載均衡時(shí),一般都會部署一個(gè)健康檢查工具,確保后端real server是正常的,可以提供服務(wù)的,避免出現(xiàn)后端real server 已經(jīng)宕機(jī)或服務(wù)不可用時(shí),負(fù)載均衡器扔將請求分發(fā)到real server,影響整體業(yè)務(wù)訪問。健康檢查的方式有很多,可以自行部署腳本,當(dāng)然當(dāng)前用的比較多的就是keepalived服務(wù)了。keepalived的健康檢查方式有三種,tcp_check、http_check、misc_check。
keepalived配置簡述
keepalived主要有三個(gè)模塊,分別是core、check和vrrp。core模塊為keepalived的核心,負(fù)責(zé)主進(jìn)程的啟動(dòng)、維護(hù)以及全局配置文件的加載和解析。check負(fù)責(zé)健康檢查,包括常見的各種檢查方式。vrrp模塊是來實(shí)現(xiàn)VRRP協(xié)議的 keepalived只有一個(gè)配置文件keepalived.conf,里面主要包括以下幾個(gè)配置區(qū)域,分別是global_defs、static_ipaddress、static_routes、vrrp_script、vrrp_instance和virtual_server。
yum install keepalived -y
配置文件:
! Configuration File for keepalived
# vi /etc/keepalived/keepalived.conf
# 全局配置 主要是配置故障發(fā)生時(shí)的通知對象以及機(jī)器標(biāo)識
global_defs {
notification_email {
r_xl@xl.com # 設(shè)置報(bào)警郵件接收地址,需要開啟 sendmail 服務(wù)
}
notification_email_from s_xl@xl.com # 設(shè)置郵件的發(fā)送地址
smtp_server 192.168.2.241 # 設(shè)置通知的 SMTP Server 地址
smtp_connect_timeout 30 # 設(shè)置通知的 SMTP Server 的超時(shí)時(shí)間
router_id LVS_DEVEL_1 # 路由ID,標(biāo)識本節(jié)點(diǎn)的字符串,郵件通知時(shí)會用到
}
# 自定義VRRP實(shí)例健康檢查腳本 keepalived只能做到對自身問題和網(wǎng)絡(luò)故障的監(jiān)控,Script可以增加其他的監(jiān)控來判定是否需要切換主備
vrrp_script chk_sshd {
script "killall -0 sshd" # 示例為檢查sshd服務(wù)是否運(yùn)行中
interval 2 # 檢查間隔時(shí)間
weight -4 # 檢查失敗降低的權(quán)重
}
# VRRP實(shí)例 定義對外提供服務(wù)的VIP區(qū)域及其相關(guān)屬性
vrrp_instance VI_1 {
state MASTER # 狀態(tài)只有 MASTER 和 BACKUP 兩種,并且要大寫,MASTER 為工作狀態(tài),BACKUP 是備用狀態(tài)
interface eth0 # 節(jié)點(diǎn)固有IP(非VIP)的網(wǎng)卡,用來發(fā)VRRP包
virtual_router_id 51 # 虛擬路由標(biāo)識,同一個(gè) vrrp_instance 的 MASTER 和 BACKUP 的 vitrual_router_id 需要一致
priority 100 # 優(yōu)先級,同一個(gè) vrrp_instance 的 MASTER 優(yōu)先級必須比 BACKUP 高
advert_int 1 # MASTER 與 BACKUP 負(fù)載均衡器之間同步檢查的時(shí)間間隔,單位為秒
authentication { # 設(shè)置認(rèn)證
auth_type PASS # 認(rèn)證方式,支持 PASS 和 HA
auth_pass 1111 # 證密碼為明文,同一 vrrp 實(shí)例 MASTER 與 BACKUP 使用相同的密碼才能正常通信
}
virtual_ipaddress { # 虛擬IP地址(VIP),可以有多個(gè)地址,每個(gè)地址占一行
192.168.12.200
}
track_script { # 自定義健康檢查腳本
chk_sshd # 配置上面自定義的vrrp腳本調(diào)用名
}
}
# 設(shè)置虛擬服務(wù)器
virtual_server 192.168.12.200 6500 { # 指定虛擬IP地址和服務(wù)端口
delay_loop 6 # 服務(wù)健康檢查周期,6秒
lb_algo rr # 負(fù)載均衡調(diào)度算法,一般用wrr、rr、wlc
lb_kind DR # 負(fù)載均衡轉(zhuǎn)發(fā)規(guī)則。一般包括DR,NAT,TUN 3種
persistence_timeout 5 # 會話保持時(shí)間。把用戶請求請求間隔在未超過保持時(shí)間時(shí),一直分發(fā)到某個(gè)服務(wù)節(jié)點(diǎn)
protocol TCP # 轉(zhuǎn)發(fā)協(xié)議 有TCP和UDP兩種
# 配置真實(shí)服務(wù)器
real_server 192.168.2.222 6500 { #指定IP和端口
weight 1 # 權(quán)重,數(shù)值越大,權(quán)重越高
# 健康檢查方式 常見有 TCP_CHECK, HTTP_GET, SSL_GET, MISC_CHECK(自定義腳本)
TCP_CHECK { # 通過TcpCheck方式判斷RealServer的健康狀態(tài)
connect_timeout 10 # 連接超時(shí)時(shí)間
nb_get_retry 3 # 重連次數(shù)
delay_before_retry 3 # 重連時(shí)間間隔
connect_port 6500 # 檢測端口
}
}
# 配置真實(shí)服務(wù)器
real_server 192.168.2.222 6500 { #指定IP和端口
weight 1 # 權(quán)重,數(shù)值越大,權(quán)重越高
# 健康檢查方式 常見有 TCP_CHECK, HTTP_GET, SSL_GET, MISC_CHECK(自定義腳本)
TCP_CHECK { # 通過TcpCheck判斷RealServer的健康狀態(tài)
connect_timeout 10 # 連接超時(shí)時(shí)間
nb_get_retry 3 # 重連次數(shù)
delay_before_retry 3 # 重連時(shí)間間隔
connect_port 6500 # 檢測端口
}
}
}
健康檢查類型
TCP_CHECK
TCP_CHECK { # 通過TcpCheck判斷RealServer的健康狀態(tài)
connect_timeout 10 # 連接超時(shí)時(shí)間
nb_get_retry 3 # 重連次數(shù)
delay_before_retry 3 # 重連時(shí)間間隔
connect_port 6500 # 檢測端口
}
2.HTTP_GET
HTTP_GET {
url {
path check/200.jsp # 檢查的uri地址
digest 1362a91278f0806aa1d33e1e26d67763 # 用keepalived自帶的genhash生成,/usr/bin/genhash -s rsIP -p port -u uri
}
connect_timeout 3 # 鏈接超時(shí)時(shí)間
nb_get_retry 3 # 重連次數(shù)
delay_before_retry 3 # 重連時(shí)間間隔
connect_port 6500 # 檢測端口
}
3.MISC_CHECK
keepalived.conf配置:
MISC_CHECK {
misc_path "/etc/keepalived/misc_check.sh http://192.168.2.222:6500/check/200.jsp" # 外部程序或者腳本的路徑和參數(shù)
misc_timeout 10 # 腳本執(zhí)行的超時(shí)時(shí)間
misc_dynamic #動(dòng)態(tài)權(quán)重標(biāo)志。腳本返回0則檢測成功權(quán)重不變,返回1表示失敗權(quán)重設(shè)置為0
}
腳本示例:
#!/bin/bash
# ./misc_check.sh http://192.168.2.222:6500/check/200.jsp
if [ $# -ne 1 ]; then
echo "Warning: command param error."
exit 1
else
CHECK_URL=$1
CMD=`/usr/bin/curl -I ${CHECK_URL} 2>/dev/null | grep "200 OK" | wc -l`
if [ ${CMD} -eq 1 ]; then
echo "Succ: Check proxy ${CHECK_URL} is succeed."
exit 0
else
echo "Fail: check proxy ${CHECK_URL} is failed."
exit 1
fi
fi