keepalived高可用對之間是經過VRRP通訊的,所以,我從VRRP開始給您講起.
1)VRRP,全稱Virtual Router Reduancy Protocol,中文名爲虛擬路由器冗餘協議,VRRP的出現是爲了解決靜態路由的單點故障;
2)VRRP是經過一種競選協議來將路由任務交給某臺VRRP路由器的;
3)VRRP用IP多播的方式,(默認多播地址(224.0.0.18))實現高可用對之間通訊;
4)工做時主節點發包,備節點接包,當備節點接收不到主節點發的包的時候,就啓動接管程序接管主節點的資源。備節點能夠有多個,經過優先級競選,但通常keepalived系統運維工做中都是一對。
5)VRRP使用了加密協議加密數據,但keepalived官方目前仍是推薦用明文的方式配置認證類型和密碼。
介紹完了VRRP,接下來我在介紹一下keepalived服務的工做原理;
keepalived高可用對之間是經過VRRP進行通訊的,VRRP是經過競選機制來肯定主備的,主的優先級高於備,所以,工做時會優先得到全部的資源,備節點處於等待狀態,當主掛了的時候,備節點就會接管主節點的資源,而後頂替主節點對外提供服務。
在keepalived服務對之間,只有做爲主的服務器會一直髮送VRRP廣播包,告訴備它還活着,此時備不會搶佔主。當主不可用時,即備監聽不到主發送的廣播包時,就會啓動相關服務接管資源,保證業務的連續性,接管速度最快能夠小於一秒。
[root@lb02 ~]# yum install keepalived -y
[root@lb02 ~]# rpm -qa keepalived
keepalived-1.3.5-8.el7_6.5.x86_64
[root@lb02-e ~]# systemctl start keepalived
[root@lb02-e ~]# ps -ef|grep keepalived
root 10039 1 0 12:21 ? 00:00:00 /usr/sbin/keepalived -D
root 10040 10039 0 12:21 ? 00:00:00 /usr/sbin/keepalived -D
root 10041 10039 0 12:21 ? 00:00:03 /usr/sbin/keepalived -D
###提示:啓動後有三個keepalived進程表示安裝正確
[root@lb02 ~]# ip a | grep eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
inet 10.0.0.6/24 brd 10.0.0.255 scope global noprefixroute eth0
inet 192.168.200.16/32 scope global eth0
inet 192.168.200.17/32 scope global eth0
inet 192.168.200.18/32 scope global eth0
###提示:默認狀況會啓動三個VIP地址
[root@lb02-e ~]# systemctl stop keepalived
###提示: 測試完畢後關閉服務,上述測試須要在lb01和lb02兩臺服務器上進行
[root@lb02 ~]# rpm -qc keepalived
/etc/keepalived/keepalived.conf
/etc/sysconfig/keepalived
[root@lb02 ~]# cat -n /etc/keepalived/keepalived.conf
1 ! Configuration File for keepalived
2
3 global_defs {
4 notification_email {
5 acassen@firewall.loc
6 failover@firewall.loc
7 sysadmin@firewall.loc
8 }
9 notification_email_from Alexandre.Cassen@firewall.loc
10 smtp_server 192.168.200.1
11 smtp_connect_timeout 30
12 router_id LVS_DEVEL
13 vrrp_skip_check_adv_addr
14 vrrp_strict
15 vrrp_garp_interval 0
16 vrrp_gna_interval 0
17 }
第1行是註釋,!開頭和#號開頭同樣,都是註釋。前端
第2行是空行。linux
第3行—8行是定義故障服務報警的Email地址。做用是服務發生切換或RS節點等有故障時,須要發送的Email地址,能夠有多個,每行一個。nginx
第9行是制定發送郵件的發送人,即發送人地址,也是可選配置。web
第10行smtp_server指定發送郵件的smtp服務器,若是本機開啓了sendmail或postfix。就可使用上面默認配置實現郵件發送,也是可選配置。面試
第11行smtp_connect_timeout是鏈接smtp的超時時間,也是可選配置。數據庫
第12行是Keepalived服務器的路由標識{route_id}。在一個局域網內,這個標識{route_id}應該是惟一的。vim
大括號{}用來區分區塊,要成對出現。若是漏寫了半個大括號,keepalived運行時,不會報錯,可是也不會獲得預期的結果。另外,因爲區塊間存在多層嵌套關係,所以很容易遺漏區塊結尾處的大括號,須要特別注意。windows
19 vrrp_instance VI_1 {
20 state MASTER
21 interface eth0
22 virtual_router_id 51
23 priority 100
24 advert_int 1
25 authentication {
26 auth_type PASS
27 auth_pass 1111
28 }
29 virtual_ipaddress {
30 192.168.200.16
31 192.168.200.17
32 192.168.200.18
33 }
34 }
第19行表示定義一個vrrp_instance實例,名字爲VI_1,每一個vrrp_instance實例能夠認爲是Keepalived服務的一個實例或者做爲一個業務服務,在Keepalived服務配置中,這樣的vrrp_instance實例能夠有多個。 注意,存在於主節點中的vrrp_isntance實例在備節點也要存在,這樣才能實現故障切換接管。緩存
第20行state MASTER表示當前示例VI_1的角色狀態,當前角色爲MASTER,這個狀態只能有MASTER和BACKUP兩種狀態,而且須要大寫這些字符。其中MASTER爲正式工做的狀態,BACKUP爲備用的狀態。當MASTER所在的服務器故障或失效時,BACKUP所在的服務器會接管故障的MASTER繼續提供服務。安全
第21行interface爲網路通訊接口。爲對外提供服務的網絡接口,如eth0,eth1當前主流的服務器都有2~4個網絡接口,在選擇服務接口時,要搞清楚。
第22行virtual_router_id爲虛擬路由ID標識,這個標識最好是一個數字。
第23行priority爲優先級,其後面的數值也是一個數字,數字越大,表示實例優先級越高。在同一個vrrp_instance實例裏,MASTER的優先級配置要高於BACKUP的。若MASTER的priority值爲150,那麼BACKUP的priority必須小於150,通常建議隔50以上爲佳。
第24行advent_int爲同步通知間隔。MASTER與BACKUP之間通訊檢查的時間間隔,默認爲1秒。
第25-27行authentication爲權限認證配置。包含認證類型(auth_type)和認證密碼(auth_pass) 。認證類型有PASS(simple passwd),AH(IPSEC)兩種,官方推薦使用的類型爲PASS。驗證密碼爲明文方式,最好長度不能超過8個字符,建議四位數字,同一vrrp實例的MASTER與BACKUP使用相同的密碼才能正常通訊。
第29-32行virtual_ipaddress爲虛擬IP地址。能夠配置多個IP地址,每一個地址佔一行,配置時最好明確指定子網掩碼以及虛擬IP綁定的網絡接口。不然,子網掩碼默認是32位,綁定的接口和前面的interface參數配置的一致。注意,這裏的虛擬IP就是在工做中須要和域名綁定的IP,即和配置的高可用服務監聽的IP要保持一致。
#優化基本源
[root@lb01-e ~]# vim /etc/yum.repos.d/CentOS-Base.repo
[root@lb02-e ~]# vim /etc/yum.repos.d/CentOS-Base.repo
[root@lb03-e ~]# vim /etc/yum.repos.d/CentOS-Base.repo
[root@lb01 ~]# yum install keepalived -y
[root@lb02 ~]# yum install keepalived -y
[root@lb01 ~]# rpm -qc keepalived
/etc/keepalived/keepalived.conf
/etc/sysconfig/keepalived
#配置keepalived主服務器lb01 MASTER
[root@lb01 ~]# vim /etc/keepalived/keepalived.conf
global_defs { #全局配置
router_id lb01 #keepalived服務器的路由標識(route_id)
}
vrrp_instance VI_1 { #vrrp實例,命名叫VI_1
state MASTER #當前實例VI_1的角色狀態
interface eth0 #是對外提供服務的網絡接口
virtual_router_id 50 #虛擬路由ID標識
priority 150 #優先級
advert_int 1 #同步通知間隔時間
authentication { #權限認證配置
auth_type PASS #認證方式
auth_pass 1111 #認證密碼
}
virtual_ipaddress {
10.0.0.4 #虛擬的VIP地址
}
}
#啓動keepalived(lb01)
[root@lb01 ~]# systemctl enable keepalived
Created symlink from /etc/systemd/system/multi-user.target.wants/keepalived.service to /usr/lib/systemd/system/keepalived.service.
[root@lb01 ~]# systemctl start keepalived
[root@lb01-e ~]# ip addr | egrep 10.0.0.4
inet 10.0.0.4/32 scope global eth0
#實戰配置keepalived備服務器lb02 BACKUP
[root@lb02 ~]# vim /etc/keepalived/keepalived.conf
global_defs {
router_id lb02
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 50
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.4
}
}
#啓動lb02的keepalived
[root@lb02 ~]# systemctl enable keepalived
Created symlink from /etc/systemd/system/multi-user.target.wants/keepalived.service to /usr/lib/systemd/system/keepalived.service.
[root@lb02 ~]# systemctl start keepalived
#能夠看到地址被lb02接管,即IP地址已發生漂移
[root@lb02 ~]# ip addr | grep 10.0.0.4
[root@lb01 keepalived]# ip addr|egrep 10.0.0.3
inet 10.0.0.3/24 scope global secondary eth0:1
[root@lb01 ~]# systemctl start keepalived
[root@lb01 keepalived]# ip addr|egrep 10.0.0.3
[root@LVS-6 ~]# ip addr|egrep 10.0.0.3
[root@LVS-6 ~]# ip addr|egrep 10.0.0.3
inet 10.0.0.3/24 scope global secondary eth0:1
[root@lb01 keepalived]# /etc/init.d/keepalived start
Starting keepalived: [ OK ]
[root@lb01 keepalived]# ip addr|egrep 10.0.0.3
inet 10.0.0.3/24 scope global secondary eth0:1
[root@LVS-6 ~]# ip addr|egrep 10.0.0.3
Keepalived配置參數 | MASTER節點特殊參數 | BACKUP節點特殊參數 |
---|---|---|
router_id(惟一標識) | router_id lb01 | router_id lb02 |
state(角色狀態) | state MASTER | state BACKUP |
priority(競選優先級) | priority 150 | priority 100 |
高可用服務器對之間心跳線鏈路發生故障,致使沒法正常通訊
心跳線壞了(包括斷了,老化)
網卡及相關驅動壞了,IP配置及衝突問題(網卡直連)
心跳線之間鏈接的設備故障(網卡及交換機)
仲裁的機器出問題了(採用總裁的方案)
高可用服務器上開啓了iptables防火牆阻撓了心跳信息傳輸
高可用服務器上心跳網卡地址等信息配置不正確,致使發送心跳失敗
其餘服務配置不當等緣由,如心跳方式不一樣,心跳廣播衝突,軟件bug等。
tcpdump -nn -c 20 -i any host 224.0.0.18
[root@lb02 scripts]# firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface eth0 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
[root@lb02 scripts]# firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface eth1 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
iptables -I INPUT -i eth0 -d 224.0.0.0/8 -p vrrp -j ACCEPT
iptables -I OUTPUT -o eth0 -d 224.0.0.0/8 -p vrrp -j ACCEPT
tcpdump -nn -c 20 -i any host 224.0.0.18
HOSTNAME | IP | 說明 |
---|---|---|
lb01 | 10.0.0.5 | VIP:10.0.0.12(用於綁定A服務www.etiantian.org域名) |
lb02 | 10.0.0.6 | VIP:10.0.0.13(用於綁定B服務bbs.etiantian.org域名) |
web01 | 10.0.0.8 | Nginx web服務器1 |
web02 | 10.0.0.7 | Nginx web服務器2 |
[root@lb01 ~]# cat /etc/keepalived/keepalived.conf
global_defs {
router_id LVS_01
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3/24 dev eth0 label eth0:1
}
}
vrrp_instance VI_2 {
state BACKUP
interface eth0
virtual_router_id 52
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.4/24 dev eth0 label eth0:2
}
}
[root@lb01 ~]# cat /etc/keepalived/keepalived.conf
global_defs {
router_id LVS_02
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3/24 dev eth0 label eth0:1
}
}
vrrp_instance VI_2 {
state MASTER
interface eth0
virtual_router_id 52
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.4/24 dev eth0 label eth0:2
}
}
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
upstream server_pools {
server 10.0.0.7;
server 10.0.0.8;
server 10.0.0.9;
}
server {
listen 10.0.0.3:80;
server_name www.etiantian.org;
location / {
proxy_pass http://server_pools;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
access_log logs/access_www.log main;
}
server {
listen 10.0.0.4:80;
server_name blog.etiantian.org;
location / {
proxy_pass http://server_pools;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
access_log logs/access_blog.log main;
}
}
systemctl restart keepalived
systemctl restart nginx
10.0.0.3 www.etiantian.org
10.0.0.4 blog.etiantian.org
#!/bin/bash
nginxpid=$(ps -C nginx --no-header|wc -l)
#1.判斷 Nginx 是否存活,若是不存活則嘗試啓動 Nginx
if [ $nginxpid -eq 0 ];then
systemctl start nginx
sleep 3
#2.等待 3 秒後再次獲取一次 Nginx 狀態
nginxpid=$(ps -C nginx --no-header|wc -l)
#3.再次進行判斷, 如 Nginx 還不存活則中止 Keepalived,讓地址進行漂移,並退出腳本
if [ $nginxpid -eq 0 ];then
systemctl stop keepalived
fi
fi
global_defs {
router_id lb01
}
vrrp_script check_web {
script "/server/scripts/check_web.sh"
interval 5
weight 50
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 50
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3
}
}
vrrp_instance VI_2 {
state BACKUP
interface eth1
virtual_router_id 55
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 2222
}
virtual_ipaddress {
172.16.1.4
}
#2.調用並運行該腳本
track_script {
check_web
}
}
global_defs {
router_id lb01
}
vrrp_script check_web {
script "/server/scripts/check_web.sh"
interval 5
weight 50
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 50
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3
}
}
vrrp_instance VI_2 {
state BACKUP
interface eth1
virtual_router_id 55
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 2222
}
virtual_ipaddress {
172.16.1.4
}
#2.調用並運行該腳本
track_script {
check_web
}
}
[root@lb02 /server/scripts]# cat check_brain.sh
#!/bin/bash
lb01_vip=10.0.1.3
lb01_nginx=$(curl -x 10.0.1.5:80 -I -s -w "%{http_code}\n" -o /dev/null blog.oldzhang.com)
#ping -c 1 -W 1 ${lb01_ip} &>/dev/null
#若是lb01的IP能ping通,可是我本身也存在VIP,我就認爲發生裂腦了,我就把本身的keep幹掉
if [ ${lb01_nginx} -eq 200 -a `ip add|grep "$lb01_vip"|wc -l` -eq 1 ];then
echo "ha is bad" >> /tmp/check.txt
systemctl stop keepalived
else
echo "ha is ok" >> /tmp/check.txt
fi
#lb01存在vip地址
[root@lb01 ~]# ip addr | grep 10.0.0.4
inet 10.0.0.4/32 scope global eth0
#中止lb01上的keepalived,檢測vip已不存在
[root@lb01 ~]# systemctl stop keepalived
[root@lb01 ~]# ip addr | grep 10.0.0.4
global_defs { router_id lb02}vrrp_script check_web { script "/server/scripts/check_web.sh" interval 5 weight 50}vrrp_script check_brain { script "/server/scripts/check_split_brain.sh" interval 5 weight 50}vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 50 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 10.0.0.3 }}vrrp_instance VI_2 { state MASTER interface eth1 virtual_router_id 55 priority 150 advert_int 1 authentication { auth_type PASS auth_pass 2222 } virtual_ipaddress { 172.16.1.4 } #2.調用並運行該腳本 track_script { check_web check_brain }}