keepalived+lvs+nginx 高可用
一、VRRP協議
VRRP(Virtual Router Redundancy Protocol,虛擬路由冗余協議)是一種容錯協議。通常,一個網絡內的所有主機都設置一條默認路由,這樣,主機發出的目的地址不在本網段的報文將被通過默認路由發往路由器RouterA,從而實現了主機與外部網絡的通信。當路由器RouterA 壞掉時,本網段內所有以RouterA 為默認路由下一跳的主機將無法與外部通信,這就是單點故障。VRRP就是為解決上述問題而提出的。
VRRP 將局域網的一組路由器組織成一個虛擬路由器。這個虛擬路由器通過虛擬IP對外提供服務,而在虛擬路由器內部是多個物理路由器協同工作,同一時間內只有一臺物理路由器占有這個虛擬IP,作為master實際負責ARP響應和數據包轉發等工作;其它物理路由器作為backup,不提供對外服務,僅接收master的vrrp狀態通告信息。
master由優先級選舉產生,每個物理路由器都有一個 1-255 之間的優先級,級別最高的(highest priority)將成為master,若優先級相同,則IP地址較大者勝出。
在vrrp協議中,所有的報文都是通過IP多播形式發送的,而在一個虛擬路由器中,只有處於master角色的路由器會一直發送VRRP數據包,處於backup角色的路由器只接收master發過來的報文信息,用來監控master的運行狀態,因此不會發生backup搶占的現象,除非它的優先級更高。當master不可用時,backup也就無法收到master發過來的報文信息,於是就認定master出現故障,接著多臺backup就會進行優先級最高的backup就將成為新的master,這樣就保證了服務的持續可用性。
二、keepalived的組件
keepalived的主要組件:
WatchDog:負責監控checkers和VRRP進程
Checkers:實現對服務器運行狀態檢測和故障隔離
VRRP Stack:實現vrrp協議,即實現HA集群中失敗切換功能
IPVS wrapper:將設置好的ipvs規則送給內核ipvs模塊
Netlink Reflector:負責虛擬IP的設置和切換
三、keepalive的適用場景
keepalived理論上可以為mysqld,httpd等服務提供高可用,給這些服務做高可用通常需要配置共享存儲資源,對此keepalived需要借助額外的命令或腳本實現,這種情況下keepalived的性能是顯然不如heartbeat或corosync的。keepalived適合提供輕量級的高可用方案,如對作為反向代理的nginx、haproxy以及ipvs做高可用,給這些服務做高可用都無需配置共享存儲資源。keepalived即能給ipvs做高可用,又能基於ipvs做負載均衡,並且能應用一系列的健康狀態檢測機制,獲知後端服務器的狀態,實現服務器池的動態維護和管理。
四、使用keepalived做反向代理nginx的高可用
前提條件:
①各節點要能互相解析主機名。建議通過hosts解析
②各節點時間同步
③iptables和selinux不對keepalived產生影響
安裝:
yum install keepalived
查看配置文件幫助信息:man keepalived.conf
keepalived配置文件主要包括四大段:
global_defs:全局配置段,主要配置郵件通知和機器標識
vrrp_instance:vrrp實例配置段,配置高可用集群
virtual_server:lvs配置段,配置負載均衡集群
vrrp_script:vrrp腳本配置段,用來實現對集群資源的監控,要在vrrp_instance配置段中調用才能生效
註:以上各配置段並非都必不可少,可按需配置。如果只是單純地做負載均衡集群,可不用配置vrrp_instance段,反過來也是;甚至如果不想使用郵件通知,都不需要配置global_defs段。
我們通過YUM安裝的默認是沒有日誌的 需要手動開啟
vi /etc/sysconfig/keepalived
修改成KEEPALIVED_OPTIONS="-D -S 0"
vi /etc/rsyslog.conf
添加一項 local0.* /var/log/keepalived.log
[root@lishuai keepalived]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived #以!開頭為註釋
global_defs { #全局配置段
notification_email {#指定keepalived在發生事件(如切換、故障)時發送email給誰,有多個收件人個寫多行
root@loaclhost #收件人
}
notification_email_from kaadmin@localhost #發件人
smtp_server 127.0.0.1 #smtp服務器地址
smtp_connect_timeout 30 #連接SMTP服務器超時時間
router_id lishuai #機器標識;通常為hostname,但不是必須為hostname,可自己定義,會顯示在郵件主題中
}
vrrp_script chk_mantaince_down {# #vrrp腳本配置段,要在vrrp實例中調用才生效
script "/etc/keepalived/down.sh" #信號0用來判斷進程的狀態;返回狀態碼為0表示正常,返回狀態碼非0表示異常
interval 1 #檢查頻率 默認一秒一次
}
vrrp_instance VI_1 { #定義對外提供服務的VIP vrrp_instance配置
state MASTER #指定vrrp_instance的初始狀態,是MASTER還是BackUP主要還是看優先級,因為vrrp默認工作在搶占模式
interface enp3s0 #指定vrrp_instance綁定的網卡,最終會通過指定的網卡宣告VIP
virtual_router_id 51 #虛擬路由id,用來區分多個instance的VRRP組播
priority 100 #優點級,可為1-255
advert_int 1 #發送心跳信息的間隔時間,MASTER會每隔1秒發送一個報文告訴組內其他機器,自己還活著。
authentication {#節點間通信認證,認證類型有PASS和AH
auth_type PASS
auth_pass lishuai #在一個vrrp實例中,master和backup要使用相同密碼才能正常通信
}
virtual_ipaddress {
192.168.2.90/24 dev enp3s0 lable enp3s0:0 #虛擬IP地址,會添加在master上
}
track_script { #調用vrrp腳本,可調用多個
chk_mantaince_down
}
}
vrrp_instance VI_2 {
state BACKUP
interface enp3s0
virtual_router_id 52
priority 99
advert_int 1
authentication {
auth_type PASS
auth_pass 9129
}
virtual_ipaddress {
192.168.2.100/24 dev enp3s0 lable enp3s0:1
}
track_script {
chk_mantaince
}
}
# vrrp實例配置段中其它常用參數:
nopreempt 表示不搶占。允許一個priority較低的節點保持master狀態,即使priority更高的節點恢復正常。
因為節點的切換會畢竟會造成服務短暫的中斷,而且存在一定的風險和不穩定性。因此應盡量減少切換操作。
要配置非搶占模式,在優先級較高節點的配置文件中:
state BACKUP
nopreempt
preempt_delay 搶占延遲時間;有時候系統重啟之後需要經過一段時間後才能工作,在這種情況下進行主備切換是沒必要的
notify_master/backup/fault 分別表示節點狀態為主/備/出錯時所執行的腳本
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
use_vmac 是否使用VRRP的虛擬MAC地址
[root@lishuai keepalived]# cat down.sh
#!/bin/bash #這個腳本的功能是當檢測到/etc/keepalived/down這個文件存在就給優先級減去2
if [ -f /etc/keepalived/down ];then
weight -2
fi
實驗一
這裏我們用192.168.2.18和192.168.2.29兩臺機器模擬最簡單的keepalived,當任意一臺負載均衡機器掛了之後vip能自動遷移到另一臺主機,我們先以192.168.2.18為master
這裏我們可以註意一下 兩臺主機的keepalived.conf文件有略微差異
兩臺機器開啟keepalived服務
systemctl start keepalived;ssh [email protected] "systemctl start keepalived"
此時我們發現vip已經被綁定在192.168.2.18這臺主機上了,我們再/etc/keepalived/下創建一個down文件驗證腳本檢測功能
touch //etc/keepalived/down
systemctl restart keepalived.service ;ssh [email protected] 'systemctl restart keepalived'
這是我們就會發現vip192.168.2.90就自動遷移到192.168.2.29這臺主機上了,而192.168.2.18這臺主機上已經沒了
實驗二 簡單雙主模型
在上述拓撲圖中我們始終有一臺負載均衡主機處於休息狀態,這樣會犧牲一部分機器性能,在下面拓撲圖中,我們讓兩臺負載均衡主機同時做master,兩臺主機有不同的vip地址,我們用DNS做輪詢,是兩個vip指向同一網址如www.lishuai.com,這樣用戶訪問www.lishuai.com 就會被調度到這兩臺負載均衡主機上,這兩臺負載均衡主機會把請求根據調度算法發給後端的RS主機,當其中一臺負載均衡主機掛了之後我們就把他的vip遷移到另一臺機器上。這樣用戶始終能夠正常訪問
我們在上次配置下添加如上配置 ,並創建名為chk_mantaince的腳本
systemctl restart keepalived.service ;ssh [email protected] 'systemctl restart keepalived'
這次我們在192.168.2.18主機創建down,在192.168.2.29主機創建down-vi_2文件
結果如下:
實驗三 keepalived+lvs模型
虛擬機實驗 網絡選擇vmware2 ,在我們之前的配置下添加如下
virtual_server 192.168.2.90 80 {
delay_loop 6
lb_algo wrr
lb_kind DR
protocol TCP
netmask 255.255.255.0
real_server 192.168.2.30 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.2.57 80 {
weight 2
HTTP_GET {
url {
path /
status_code 200
}
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
delay_loop 延遲輪詢時間(單位秒)。
lb_algo 後端調試算法(load balancing algorithm)(rr|wrr|ls|wlc|sh|wsh等)
lb_kind LVS調度類型NAT/DR/TUN。
virtualhost 用來給HTTP_GET和SSL_GET配置請求header的。
sorry_server 當所有real server都掉線時,sorry server頂替。
real_server 真正提供服務的服務器。
weight 權重。
notify_up/down 當real server下線或啟動時執行的腳本。
健康檢查的方式,N多種方式。
path 請求real serserver上的路徑。
digest或者status_code 分別表示用genhash算出的結果和http狀態碼。
connect_port 健康檢查,如果端口通則認為服務器正常。
connect_timeout,nb_get_retry,delay_before_retry分別表示超時時長、重試次數,下次重試的時間延遲。
systemctl start keepalived.service ;ssh [email protected] 'systemctl start keepalived' 啟動keepalived
我們可以查看一下此時已經在192.168.2.29上自動生成lvs規則
我們在192.168.2.29裏 touch down ,此時192.168.2.90這個IP就自動轉移到192.168.2.28這臺主機上了,這臺主機也自動生產了lvs規則
我們訪問一下可以發現這和我們在keepalived配置文件裏設置的規則是一樣的。
實驗四 keepalive+nginx雙主模型
這裏我們用keepalived把兩個nginx負載均衡主機同時做master,當任何一臺nginx主機down了就把負載遷移到另一臺主機上,例如當負載均衡主機2 down了就會把192.168.2.100這個IP給轉移到nginx負載均衡主機1上
[root@lishuai keepalived]# vi keepalived.conf #192.168.2.18的配置文件
router_id lishuai
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id lishuai
}
vrrp_script chk_mantaince_down {
script "/etc/keepalived/down.sh"
interval 1
}
vrrp_script chk_mantaince {
script "/etc/keepalived/killall.sh"
interval 1
weight -20
}
vrrp_instance VI_1 {
state MASTER
interface enp3s0
virtual_router_id 66
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass lishuai
}
virtual_ipaddress {
192.168.2.90/24 dev enp3s0
}
track_script {
chk_mantaince
}
}
vrrp_instance VI_2 {
state BASKUP
interface enp3s0
virtual_router_id 77
priority 99
advert_int 1
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
192.168.2.100/24 dev enp3s0
}
track_script {
chk_mantaince
}
下面是192.168.2.29的配置文件
! Configuration File for keepalived
global_defs {
notification_email {
root@loaclhost
}
notification_email_from kaadmin@localhost
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id lishuai
}
vrrp_script chk_mantaince_down {
script "/etc/keepalived/down.sh"
interval 1
}
vrrp_script chk_mantaince {
script "/etc/keepalived/killall.sh"
interval 1
weight -20
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 66
priority 99
advert_int 1
authentication {
auth_type PASS
auth_pass lishuai
}
virtual_ipaddress {
192.168.2.90/24 dev ens33
}
track_script {
chk_mantaince
}
}
vrrp_instance VI_2 {
state MASTER
interface ens33
virtual_router_id 77
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
192.168.2.100/24 dev ens33
}
track_script {
chk_mantaince
}
}
下面是killall.sh
這裏再次註意 新版本的keepalived不支持采用類似script "killall -0 nginx &> /dev/null"這種形式,必須寫成shell文件,如果shell文件執行失敗則執行配置文件後面的weight -20
這是我們nginx.conf裏的負載均衡設置
驗證:
當我們執行完重載keepalived後如下
負載功能這是也正常
我們把192.168.2.18的nginx給下線
此時192.168.2.90這個IP地址轉移到192.168.2.29這臺負載均衡主機了,此時192.168.2.90和192.168.2.100都依然能正常訪問,我們啟動192.168.2.18上的nginx,然後把192.168.2.29上的nginx下線,此時192.168.2.90和192.168.2.100都被移動回192.168.2.18這臺負載均衡主機上了
此時訪問192.168.2.90和192.168.2.100依舊正常負載均衡
keepalived+lvs+nginx 高可用