一、實驗環境
http server1與http server2組成web集群,由nginx服務器實現負載均衡代理,使用keepalived保證nginx服務的高可用。通過虛擬IP192.168.154.177對外提供web服務。
實驗目的:
1)當Nginx server1上的nginx服務異常時,由nginx server2提供反帶服務。
2)當Nginx server1上的nginx服務異常時,重啟Nginx server1上的nginx服務,啟動成功之后,仍由Nginx server1提供代理服務。
二、分別在nginx server1、nginx server2上安裝nginx
1)獲取nginx安裝包
2)解決依賴關系
yum install -y pcre-devel openssl-devel zlib-devel
3)解壓安裝包
tar xf nginx-1.10.0.tar.gz
4)編譯安裝
./configure –prefix=/usr/local/nginx –conf-path=/etc/nginx/nginx.conf –user=nginx –group=nginx
make && make install
5)配置環境變量,方便使用nginx命令
echo "PATH=/usr/local/nginx/sbin/:$PATH" > /etc/profile.d/nginx.sh
source /etc/profile.d/nginx.sh
使用nginx -V查看nginx版本是否為手動安裝的版本。
6)配置nginx服務系統服務。此操作須在nginx server1、server2上都完成,以方便keepalived通過服務管理命令來管理nginx服務。
編輯/etc/nginx/nginxconf文件,配置pid如下
pid /usr/local/nginx/logs/nginx.pid;
編輯/etc/init.d/nginx
#!/bin/sh
#
# nginx – this script starts and stops the nginx daemon
#
# chkconfig: – 85 15
# description: Nginx is an HTTP(S) server, HTTP(S) reverse \
# proxy and IMAP/POP3 proxy server
# processname: nginx
# config: /etc/nginx/nginx.conf
# config: /etc/sysconfig/nginx
# pidfile: /var/run/nginx.pid
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
nginx="/usr/local/nginx/sbin/nginx"
prog=$(basename $nginx)
sysconfig="/etc/sysconfig/$prog"
lockfile="/var/lock/subsys/nginx"
pidfile="/usr/local/nginx/logs/nginx.pid" #pid改為與nginx.conf一致
NGINX_CONF_FILE="/etc/nginx/nginx.conf"
[ -f $sysconfig ] && . $sysconfig
start() {
[ -x $nginx ] || exit 5
[ -f $NGINX_CONF_FILE ] || exit 6
echo -n $"Starting $prog: "
daemon $nginx -c $NGINX_CONF_FILE
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
echo -n $"Stopping $prog: "
killproc -p $pidfile $prog
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
restart() {
configtest_q || return 6
stop
start
}
reload() {
configtest_q || return 6
echo -n $"Reloading $prog: "
killproc -p $pidfile $prog -HUP
echo
}
configtest() {
$nginx -t -c $NGINX_CONF_FILE
}
configtest_q() {
$nginx -t -q -c $NGINX_CONF_FILE
}
rh_status() {
status $prog
}
rh_status_q() {
rh_status >/dev/null 2>&1
}
# Upgrade the binary with no downtime.
upgrade() {
local oldbin_pidfile="${pidfile}.oldbin"
configtest_q || return 6
echo -n $"Upgrading $prog: "
killproc -p $pidfile $prog -USR2
retval=$?
sleep 1
if [[ -f ${oldbin_pidfile} && -f ${pidfile} ]]; then
killproc -p $oldbin_pidfile $prog -QUIT
success $"$prog online upgrade"
echo
return 0
else
failure $"$prog online upgrade"
echo
return 1
fi
}
# Tell nginx to reopen logs
reopen_logs() {
configtest_q || return 6
echo -n $"Reopening $prog logs: "
killproc -p $pidfile $prog -USR1
retval=$?
echo
return $retval
}
case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart|configtest|reopen_logs)
$1
;;
force-reload|upgrade)
rh_status_q || exit 7
upgrade
;;
reload)
rh_status_q || exit 7
$1
;;
status|status_q)
rh_$1
;;
condrestart|try-restart)
rh_status_q || exit 7
restart
;;
*)
echo $"Usage: $0 {start|stop|reload|configtest|status|force-reload|upgrade|restart|reopen_logs}"
exit 2
esac
7)之后使用chkconfig –add nginx將nginx加為系統服務,之后即可通過service來管理nginx服務。
三、配置nginx
安裝成功之后,在MASTER上編輯nginx配置文件
vim /etc/nginx/nginx.conf
在http上下文中添加下面的配置
upstream webcluster {
server 192.168.154.129;
server 192.168.154.130;
}
在需要反帶的server中的location上下文中配置
location / {
proxy_pass http://webcluster;
index index.html index.htm;
}
如下圖所示:
之后,測試配置文件是否有誤,無誤則啟動nginx,并將配置文件拷貝至BACKUP節點中。
啟動BACKUP節點上的nginx服務。
四、安裝并配置keepalived
在CentOS6.4之后的版本,keepalived被收錄進base源中,以前的版本被收錄進epel源中,配置好yum源,使用yum安裝即可。
安裝好keepalived之后,在MASTER服務器中編輯keepalived配置文件
1、實現當Nginx server1上的nginx服務異常時,由nginx server2提供反帶服務。
vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
root@localhost
}
notification_email_from keepalived@localhost
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id 121
vrrp_mcast_group4 224.0.54.154
}
vrrp_instance nginxcluster {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 797fea91
}
virtual_ipaddress {
192.168.154.177/24 dev eth1
}
}
將配置文件拷貝至BACKUP節點中。修改state–>BACKUP;priority–>95(低于MASTER的priority 100即可)之后,啟動MASTER和BACKUP上的keepalived服務。 此時,當MASTER上的nginx服務異常時,MASTER并不會切換,此時web服務無法正常對外提供。要解決此問題,應該檢測nginx服務的狀態,當MASTER上的nginx服務異常時,MASTER轉換為BACKUP,繼續對外提供web服務。
keepalived要實現對服務的監控,需要用到其腳本功能。
keepalived調用外部輔助腳本,完成資源監控,并根據監控的結果狀態來實現優先級動態調整;
vrrp_script:定義一個資源監控腳本;
vrrp_script <STRING> {
script "" #自己寫的檢測腳本。也可以是一行命令如killall -0 nginx
interval INT #定義檢測周期,單位為秒,即每隔幾秒檢測一次
weight -INT #檢測失敗之后,當前keepalived的優先級會減去定義的整數
fall INT #連續檢測幾次失敗才算確定的失敗。會用weight減少優先級
rise 1 #檢測1次成功就算成功,但不修改優先級
}
track_script:調用定義的資源監控腳本;可以監控多個
track_script {
SCRIPT_NAME
}
在上例中的配置文件的基礎上做修改,新增下文中突出的配置。
vrrp_script chk_nginx {
script "pidof nginx > /dev/null && exit 0 || exit 1"
interval 1
weight -10
fall 3
rise 1
}
vrrp_instance nginxcluster {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 797fea91
}
virtual_ipaddress {
192.168.154.177/24 dev eth1
}
track_script {
chk_nginx
}
}
測試:使用killall nginx殺掉MASTER上的nginx進程,此時keepalived服務仍在運行。
查看keepalived日志
tailf -n 0 /var/log/messages
Nov 1 22:19:37 node1 Keepalived_vrrp[9378]: VRRP_Script(chk_nginx) failed
Nov 1 22:19:39 node1 Keepalived_vrrp[9378]: VRRP_Instance(nginxcluster) Received higher prio advert
Nov 1 22:19:39 node1 Keepalived_vrrp[9378]: VRRP_Instance(nginxcluster) Entering BACKUP STATE
Nov 1 22:19:39 node1 Keepalived_vrrp[9378]: VRRP_Instance(nginxcluster) removing protocol VIPs.
Nov 1 22:19:39 node1 Keepalived_healthcheckers[9377]: Netlink reflector reports IP 192.168.154.177 removed
由日志可以發現,keepalived觸發了chk_nginx腳本,并且檢測失敗,之后,weight -10,由100-10=90,低于BACKUP上的優先級,故其提示接收到更高的優先級組播,轉換為BACKUP狀態,并且移除VIP。
此時,并不影響web服務的正常向外提供。實現了當Nginx server1上的nginx服務異常時,由nginx server2提供反帶服務。
2、下面,來實現當Nginx server1上的nginx服務異常時,重啟Nginx server1上的nginx服務,啟動成功之后,仍由Nginx server1提供代理服務。
此功能需要借助于notify_master、notify_backup、notify_fault配置來實現,當MASTER轉換為BACKUP節點時,觸發一個重啟nginx服務的腳本,由于keepalived默認工作在搶占模式下,其會發送組播向其他通告自己的優先級,并進行比對,當發現自己的優先級較高時,發起新一輪的選舉,由于其優先級較高,其會稱為MASTER。
在MASTER轉換為BACKUP,在轉換為MASTER的之一過程中
notify_master <STRING>|<QUOTED-STRING> #當前節點為主節點時觸發的腳本
notify_backup <STRING>|<QUOTED-STRING> #當前節點為備節點時觸發的腳本
notify_fault <STRING>|<QUOTED-STRING>#當前節點轉為失敗狀態時觸發的腳本
1)在/etc/keepalived/目錄下編輯chk_nginx_on.sh腳本:當節點角色發生切換時,以郵件的形式通知root用戶,并重啟nginx服務。
#!/bin/bash
#
contact='root@localhost'
notify() {
mailsubject="$(hostname) to be nginxcluster $1, vip floating."
mailbody="$(date +'%F %T'): vrrp transition, $(hostname) changed to be nginxcluster $1"
echo "$mailbody" | mail -s "$mailsubject" $contact
}
case $1 in
master)
notify master
service nginx restart
;;
backup)
notify backup
service nginx restart
;;
fault)
notify fault
;;
*)
echo "Usage: $(basename $0) {master|backup|fault}"
exit 1
;;
esac
2)編輯/etc/keepalived/keepalived.conf
在相應的instance配置段中添加以下內容:
notify_master "/etc/keepalived/chk_nginx_on.sh master"
notify_backup "/etc/keepalived/chk_nginx_on.sh backup"
notify_fault "/etc/keepalived/chk_nginx_on.sh fault"
之后,重載配置:service keepalived reeload
3)測試,停掉MASTER上的nginx服務,觀察keepalived日志。
發現,當nginx服務停止之后,keepalived觸發了chk_nginx腳本,并且檢測失敗,轉換為BACKUP狀態,并且移除VIP。轉換為BACKUP之后,觸發chk_nginx_on.sh腳本,重啟nginx服務,之后,其通過chk_nginx腳本檢測成功,故其優先級得以恢復,由于其優先級高于BACKUP,觸發新的選舉,并被選舉為MASTER。
Nov 2 19:22:01 node1 Keepalived_vrrp[8611]: VRRP_Script(chk_nginx) failed
Nov 2 19:22:02 node1 Keepalived_vrrp[8611]: VRRP_Instance(nginxcluster) Received higher prio advert
Nov 2 19:22:02 node1 Keepalived_vrrp[8611]: VRRP_Instance(nginxcluster) Entering BACKUP STATE
Nov 2 19:22:02 node1 Keepalived_vrrp[8611]: VRRP_Instance(nginxcluster) removing protocol VIPs.
Nov 2 19:22:02 node1 Keepalived_healthcheckers[8610]: Netlink reflector reports IP 192.168.154.177 removed
Nov 2 19:22:03 node1 Keepalived_vrrp[8611]: VRRP_Script(chk_nginx) succeeded
Nov 2 19:22:04 node1 Keepalived_vrrp[8611]: VRRP_Instance(nginxcluster) forcing a new MASTER election
Nov 2 19:22:04 node1 Keepalived_vrrp[8611]: VRRP_Instance(nginxcluster) forcing a new MASTER election
Nov 2 19:22:05 node1 Keepalived_vrrp[8611]: VRRP_Instance(nginxcluster) Transition to MASTER STATE
Nov 2 19:22:06 node1 Keepalived_vrrp[8611]: VRRP_Instance(nginxcluster) Entering MASTER STATE
Nov 2 19:22:06 node1 Keepalived_vrrp[8611]: VRRP_Instance(nginxcluster) setting protocol VIPs.
Nov 2 19:22:06 node1 Keepalived_healthcheckers[8610]: Netlink reflector reports IP 192.168.154.177 added
Nov 2 19:22:06 node1 Keepalived_vrrp[8611]: VRRP_Instance(nginxcluster) Sending gratuitous ARPs on eth1 for 192.168.154.177
Nov 2 19:22:11 node1 Keepalived_vrrp[8611]: VRRP_Instance(nginxcluster) Sending gratuitous ARPs on eth1 for 192.168.154.177
4)總結:通過vrrp_scrip機制,可以實現當nginx服務出現故障時,MASTER轉移至備節點,從而保障nginx服務的正常對外提供;而通過notify機制,可以實現當服務異常時重啟nginx服務,并根據keepalived默認工作在搶占模式,搶回MASTER。
原創文章,作者:M20-1鐘明波,如若轉載,請注明出處:http://www.www58058.com/57048