Keepalived是一款優秀的高可用軟件,起初設計旨在解決LVS的高可用與健康狀態檢測。另外在這補充一個可用程度的計算公式
HA:High Availiablity,高可用;
MTBF:記爲MTBF (mean time between failure/平均故障間隔時間),也就是平均無故障時間,系統的壽命是指兩次相鄰失效(故障) 之間的工作時間, 而不是指整個系統的報廢時間。
MTTR:記爲MTTR(mean time to repair/平均修復時間),也就是平均業務故障中斷時間,可修復產品的平均修復時間, 就是從出現故障到修復中間的這段時間記爲MTTR平均修復時間。
A: 可用度(也稱有效度) 通常記作A,也可以理解爲高可用程度, 可用平均無故障時間(MTBF)和平均修復時間(MTTR)來計算:A = MTBF/(MTBF + MTTR)。
A=MTBF/(MTBF+MTTR) 高可用程度=平均無故障時間/(平均無故障時間+平均業務故障中斷時間)
(0,1):90%, 95%, 99%, 99.5%,
99.9%(525.6分鐘/8小時宕機/年)
99.99%(52.56分鐘宕機/年)
99.999%(5.256分鐘宕機/年)
99.9999%(0.5256分鐘/30秒宕機/年)
Keepalived冗餘實現的本身就是在雙方高可用機器安裝程序實現心跳探測,而這一層面可以稱爲心跳層,心跳層的實現藉助於網絡協議的VRRP(虛擬路由器冗餘協議)來實現
VRRP協議的軟件實現,原生設計的目的爲了高可用ipvs服務:
簡單來說keepalived可以實現的效果爲
- 基於vrrp協議完成虛擬IP地址流動;
- 爲vip地址所在的節點生成ipvs規則(在配置文件中預先定義);
- 爲ipvs集羣的各RS做健康狀態檢測;(LVS+Keepalived雙主)
- 基於腳本調用接口通過執行腳本完成腳本中定義的功能,進而影響集羣事務;(Nginx+Keepalived雙主)
配置之前對主機的要求:
HA Cluster的配置前提:
(1) 各節點時間必須同步;
ntp, chrony
(2) 確保iptables,firewalld及selinux不會成爲阻礙;
(3) 各節點之間可通過主機名互相通信(對KA並非必須);
建議使用/etc/hosts文件實現;
(4) 確保各節點的用於集羣服務的接口支持MULTICAST通信;
D類:224-239;
簡單來實現第一項 基於vrrp協議完成虛擬IP地址流動
[root@node1 keepalived]# cat keepalived.conf
! Configuration File for keepalived
global_defs { ##對於郵件報警,先簡單配置爲本地的郵箱,而且這裏的郵件報警也比較雞肋,後面我們藉助keepalive調用腳本的能力再開發報警或者藉助zabbix這種專業級程序
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.0.112 ##組播地址
}
vrrp_instance VI_1 {
state MASTER #狀態分爲MASTER | BACKUP
interface eno16777736 ##浮動ip綁定在哪一個物理接口
virtual_router_id 31 ##虛擬路由器id,和另一臺設置爲一致
priority 100 ##優先級
advert_int 1 ##心跳檢測頻率,默認1s
nopreempt ##非搶佔模式
authentication {
auth_type PASS
auth_pass f1GDsVH6 ##VRRP組播,和同一組虛擬vip保持一致
}
virtual_ipaddress {
192.168.233.199/24 dev eno16777736 label eno16777736:1 ##設置vip地址
}
}
vrrp_instance VI_2 {
state BACKUP
interface eno16777736
virtual_router_id 32
priority 98
advert_int 1
authentication {
auth_type PASS
auth_pass f1GDsV78
}
virtual_ipaddress {
192.168.233.198/24 dev eno16777736 label eno16777736:2
}
}
查看上線後的組播內容
[root@node1 keepalived]# tcpdump -i eno16777736 -nn host 224.0.0.112
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eno16777736, link-type EN10MB (Ethernet), capture size 262144 bytes
06:36:08.762574 IP 192.168.233.129 > 224.0.0.112: VRRPv2, Advertisement, vrid 31, prio 100, authtype simple, intvl 1s, length 20
06:36:08.762750 IP 192.168.233.128 > 224.0.0.112: VRRPv2, Advertisement, vrid 32, prio 100, authtype simple, intvl 1s, length 20
06:36:09.763419 IP 192.168.233.128 > 224.0.0.112: VRRPv2, Advertisement, vrid 32, prio 100, authtype simple, intvl 1s, length 20
06:36:09.764635 IP 192.168.233.129 > 224.0.0.112: VRRPv2, Advertisement, vrid 31, prio 100, authtype simple, intvl 1s, length 20
06:36:10.763953 IP 192.168.233.128 > 224.0.0.112: VRRPv2, Advertisement, vrid 32, prio 100, authtype simple, intvl 1s, length 20
06:36:10.764830 IP 192.168.233.129 > 224.0.0.112: VRRPv2, Advertisement, vrid 31, prio 100, authtype simple, intvl 1s, length 20
06:36:11.764128 IP 192.168.233.128 > 224.0.0.112: VRRPv2, Advertisement, vrid 32, prio 100, authtype simple, intvl 1s, length 20
06:36:11.765028 IP 192.168.233.129 > 224.0.0.112: VRRPv2, Advertisement, vrid 31, prio 100, authtype simple, intvl 1s, length 20
06:36:12.764737 IP 192.168.233.128 > 224.0.0.112: VRRPv2, Advertisement, vrid 32, prio 100, authtype simple, intvl 1s, length 20
06:36:12.765213 IP 192.168.233.129 > 224.0.0.112: VRRPv2, Advertisement, vrid 31, prio 100, authtype simple, intvl 1s, length 20
06:36:13.765372 IP 192.168.233.128 > 224.0.0.112: VRRPv2, Advertisement, vrid 32, prio 100, authtype simple, intvl 1s, length 20
06:36:13.766607 IP 192.168.233.129 > 224.0.0.112: VRRPv2, Advertisement, vrid 31, prio 100, authtype simple, intvl 1s, length 20
配置keepalive狀態變更報警腳本
在keepalived.conf的vrrp_instance段內配置郵件觸發腳本
vrrp_instance VI_1 {
state BACKUP
interface eno16777736
virtual_router_id 31
priority 98
advert_int 1
authentication {
auth_type PASS
auth_pass f1GDsVH6
}
virtual_ipaddress {
192.168.233.199/24 dev eno16777736 label eno16777736:1
# 192.168.233.199/24 ##此操作也可以,查看浮動ip使用ip a l
}
notify_master "/etc/keepalived/scripts/notify.sh master" ##狀態變更爲master時執行腳本
notify_backup "/etc/keepalived/scripts/notify.sh backup" ##狀態變更爲backup時執行腳本
notify_fault "/etc/keepalived/scripts/notify.sh fault" ##狀態發生故障時執行腳本
}
############################## 以下腳本內容 ################################
[root@node2 scripts]# cat notify.sh
#!/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)
notify master
;;
backup)
notify backup
;;
fault)
notify fault
;;
*)
echo "Usage: $(basename $0) {master|backup|fault}"
exit 1
;;
esac
爲ipvs集羣的各RS做健康狀態檢測;(LVS+Keepalived雙主)
詳見:https://blog.51cto.com/swiki/2342624
基於腳本調用接口通過執行腳本完成腳本中定義的功能,進而影響集羣事務;(Nginx+Keepalived雙主)
拓撲信息:
客戶端 | NGINX1 | NGINX2 |
---|---|---|
192.168.2.1 | 192.168.2.128 VIP:192.168.2.198 | 192.168.2.129 VIP:192.168.2.199 |
腳本實現藉助killall,centos7最小化安裝並沒有該命令,所以需要手動安裝psmisc
修改原來的郵件通知腳本實現當NGINX進入master時,自動啓動NGINX
配置實現:
######################### NGINX1 #########################
[root@node1 keepalived]# yum install nginx psmisc -y;systemctl start nginx;
[root@node1 keepalived]# echo "192.168.2.128" > /usr/share/nginx/html/index.html
[root@node1 keepalived]# cat keepalived.conf
! Configuration File for keepalived
global_defs { ##對於郵件報警,先簡單配置爲本地的郵箱,而且這裏的郵件報警也比較雞肋,後面我們藉助keepalive調用腳本的能力再開發報警或者藉助zabbix這種專業級程序
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.0.112 ##組播地址
}
vrrp_script chk_nginx {
script "killall -0 nginx && exit 0 || exit 1"
interval 1
weight -5
fall 2
rise 1
}
vrrp_instance VI_1 {
state MASTER #狀態分爲MASTER | BACKUP
interface eno16777736 ##浮動ip綁定在哪一個物理接口
virtual_router_id 31 ##虛擬路由器id,和另一臺設置爲一致
priority 100 ##優先級
advert_int 1 ##心跳檢測頻率,默認1s
# nopreempt ##非搶佔模式
authentication {
auth_type PASS
auth_pass f1GDsVH6 ##VRRP組播,和同一組虛擬vip保持一致
}
virtual_ipaddress {
192.168.2.198/24 dev eno16777736 label eno16777736:1 ##設置vip地址
}
track_script {
chk_nginx
}
notify_master "/etc/keepalived/scripts/notify.sh master" ##狀態變更爲master時執行腳本
notify_backup "/etc/keepalived/scripts/notify.sh backup" ##狀態變更爲backup時執行腳本
notify_fault "/etc/keepalived/scripts/notify.sh fault" ##狀態發生故障時執行腳本
}
vrrp_instance VI_2 {
state BACKUP
interface eno16777736
virtual_router_id 32
priority 98
advert_int 1
authentication {
auth_type PASS
auth_pass f1GDsV78
}
virtual_ipaddress {
192.168.2.199/24 dev eno16777736 label eno16777736:2
}
notify_master "/etc/keepalived/scripts/notify.sh master" ##狀態變更爲master時執行腳本
notify_backup "/etc/keepalived/scripts/notify.sh backup" ##狀態變更爲backup時執行腳本
notify_fault "/etc/keepalived/scripts/notify.sh fault" ##狀態發生故障時執行腳本
track_script {
chk_nginx
}
}
######################### NGINX2 #########################
NGINX2與NGINX1的keepalived雙活配置相反,這裏不在贅述
附notify.sh 腳本內容:
[root@node1 keepalived]# cat scripts/notify.sh
#!/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)
systemctl start nginx
notify master
;;
backup)
#systemctl start nginx
notify backup
;;
fault)
notify fault
;;
*)
echo "Usage: $(basename $0) {master|backup|fault}"
exit 1
;;
esac