一、环境规划
操作系统:CentOS6.5 x86_64
内核版本:2.6.32-504.el6.x86_64
Nginx版本:nginx-1.8.0-1.el6.ngx.x86_64
Keepalived版本:keepalived-1.2.19
前端双Nginx+Keepalived,Nginx反向代理到后端tomcat集群实现负载均衡,Keepalived实现集群高可用,主nginx故障后虚拟IP自动漂移到备nginx。
主nginx:192.168.60.48
备nginx:192.168.60.49
虚拟IP:192.168.60.50
后端tomcat集群:192.168.60.51、192.168.60.52、192.168.60.53
后端每个主机都开启两个端口提供业务:16915、16916
二、安装
前端两台主机分别安装nginx和keepalived。
1)编译安装keepalived
# 安装依赖 yum install kernel-* gcc make openssl-* # 下载keepalived-1.2.19.tar.gz wget http://www.keepalived.org/software/keepalived-1.2.19.tar.gz # 解压 tar xvzf keepalived-1.2.19.tar.gz cd keepalived-1.2.19 # 配置 ./configure --sysconfdir=/etc --with-kernel-dir=/usr/src/kernels/2.6.32-504.el6.x86_64 # 编译并安装 make && make install # 查看keepalived版本,验证安装成功 keepalived -v # 设置开机自启动 chkconfig keepalived on
注:用yum也可安装keepalived,不过版本要低一些。
2)RPM包安装Nginx
官方nginx yum源:
[nginx] name=nginx repo baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ enabled=1 gpgcheck=0
yum源设置好后直接安装即可:
yum install nginx chkconfig nginx on
三、配置
1)前端两台主机nginx的配置完全一样
# vim /etc/nginx/conf.d/upstream.conf upstream tomcatclu_16915 { server 192.168.60.51:16915; server 192.168.60.52:16915; server 192.168.60.53:16915; ip_hash; } upstream tomcatclu_16916 { server 192.168.60.51:16916; server 192.168.60.52:16916; server 192.168.60.53:16916; ip_hash; } # vim /etc/nginx/conf.d/server.conf server { listen 16915; server_name _; location / { proxy_pass http://tomcatclu_16915; } location /nginx_status{ stub_status on; access_log off; allow 127.0.0.1; # 要允许公司ip访问nginx status allow 192.168.252.0/24; deny all; } } server { listen 16916; server_name _; location / { proxy_pass http://tomcatclu_16916; } location /nginx_status{ stub_status on; access_log off; allow 127.0.0.1; # 要允许公司ip访问nginx status allow 192.168.252.0/24; deny all; } }
2)nginx_master的keepalived配置
[root@nginx_master ~]# vim /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { router_id nginx-ha1 } vrrp_script check_nginx { # 检查nginx状态的脚本,文章后面给出 script "/data/script/check_nginx.sh" # 执行间隔2秒 interval 2 } vrrp_instance VI_1 { # 两台主机都是BACKUP state BACKUP interface eth0 # 同一keepalived集群的virtual_router_id 必须相同,默认51 virtual_router_id 55 # 主的优先级高 priority 100 advert_int 1 # 不抢占:如果集群里已存在MASTER状态的主机,即使优先级高于MASTER也不抢占为MASTER。只在优先级高的主机上设置即可。 nopreempt authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { # 虚拟IP 192.168.60.50 } track_script { check_nginx } }
3)nginx_slave的keepalived配置
[root@nginx_slave ~]# vim /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { router_id nginx-ha2 } vrrp_script check_nginx { script "/data/script/check_nginx.sh" interval 2 } vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 55 # 备的优先级低 priority 80 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.60.50 } track_script { check_nginx } }
4)防火墙设置
# iptables放行组播地址流量: iptables -I INPUT -d 224.0.0.18 -j ACCEPT service iptables save
VRRP报文是通过IP多播形式发送的,组播地址224.0.0.18是VRRP报文的目的地址。
本实验里,两个主机都是BACKUP,如果同时启动keepalived,VRRP协议通过竞选使优先级高的主机做为MASTER。如果防火墙没有允许VRRP报文通过的话,两个BACKUP都会成为MASTER,你会发现两个主机都启动了虚拟IP。
5)部署nginx状态检查脚本check_nginx.sh
/data/script/check_nginx.sh检查脚本内容如下:
#!/bin/bash # check nginx server status # http://qicheng0211.blog.51cto.com # nginx端口 PORTS="16915 16916" function check_ports { for port in $PORTS;do nc -z 127.0.0.1 $port | grep -q succeeded [ "${PIPESTATUS[1]}" -eq 0 ] && mark=${mark}1 done # 如果mark值为空说明两个端口都不通。 # 如果mark等于1,说明有一个端口是通的。 # 如果mark等于11,说明两个端口都是通的。 echo $mark } ret1=$(check_ports) # 如果nginx端口不通,会尝试重启一次nginx if [ "$ret1" != 11 ];then /sbin/service nginx stop /sbin/service nginx start sleep 1 ret2=$(check_ports) # 如果还是有端口不通,表示nginx服务不正常,则停掉keepalived,使VIP发生切换 [ "$ret2" != 11 ] && /etc/init.d/keepalived stop fi
大家根据自个的环境编写nginx状态检查脚本,不一定要照搬。
给脚本设置可执行权限:
chmod +x /data/script/check_nginx.sh
补充一点:如果nginx恢复正常后,keepalived不能自动启动,需要编写一个脚本完成这项工作:判断nginx正常后,拉起keepalived。脚本放到cron里每分钟执行。
6)开启keepalived的日志
编辑/etc/sysconfig/keepalived:
KEEPALIVED_OPTIONS="-D -d -S 0"
编辑/etc/rsyslog.conf:
# 配置文件最后面加上下面一行 local0.* /var/log/keepalived.log
重启rsyslog:
service rsyslog restart
按上面配置后,keepalived会把日志记录到/var/log/keepalived.log。
7)启动服务
# 先检查nginx配置文件正确性 nginx -t # 启动nginx服务 service nginx start # 同时启动keepalived服务 service keepalived start # 过一会查看虚拟IP是否在nginx_master主机上 ip a
四、验证
nginx_master和nginx_slave同时启动keepalived,观察日志/var/log/keepalived.log,你会发现nginx_master抢占为MASTER,绑定了虚拟IP192.168.60.50。
nginx_master:
nginx_slave:
我们在同网段的其他机器上去arping一下虚拟IP的MAC,发现是nginx_master eth0的mac:
下面我们把nginx_master的keepalived服务停掉或者重启系统,同时不断的ping虚拟IP。经过一个请求超时的间隔,虚拟IP会漂移到nginx_slave上面:
nginx_slave:
我们再去arping一下虚拟IP的MAC,发现变成了nginx_slave eth0的mac:
查看nginx_slave的日志keepalived.log,nginx_slave在成为MASTER的同时发送了免费ARP(gratuitous ARP),更新了以太网邻居的ARP快速缓存:
VRRP_Instance(VI_1) Entering MASTER STATE VRRP_Instance(VI_1) setting protocol VIPs. VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 192.168.60.50
最后把nginx_master的keepalived服务开启,虚拟IP并没有漂移回到nginx_master,这是因为nginx_master开启了不抢占模式,即使优先级高,也不会抢占MASTER。