一、实验环境
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.178linux.com/57048