單主模式Keepalive之Nginx 調(diào)度
實驗?zāi)康?/strong>:
實現(xiàn)Nginx調(diào)度的高可用,當(dāng)一臺Nginx調(diào)度器故障時理郑,啟用備用的Nginx調(diào)度,在架構(gòu)中,啟用了kepalive節(jié)點狀態(tài)通知腳本機制怨酝,當(dāng)keepalive的狀態(tài)由MASTER變?yōu)锽ACKUP或由BACKUP變?yōu)镸ASTER時,以郵件通知用戶那先,通過在通知腳本文件中定義BACKUP狀態(tài)的節(jié)點啟用nginx服務(wù)农猬,是為了防止因Nginx服務(wù)故障導(dǎo)致節(jié)點權(quán)重降低從而變?yōu)锽ACKUP狀態(tài),為了避免此種現(xiàn)象售淡,故在轉(zhuǎn)換為BACKUP狀態(tài)時需啟動一次Nginx服務(wù)斤葱。
實驗環(huán)境
keepalive-A 172.16.253.108
keepalive-B 172.16.253.105
Nginx-A 172.16.253.108
Nginx-B 172.16.253.105
LVS-RS1 172.16.250.127
LVS-RS2 172.16.253.193
VIP 172.16.253.150
client 172.16.253.177
web服務(wù)集群
為了更好的觀察實驗結(jié)果,故在此將RS1和RS2的web頁面內(nèi)容設(shè)置不一致揖闸,以致可以更清晰的區(qū)分RS1服務(wù)端和RS2服務(wù)端
LVS-RS1
[root@LVS-RS1 ~]# systemctl restart chronyd \\多臺服務(wù)器時間同步
[root@LVS-RS1 ~]# iptables -F
[root@LVS-RS1 ~]# setenforce 0
[root@LVS-RS1 ~]# yum -y install nginx
[root@LVS-RS1 ~]# vim /usr/share/nginx/html/index.html
<h1> Web RS1 </h1>
[root@LVS-RS1 ~]# systemctl start nginx
LVS-RS2
[root@LVS-RS2 ~]# systemctl restart chronyd \\多臺服務(wù)器時間同步
[root@LVS-RS2 ~]# iptables -F
[root@LVS-RS2 ~]# setenforce 0
[root@LVS-RS2 ~]# yum -y install nginx
[root@LVS-RS2 ~]# vim /usr/share/nginx/html/index.html
<h1> Web RS2 </h1>
[root@LVS-RS2 ~]# systemctl start nginx
nginx調(diào)度集群
nginx-A
[root@nginx-A ~]# yum -y install nginx
[root@nginx-A ~]# vim /usr/share/nginx/html/index.html
</h1> sorry from keepalive-A </h1>
[root@nginx-A ~]# vim /etc/nginx/nginx.conf
http {
upstream websrvs {
server 172.16.250.127:80;
server 172.16.253.193:80;
}
}
server {
listen 80 default_server;
location / {
proxy_pass http://websrvs;
}
}
[root@nginx-A ~]# systemctl start nginx
nginx-B
[root@nginx-B ~]# yum -y install nginx
[root@nginx-B ~]# vim /usr/share/nginx/html/index.html
</h1> sorry from keepalive-B </h1>
[root@nginx-B ~]# vim /etc/nginx/nginx.conf
http {
upstream websrvs {
server 172.16.250.127:80;
server 172.16.253.193:80;
}
}
server {
listen 80 default_server;
location / {
proxy_pass http://websrvs;
}
}
[root@nginx-B ~]# systemctl start nginx
keepalive集群
keepalive-A
[root@keepalive-A ~]# yum -y install keepalived
[root@keepalive-A ~]# vim /etc/keepalived/notify.sh \\定義狀態(tài)檢測通知腳本揍堕,當(dāng)節(jié)點變?yōu)锽ACKUP時,啟動nginx服務(wù)
#!/bin/bash
#
contact='root@localhost' \\通知的聯(lián)系者汤纸,即本地郵件服務(wù)器的通知郵件接受者
notify() {
local mailsubject="$(hostname) to be $1, vip floating" \\指定郵件標(biāo)題
local mailbody="$(date +'%F %T'): vrrp transition, $(hostname) changed to be $1" \\指定郵件正文
echo "$mailbody" | mail -s "$mailsubject" $contact \\發(fā)送通知信息郵件到郵件接收者
}
case $1 in
master)
notify master
;;
backup)
notify backup
systemctl start nginx
;;
fault)
notify fault
;;
*)
echo "Usage: $(basename $0) {master|backup|fault}"
exit 1
;;
esac
[root@keepaliveA ~]# vim /etc/keepalived/keepalived.conf
global_defs {
notification_email {
jevon@danran.com
}
notification_email_from ka_admin@danran.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id keepaliveA
vrrp_mcast_group4 224.103.5.5
}
vrrp_script chk_mant_down { \\定義檢測腳本
script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0" \\檢測/etc/keepalived/down文件是否存在衩茸,若文件存在,則weight權(quán)重-10贮泞,若文件不存在楞慈,則每隔一秒檢測
interval 1 \\每隔一秒檢測
weight -10
fall 2 \\檢測兩次故障則表示節(jié)點故障
rise 1 \\檢測一次正常則表示節(jié)點正常
}
vrrp_script chk_nginx { \\檢測nginx服務(wù)是否運行腳本
script "killall -0 nginx" \\-0為探測信號,當(dāng)nginx進程存在時隙畜,返回值$?=0,當(dāng)nginx進程不存在時抖部,返回值$?為非零,則權(quán)重減10
interval 2
weight -10
fall 2
rise 2
}
vrrp_instance VI_A {
state BACKUP
interface ens33
virtual_router_id 51
priority 95
advert_int 1
authentication {
auth_type PASS
auth_pass qr8hQHuL
}
virtual_ipaddress {
172.16.253.150/32
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}
track_script { \\腳本調(diào)用
chk_mant_down
chk_nginx \\調(diào)用chk_nginx腳本
}
}
[root@keepalive-A ~]# systemctl start keepalived
[root@keepalive-A ~]# systemctl status keepalived
keepalive-B
[root@keepalive-B ~]# yum -y install keepalived
[root@keepalive-A ~]# vim /etc/keepalived/notify.sh \\定義狀態(tài)檢測通知腳本
#!/bin/bash
#
contact='root@localhost' \\通知的聯(lián)系者议惰,即本地郵件服務(wù)器的通知郵件接受者
notify() {
local mailsubject="$(hostname) to be $1, vip floating" \\指定郵件標(biāo)題
local mailbody="$(date +'%F %T'): vrrp transition, $(hostname) changed to be $1" \\指定郵件正文
echo "$mailbody" | mail -s "$mailsubject" $contact \\發(fā)送通知信息郵件到郵件接收者
}
case $1 in
master)
notify master
;;
backup)
notify backup
systemctl start nginx
;;
fault)
notify fault
;;
*)
echo "Usage: $(basename $0) {master|backup|fault}"
exit 1
;;
esac
[root@keepalive-B ~]# vim /etc/keepalived/keepalived.conf
global_defs {
notification_email {
jevon@danran.com
}
notification_email_from ka_admin@danran.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id keepaliveA
vrrp_mcast_group4 224.103.5.5
}
vrrp_script chk_mant_down { \\定義檢測腳本
script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0" \\檢測/etc/keepalived/down文件是否存在慎颗,若文件存在,則weight權(quán)重-10言询,若文件不存在俯萎,則每隔一秒檢測
interval 1 \\每隔一秒檢測
weight -10
fall 2 \\檢測兩次故障則表示節(jié)點故障
rise 1 \\檢測一次正常則表示節(jié)點正常
}
vrrp_script chk_nginx { \\檢測nginx服務(wù)是否運行腳本
script "killall -0 nginx" \\-0為探測信號,當(dāng)nginx進程存在時运杭,返回值$?=0,當(dāng)nginx進程不存在時夫啊,返回值$?為非零,則權(quán)重減10
interval 2
weight -10
fall 2
rise 2
}
vrrp_instance VI_A {
state BACKUP
interface ens33
virtual_router_id 51
priority 95
advert_int 1
authentication {
auth_type PASS
auth_pass qr8hQHuL
}
virtual_ipaddress {
172.16.253.150/32
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}
track_script { \\腳本調(diào)用
chk_mant_down
chk_nginx \\調(diào)用chk_nginx腳本
}
}
[root@keepalive-B ~]# systemctl start keepalived
[root@keepalive-A ~]# systemctl start keepalived
測試
訪問測試調(diào)度
[root@client ~]# for i in {1..10};do curl http://172.16.253.150;done
<h1> Web RS1 </h1>
<h1> Web RS2 </h1>
<h1> Web RS1 </h1>
<h1> Web RS2 </h1>
<h1> Web RS1 </h1>
測試檢測監(jiān)控Nginx服務(wù)資源的外部腳本
[root@keepalive-A ~]# ip a l
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:75:dc:3c brd ff:ff:ff:ff:ff:ff
inet 172.16.253.150/32 scope global ens33
valid_lft forever preferred_lft forever
手動停止Nginx服務(wù)辆憔,keepalive-A變成了BACKUP節(jié)點
[root@keepalive-A ~]# systemctl stop nginx
[root@keepalive-A ~]# ip a l
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:75:dc:3c brd ff:ff:ff:ff:ff:ff
幾秒種后撇眯,Nginx服務(wù)再次自動啟動报嵌,則Keepalive-A再次成為MASTER節(jié)點
[root@keepalive-A ~]# ip a l
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:75:dc:3c brd ff:ff:ff:ff:ff:ff
inet 172.16.253.150/32 scope global ens33
valid_lft forever preferred_lft forever
當(dāng)Nginx的80端口占用時,Nginx服務(wù)停止之后不會再次啟動熊榛,則keepalive-A變?yōu)锽ACKUP
[root@keepalive-A ~]# yum -y install httpd
[root@keepalive-A ~]# systemctl stop nginx && systemctl start httpd \\停止nginx的同時啟動httpd
[root@keepalive-A ~]# ip a l
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:75:dc:3c brd ff:ff:ff:ff:ff:ff
[root@keepalive-A ~]# systemctl status keepalived.service
Sep 05 21:21:14 cxjing.com Keepalived_vrrp[24153]: VRRP_Script(chk_nginx) failed
在HTTP進程停止之后锚国,80端口被釋放,則keepalive-A上的Nginx也不會再次重啟
雙主模式的Nginx調(diào)度(一般不會做會話綁定)
雙主模式的目的是為了解決訪問路徑的單點故障玄坦,當(dāng)一個web虛擬路由故障時血筑,可使用另外一個web路徑訪問,最終是實現(xiàn)集群的高可用性
實驗環(huán)境
keepalive-A 172.16.253.108
keepalive-B 172.16.253.105
Nginx-A 172.16.253.108
Nginx-B 172.16.253.105
LVS-RS1 172.16.250.127
LVS-RS2 172.16.253.193
VI-A 172.16.253.150
VI-B 172.16.253.140
client 172.16.253.177
環(huán)境拓撲圖
實現(xiàn)過程
keepalive-A
[root@keepalive-A ~]# vim /etc/keepalived/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
systemctl start nginx
;;
fault)
notify fault
;;
*)
echo "Usage: $(basename $0) {master|backup|fault}"
exit 1
;;
esac
[root@keepalive-A ~]# systemctl stop keepalived
[root@keepalive-A ~]# vim /etc/keepalived/keepalived.conf
global_defs {
notification_email {
jevon@danran.com
}
notification_email_from ka_admin@danran.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id keepaliveA
vrrp_mcast_group4 224.103.5.5
}
vrrp_script chk_mant_down {
script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0"
interval 1
weight -10
fall 2
rise 1
}
vrrp_script chk_nginx {
script "killall -0 nginx"
interval 2
weight -10
fall 2
rise 2
}
vrrp_instance VI_A {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass qr8hQHuL
}
virtual_ipaddress {
172.16.253.150/32
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}
track_script {
chk_mant_down
chk_nginx
}
}
vrrp_instance VI_B {
state BACKUP
interface ens33
virtual_router_id 52
priority 95
advert_int 1
authentication {
auth_type PASS
auth_pass qr8hQH99
}
virtual_ipaddress {
172.16.253.140/32
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}
track_script {
chk_mant_down
chk_nginx
}
}
[root@keepalive-A ~]# systemctl start keepalived
keepalive-B
[root@keepalive-A ~]# vim /etc/keepalived/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
systemctl start nginx
;;
fault)
notify fault
;;
*)
echo "Usage: $(basename $0) {master|backup|fault}"
exit 1
;;
esac
[root@keepalive-B ~]# systemctl stop keepalived
[root@keepalive-B ~]# vim /etc/keepalived/keepalived.conf
global_defs {
notification_email {
jevon@danran.com
}
notification_email_from ka_admin@danran.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id keepaliveA
vrrp_mcast_group4 224.103.5.5
}
vrrp_script chk_mant_down {
script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0"
interval 1
weight -10
fall 2
rise 1
}
vrrp_script chk_nginx {
script "killall -0 nginx"
interval 2
weight -10
fall 2
rise 2
}
vrrp_instance VI_A {
state BACKUP
interface ens33
virtual_router_id 51
priority 95
advert_int 1
authentication {
auth_type PASS
auth_pass qr8hQHuL
}
virtual_ipaddress {
172.16.253.150/32
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}
track_script {
chk_mant_down
chk_nginx
}
}
vrrp_instance VI_B {
state MASTER
interface ens33
virtual_router_id 52
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass qr8hQH99
}
virtual_ipaddress {
172.16.253.140/32
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}
track_script {
chk_mant_down
chk_nginx
}
}
[root@keepalive-B ~]# systemctl start keepalived
查看keepalive-A和keepalive-B IP地址煎楣,確認(rèn)虛擬路由配置正確
[root@keepalive-A ~]# ip a l
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:75:dc:3c brd ff:ff:ff:ff:ff:ff
inet 172.16.253.150/32 scope global ens33
valid_lft forever preferred_lft forever
[root@keepalive-B ~]# ip a l
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:0e:47:87 brd ff:ff:ff:ff:ff:ff
inet 172.16.253.140/32 scope global ens33
valid_lft forever preferred_lft forever
測試Nginx調(diào)度
[root@client ~]# for i in {1..10};do curl http://172.16.253.150;done
<h1> Web RS1 </h1>
<h1> Web RS2 </h1>
<h1> Web RS1 </h1>
<h1> Web RS2 </h1>
<h1> Web RS1 </h1>
[root@client ~]# for i in {1..10};do curl http://172.16.253.140;done
<h1> Web RS1 </h1>
<h1> Web RS2 </h1>
<h1> Web RS1 </h1>
<h1> Web RS2 </h1>
<h1> Web RS1 </h1>
<h1> Web RS2 </h1>
<h1> Web RS1 </h1>