Keepalived 是一種高性能的服務器高可用或熱備解決方案, Keepalived 能夠用來防止服務器單點故障的發生,經過配合 Nginx 能夠實現 web 前端服務的高可用。雖然nginx的抗壓性很強,不多出現宕機,可是若是不作熱備,nginx一掛服務都會掛掉,因此熱備是必須的,固然,根據本身的實際業務需求來決定。html
keepalived是以VRRP協議爲實現基礎的,VRRP全稱Virtual Router Redundancy Protocol(虛擬路由冗餘協議)前端
keepalived是以VRRP協議爲實現基礎的,VRRP全稱Virtual Router Redundancy Protocol,即虛擬路由冗餘協議。nginx
虛擬路由冗餘協議,能夠認爲是實現路由器高可用的協議,即將N臺提供相同功能的路由器組成一個路由器組,這個組裏面有一個master和多個backup,master上面有一個對外提供服務的vip(該路由器所在局域網內其餘機器的默認路由爲該vip),master會發組播,當backup收不到vrrp包時就認爲master宕掉了,這時就須要根據VRRP的優先級來選舉一個backup當master。這樣的話就能夠保證路由器的高可用了。web
keepalived主要有三個模塊,分別是core、check和vrrp。core模塊爲keepalived的核心,負責主進程的啓動、維護以及全局配置文件的加載和解析。check負責健康檢查,包括常見的各類檢查方式。vrrp模塊是來實現VRRP協議的。算法
keepalived只有一個配置文件
keepalived.conf
。裏面主要包括如下幾個配置區域,分別是global_defs
、vrrp_instance
、和virtual_server
。後端
主要是配置故障發生時的通知對象以及機器標識,通俗點說就是出情況後發郵件通知的一個配置。centos
global_defs {
notification_email { 故障發生時給誰發郵件通知
a@abc.com
b@abc.com
...
}
notification_email_from alert@abc.com 通知郵件從哪一個地址發出
smtp_server smtp.abc.com smpt_server 通知郵件的smtp地址。
smtp_connect_timeout 30 鏈接smtp服務器的超時時間
enable_traps 開啓SNMP陷阱
router_id host163 標識本節點的字條串,一般爲hostname
}
複製代碼
vrrp_instance用來定義對外提供服務的VIP區域及其相關屬性bash
vrrp_instance VI_1 {
state MASTER state 能夠是MASTER或BACKUP
interface ens33 本機網卡的名字
virtual_router_id 51 取值在0-255之間,用來區分多個instance的VRRP組播
priority 100 權重
advert_int 1 發VRRP包的時間間隔,即多久進行一次master選舉
authentication { 身份認證區
auth_type PASS
auth_pass 1111
}
virtual_ipaddress { 虛擬ip地址
192.168.27.160
}
}
複製代碼
超大型的LVS中用到,我在這裏不用它。服務器
virtual_server 192.168.200.100 443 {
delay_loop 6 延遲輪詢時間(單位秒)
lb_algo rr 後端調試算法
lb_kind NAT LVS調度類型
persistence_timeout 50
protocol TCP
real_server 192.168.201.100 443 { 真正提供服務的服務器
weight 1
SSL_GET {
url {
path /
digest ff20ad2481f97b1754ef3e12ecd3a9cc 表示用genhash算出的結果
}
url {
path /mrtg/
digest 9b3a0c85a887a256d6939da88aabd8cd
}
connect_timeout 3
nb_get_retry 3 重試次數
delay_before_retry 3 下次重試的時間延遲
}
}
}
複製代碼
yum install keepalived -y
複製代碼
我準備了四個主機,ip是192.168.27.166-169
,都搭建nginx服務,而後把166和167分別當主備機。負載均衡
nginx配置
upstream centos_pool{
server s168:80;
server s169:80;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
# root /usr/share/nginx/html;
# index index.html index.htm;
proxy_pass http://centos_pool;
}
複製代碼
四個主機都用該配置啓動,看起來是4個nginx服務,在這個實例裏不是這樣的,不一樣的是166和167是nginx服務,168和169是web服務(用nignx開放80端口來模仿服務)。
換句話說,166和167用來作負載均衡,168和169是web服務主機。
我在168和169的主機/usr/share/nginx/html/index.html
裏作了簡單的標識:
好了,下來配置keepalived
配置keepalived
166主機配置:
! Configuration File for keepalived
global_defs {
router_id LVS_DEVEL
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.27.160
}
}
複製代碼
能夠說是最核心的配置了,也是最簡配置,想要配置郵件服務能夠對照上文中的模塊介紹註釋去弄。lvs配置也同樣。
167熱備配置:
! Configuration File for keepalived
global_defs {
router_id LVS_DEVEL
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 50
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.27.160
}
}
複製代碼
能夠看出,除了state MASTER/BACKUP
和priority 100
屬性不一樣,其餘都相同也必須相同。 好了,如今啓動keepalived,從ip路由就能看出誰是主機(接管節點的網卡會綁定VIP地址192.168.27.160)
一切配置正常後,我把166上的nginx停了,會發生什麼呢?
167會接手虛擬ip地址,完成雙機熱備任務嗎?答案是不會,由於你回頭看看,keepalived沒有一點是和nginx有關係的,兩服務互不影響。keepalived實際上是監控master上的keepalived的心跳的。因此,我把keepalived服務也關掉。
[root@s166 keepalived]# nginx -s stop
[root@s166 keepalived]# service keepalived stop
Redirecting to /bin/systemctl stop keepalived.service
複製代碼
而後再查看166的ip路由
[root@s166 keepalived]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:7b:59:07 brd ff:ff:ff:ff:ff:ff
inet 192.168.27.166/24 brd 192.168.27.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::83ee:6998:a0d4:7974/64 scope link tentative dadfailed
valid_lft forever preferred_lft forever
inet6 fe80::2513:4c77:5da7:f031/64 scope link tentative dadfailed
valid_lft forever preferred_lft forever
inet6 fe80::99b3:c79:5377:c3fe/64 scope link tentative dadfailed
valid_lft forever preferred_lft forever
複製代碼
能夠看到是沒有192.168.27.160
這個虛擬ip了。那咱們再看一下167是否有,若是有,證實配置生效。
192.168.27.160
這個連接,會發現運行正常。
既然keepalived和nginx沒有關聯,那咱們能夠寫個腳本監聽nginx,若是nginx掛了,而後用命令把keepalived也停掉,這樣就會完成雙機熱備的任務。
建立腳本check_nginx.sh
#!/bin/bash
A=`ps -C nginx --no-header | wc -l`
if [ $A -eq 0 ];then
echo "restart the nginx server" >> /etc/keepalived/keepalived_error.log
/usr/sbin/nginx
sleep 2
if [ `ps -C nginx --no-header | wc -l` -eq 0 ];then
echo "keepalived is closed" >> /etc/keepalived/keepalived_error.log
/usr/bin/ps -ef | grep "keepalived" | grep -v "grep" | cut -c 9-15 | xargs kill -9
echo /usr/bin/ps -ef | grep "keepalived" >> /etc/keepalived/keepalived_error.log
fi
fi
複製代碼
對了,記住修改腳本可執行權限。爲何要重定向呢,由於echo
不會打印在控制檯上,咱們能夠跟蹤keepalived_error.log
來判斷腳本是否執行。
那既然這樣,咱們的腳本如何控制時間呢?sleep的時間也得控制好,在保持高性能下轉換越快越好。因此,咱們把腳本加載到keepalived配置中,keepalived每進行一次選舉,就執行一次腳本。
把腳本添加到keepalived任務中
! Configuration File for keepalived
global_defs {
router_id LVS_DEVEL
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.27.160
}
track_script {
chk_nginx # nginx存活狀態檢測腳本
}
}
vrrp_script chk_nginx {
script "/etc/keepalived/check_nginx.sh"
interval 2
weight -20
}
複製代碼
同理,BACKUP主機也要配置
! Configuration File for keepalived
global_defs {
router_id LVS_DEVEL
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 50
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.27.160
}
track_script {
chk_nginx
}
}
vrrp_script chk_nginx {
script "/etc/keepalived/check_nginx.sh"
interval 2
weight -20
}
複製代碼
那如何測試不重啓nginx,讓它直接關keepalived,而後啓用BACKUP呢。我把那行重啓nginx腳本註釋掉。而後再跑。
#!/bin/bash
A=`ps -C nginx --no-header | wc -l`
if [ $A -eq 0 ];then
# echo "restart the nginx server" >> /etc/keepalived/keepalived_error.log
# /usr/sbin/nginx
# sleep 2
# if [ `ps -C nginx --no-header | wc -l` -eq 0 ];then
echo "keepalived is closed" >> /etc/keepalived/keepalived_error.log
/usr/bin/ps -ef | grep "keepalived" | grep -v "grep" | cut -c 9-15 | xargs kill -9
echo /usr/bin/ps -ef | grep "keepalived" >> /etc/keepalived/keepalived_error.log
# fi
fi
複製代碼
說明腳本和keepalived整合沒問題,將註釋去掉。任務完成。
[root@s166 keepalived]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:7b:59:07 brd ff:ff:ff:ff:ff:ff
inet 192.168.27.166/24 brd 192.168.27.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 192.168.27.160/32 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::83ee:6998:a0d4:7974/64 scope link tentative dadfailed
valid_lft forever preferred_lft forever
inet6 fe80::2513:4c77:5da7:f031/64 scope link tentative dadfailed
valid_lft forever preferred_lft forever
inet6 fe80::99b3:c79:5377:c3fe/64 scope link tentative dadfailed
valid_lft forever preferred_lft forever
複製代碼
[root@s167 keepalived]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:d4:26:34 brd ff:ff:ff:ff:ff:ff
inet 192.168.27.167/24 brd 192.168.27.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 192.168.27.160/32 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::99b3:c79:5377:c3fe/64 scope link noprefixroute
valid_lft forever preferred_lft forever
複製代碼
雖然咱們把s166都關閉了keepalived,可是ip路由還會有虛擬ip 192.168.27.160
,這個多是keepalived並無徹底終止。可是我在刷新的時候沒有出現錯誤頁面,證實並無影響到服務的正常運行。不屬於裂腦問題。我將腳本中的強制killkeepalived
的操做換成更委婉的/usr/sbin/service keepalived stop
,解決了該問題.
拓展:高可用之裂腦問題