上述演示中,不論是lvs-nat仍是lvs-nat模型,都會有2個遺留問題:前端
(1) 若是調度器服務器掛了,如何對調度器作高可用linux
(2) 若是RS中某臺服務器掛了,如何對RS作集羣的健探測nginx
健康監測的方式有不少種,好比網絡層可使用icmp ping監測主機的存活狀態,傳輸層可使用tcp端口監測工具探測端口的可用性,好比nmap,應用層,好比能夠對關鍵服務發起請求。算法
而實現高可用的方案通常有2種,一種是vrrp協議的實現,好比keepalived,一種是ais的實現方案,好比heartbeat, corosync, pacemaker。其中ais是很是完備,很是重量級的實現。windows
首先,這裏以很是簡單的方式描述下ais方案,首先假設這樣一種場景,由多臺服務器提供相同的服務,好比是httpd服務,此時集羣中每臺機器須要知道對方的生存情況,好比機器A持續的向其餘機器發送信息表示本身存活(假如連續3次失敗則會被斷定爲非存活狀態),這種方式被稱爲心跳檢測,可是可能會有這樣一種網絡緣由形成的故障,A認爲本身是存活的,可是信息沒有成功被其餘服務器接收,好比B和C都認爲A是非存活狀態,此時會形成分裂現象,解決這個問題須要一個仲裁方案,好比最簡單的少數服從多數原則,這也是通常推薦奇數臺機器構建集羣的緣由,有時候只有2臺,可使用好比網關服務器當觀察者湊夠3臺也能夠,總之必須有一個仲裁機制。假設此時多數的認爲機器B能夠當作Master向外提供服務,須要一個機制能夠中止掉機器A的服務,而且剝奪他的ip使用權,最簡單的方式,就是停掉A,而後在機器B上配置的接口上配置一個別名。而實際上ais的實現很是複雜,分爲三層,最底層是集羣事務層,還有資源管理層和資源代理層,它是一個很是完備的實現,基本上能夠知足一切的高可用方案,後面會詳細介紹。bash
這裏咱們關注的是vrrp協議,,Virtual Redundant Routing Protocol,vrrp協議是很是老的一個協議,是一個虛擬的路由器協議,而keepalived則是vrrp協議的實現。服務器
關於VRRP的協議詳情能夠參考華爲等公司一些vrrp協議白皮書,由於vrrp協議本來就是用來作虛擬路由之類的。網絡
VRRP中術語說明:app
VRRP的工做過程:負載均衡
(1) 虛擬路由器根據優先級選舉Master。Master經過發送免費ARP報文,將本身的虛擬MAC地址通知給與它鏈接的設備或者主機,從而承擔報文轉發任務。
(2) Master路由器週期性發送VRRP報文,以公佈其配置信息和工做狀態
(3)若是Master出現故障,根據優先級從Backup中選舉
(4)虛擬路由器狀態切換時,Master路由器由一臺設備切換爲另外一臺,新的Master路由器只是簡單地發送一個攜帶虛擬路由器的MAC地址和虛擬IP地址信息的免費ARP報文,這樣就能夠更新與它相鏈接的主機或者設備中的ARP相關信息。網絡上的主機感知不到Master路由器已經切換爲另一個臺設備
(5)Backup路由器的優先級高於Master時,根據工做方式決定是否從新選舉
VRRP的工做模式
keepalived
keepalived做爲vrrp協議的實現,設計目的是爲了高可用ipvs服務器,他可以在配置文件定義ipvs規則,並能對RS的健康狀態進行探測;vrrp_script,vrrp_track
keepalivedz中包含多個組件:
控制組件:配置文件分析器
內存管理
IO複用
核心組件
vrrp stack
checker
ipvs wrapper
watch dog
HA集羣配置的前提,通常Linux都須要如下配置
(1)各節點時間同步,Centos上能夠基於ntp協議,Centos7上能夠是chrony
(2)確保iptables以及selinux不會阻礙;
(3)各節點之間經過主機名互相銅線,即名稱解析服務器的解析結果必須和"uname -n"命令的結果一致;
(4)各個節點之root用戶基於密鑰認證的ssh通訊;
yum -y install keepalived
同步下時間:
ntpdate time.windows.com hwclock -w
經過命令rpm -qc keepalived發現配置文件只須要關注keepalived.conf便可,詳情使用man keepalived.conf觀察,下面簡要說明一下,Keepavlived分爲多個配置段,global配置段,vppr配置段,lvs配置段
global_defs:定義全局配置
global_defs { notification_email { root@localhost } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id ysz202 vrrp_mcast_group4 224.0.100.18 }
說明:
vrrp_instance : vrrp實例配置
定義一個虛擬路由實例
state MASTER|BACKUP:在當前VRRP實例中此節點的初始狀態;
interface IFACE_NAME:vrrp用於綁定vip的接口;
virtual_router_id #:當前VRRP實例的VRID,可用範圍爲0-255,默認爲51;
priority #:當前節點的優先級,可用範圍0-255;
advert_int 1:通告時間間隔;
authentication { #認證機制
# PASS||AH
# PASS - Simple Passwd (suggested)
# AH - IPSEC (not recommended))
auth_type PASS
# Password for accessing vrrpd.
# should be the same for all machines.
# Only the first eight (8) characters are used.
auth_pass 1234
}
# 最關鍵的。定義vip
virtual_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
}
# 一個主機上可能有多個接口,定義要監控的接口
trace_interface {
eth0
eth1
...
}
nopreempt #非搶佔模式,默認是搶佔模式,若是2個服務器性能有優劣之別,能夠搶佔..
#通告腳本定義
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
其中的腳本notify.sh能夠大體以下
#!/bin/bash # contact='root@localhost' notify() { subject="$(hostname) to be $1 :vip floating" body="$(date +'%F %T'): vrrp transition, $(hostname) change to be $1" echo $body | mail -s "$subject" $contact } case $1 in master) notify master ;; backup) notify backup ;; fault) notify fault ;; *) echo "Usage:$(basename $0) {master|backup|fault}" ;; esac
virtual_server : 虛擬服務器
功能描述:
f
virtual server IP port或者vitual server FWM #
virtual_server 192.168.200.100 443 { delay_loop 6 # lb_algo rr #負載均衡調度算法 lb_kind NAT #調度類型 nat_mask 255.255.255.0 # persistence_timeout 50 #持久鏈接時長 protocol TCP #只支持TCP協議 # quality regression. Defaults to 1. quorum 1 sorry_server 192.168.1.202 80 real_server 192.168.201.100 443 { weight 1 #notify_up <STRING>|<QUOTED-STRING> #notify_down <STRING>|<QUOTED-STRING> #應用層檢測 SSL_GET { url { path / digest ff20ad2481f97b1754ef3e12ecd3a9cc #特徵碼 } url { path /mrtg/ status_code 200 #基於狀態碼斷定 } connect_timeout 3 #鏈接的超時時長 nb_get_retry 3 #鏈接的重試次數 delay_before_retry 3 #鏈接的重試間隔 } } }
總結:
若是隻是須要vip服務,能夠只配置vrrp實例,若是須要keepalived來幫助完成lvs負載均衡才須要配置Vitual Server
vrrp_script: 資源腳本
track_script: 調用vrrp_script腳本去監控資源;
vrrp_script chk_httpd { script "killall -0 httpd" interval 2 weight -5 } vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 51 priority 98 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.111/32 brd 192.168.1.111 dev eth0 label eth0:0 } track_script { chk_httpd } notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault" }
說明:上述配置中命令killall -0 httpd 用來檢測當前httpd進程是否存活,假如沒有的話返回失敗,當前服務器的優先級會下降,在搶佔工做模式下由Master->Backup實現地址漂移,這種方式能夠爲任何服務作高可用,好比說這裏的httpd能夠改爲Nginx。
設計以下:
ysz211(192.168.1.211)和ysz214(192.168.1.214)做爲VS提供ipvsadm服務,使用keepalived作ha實現高可用,虛擬ip爲192.168.1.204在ysz211和ysz214上地址漂移
ysz212(192.168.1.212)和ysz213(192.168.1.213)做爲RS提供httpd服務
yum install ipvsadm yum install keepalived
keepalived的配置文件keepalived.conf大體以下:
ysz211爲MASTER,ysz214爲BACKUP,另一臺只須要將state設置爲BACKUP且優先級調低爲98便可
global_defs {
notification_email {
root@localhost
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_mcast_group4 224.0.100.18
}
vrrp_instance VI_1 {
state MASTER
interface eno16777736
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.204 dev eno16777736 label eno16777736:0
}
}
virtual_server 192.168.1.204 80 {
delay_loop 6
lb_algo rr
lb_kind DR
protocol TCP
real_server 192.168.1.212 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
real_server 192.168.1.213 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}
使用tail -f /var/log/messages發現成功啓動,信息以下:
Nov 14 21:38:05 www Keepalived_healthcheckers[5180]: Opening file '/etc/keepalived/keepalived.conf'.
Nov 14 21:38:05 www Keepalived_healthcheckers[5180]: Configuration is using : 17026 Bytes
Nov 14 21:38:05 www Keepalived_healthcheckers[5180]: Using LinkWatch kernel netlink reflector...
Nov 14 21:38:05 www Keepalived_healthcheckers[5180]: Activating healthchecker for service [192.168.1.212]:80
Nov 14 21:38:05 www Keepalived_healthcheckers[5180]: Activating healthchecker for service [192.168.1.213]:80
Nov 14 21:38:06 www Keepalived_vrrp[5181]: VRRP_Instance(VI_1) Transition to MASTER STATE
Nov 14 21:38:07 www Keepalived_vrrp[5181]: VRRP_Instance(VI_1) Entering MASTER STATE
Nov 14 21:38:07 www Keepalived_vrrp[5181]: VRRP_Instance(VI_1) setting protocol VIPs.
Nov 14 21:38:07 www Keepalived_vrrp[5181]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eno16777736 for 192.168.1.204
Nov 14 21:38:07 www Keepalived_healthcheckers[5180]: Netlink reflector reports IP 192.168.1.204 added
Nov 14 21:38:12 www Keepalived_vrrp[5181]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eno16777736 for 192.168.1.204
且ipvsadm也成功啓動,截圖以下
搭建成功,能夠模擬ysz211 keepalived 故障和ysz213 httpd服務故障,對外服務都可用,從而同時實現了負載均衡和高可用的目的。
雙主模型實際上也是主備模型,2個實例互爲主備,好比一個httpd服務,一個nginx服務,儘量減小資源浪費,注意下面是2個不一樣的ip地址,所以還能夠在DNS解析服務器上再作一次負載均衡,使得請求分散到2個ip中,使得前端2個調度器都不會空閒。
ysz202配置文件
global_defs { notification_email { root@localhost } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id ysz202 vrrp_mcast_group4 224.0.100.18 } vrrp_script chk_httpd { script "killall -0 httpd" interval 2 weight -5 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.111/32 brd 192.168.1.111 dev eth0 label eth0:0 } track_script { chk_httpd } notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault" } vrrp_instance VI_2 { state BACKUP interface eth0 virtual_router_id 52 priority 98 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.112/32 brd 192.168.1.111 dev eth0 label eth0:1 } track_script { chk_httpd } notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault" }
ysz204上配置文件
global_defs { notification_email { root@localhost } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id ysz202 vrrp_mcast_group4 224.0.100.18 } vrrp_script chk_httpd { script "killall -0 httpd" interval 2 weight -5 } vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 51 priority 98 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.111/32 brd 192.168.1.111 dev eth0 label eth0:0 } track_script { chk_httpd } notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault" } vrrp_instance VI_2 { state MASTER interface eth0 virtual_router_id 52 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.112/32 brd 192.168.1.111 dev eth0 label eth0:1 } track_script { chk_httpd } notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault" }