您现在的位置:爱折腾>> Linux>>正文内容

利用Nginx+Keepalived实现web负载均衡

1 规划和准备

  • 需要统一接入的应用系统
 
应用系统 域名/虚拟目录 应用服务器及URL
svn dev.mycompany.com/svn http://50.1.1.21/svn
svn web管理 dev.mycompany.com/submin http://50.1.1.21/submin
网站 www.mycompany.com http://50.1.1.10http://50.1.1.11http://50.1.1.12
OA oa.mycompany.com http://50.1.1.13:8080http://50.1.1.14:8080
  • 接入服务器
 
用途 IP
MASTER 50.1.1.3
BACKUP 50.1.1.4

操作系统: RHEL5.6×64,配置了yum 私服

两台接入服务器公用一个虚拟IP(VIP):50.1.1.2

2 安装

两台接入服务器分别安装NginX和keepalived:

  • 准备依赖包:
  1. yum -y install gcc pcre-devel zlib-devel openssl-devel 
  • 下载
  1. wget http://nginx.org/download/nginx-1.2.4.tar.gz   
  2. wget http://www.keepalived.org/software/keepalived-1.2.7.tar.gz 
  • 安装NginX
  1. tar zxvf nginx-1.2.4.tar.gz  
  2.  
  3. cd nginx-1.2.4  
  4.  
  5. ./configure --with-http_stub_status_module  
  6.  
  7. make && make install 

 

  • 安装keepalived
  1. tar zxvf keepalived-1.2.7.tar.gz  
  2. cd keepalived-1.2.7  
  3. ./configure  
  4. make   
  5. make install  
  6.  
  7. cp /usr/local/etc/rc.d/init.d/keepalived /etc/rc.d/init.d/  
  8. cp /usr/local/etc/sysconfig/keepalived /etc/sysconfig/  
  9. mkdir /etc/keepalived  
  10. cp /usr/local/etc/keepalived/keepalived.conf /etc/keepalived/  
  11. cp /usr/local/sbin/keepalived /usr/sbin/ 

 

  • 加入启动服务

  1. echo "/usr/local/nginx/sbin/nginx" >> /etc/rc.localecho "/etc/init.d/keepalived start" >> /etc/rc.local 

 

3 配置

3.1 配置NginX

两台接入服务器的NginX的配置完全一样,主要是配置/usr/local/nginx/conf/nginx.conf的http。其中多域名指向是通过虚拟主机(配置http下面的server)实现;同一域名的不同虚拟目录通过每个server下面的不同location实现;到后端的服务器在http下面配置upstream,然后在server或location中通过proxypass引用。要实现前面规划的接入方式,http的配置如下:

  1. http {  
  2.     include       mime.types;  
  3.     default_type  application/octet-stream;  
  4.  
  5.     sendfile        on;  
  6.  
  7.     upstream dev.hysec.com {  
  8.         server 50.1.1.21:80;  
  9.     }  
  10.  
  11.     upstream www.hysec.com {  
  12.       ip_hash;  
  13.       server 50.1.1.10:80;  
  14.       server 50.1.1.11:80;  
  15.       server 50.1.1.12:80;  
  16.     }  
  17.  
  18.     upstream oa.hysec.com {  
  19.       ip_hash;  
  20.       server 50.1.1.13:8080;  
  21.       server 50.1.1.14:8080;  
  22.  
  23.     server {  
  24.         listen      80;  
  25.         server_name dev.hysec.com;  
  26.         location /svn {  
  27.             proxy_pass http://dev.hysec.com;  
  28.         }  
  29.  
  30.         location /submin {  
  31.             proxy_pass http://dev.hysec.com;  
  32.         }  
  33.     }  
  34.  
  35.     server {  
  36.         listen       80;  
  37.         server_name  www.hysec.com;  
  38.         location / {  
  39.             proxy_pass http://www.hysec.com;  
  40.         }  
  41.     server {  
  42.         listen       80;  
  43.         server_name  oa.hysec.com;  
  44.         location / {  
  45.             proxy_pass http://oa.hysec.com;  
  46.         }  

 

验证方法:

  • 首先用IP访问前表中各个应用服务器的url
  • 再用域名和路径访问前表中各个应用系统的域名/虚拟路径

3.2 配置keepalived

按照上面的安装方法,keepalived的配置文件在/etc/keepalived/keepalived.conf。主、从服务器的配置相关联但有所不同。如下:

Master:

  1. ! Configuration File for keepalived  
  2.  
  3. global_defs {  
  4. notification_email {  
  5.         wanghaikuo@hysec.com  
  6.         wanghaikuo@gmail.com  
  7.    }  
  8.  
  9.    notification_email_from wanghaikuo@hysec.com  
  10.    smtp_server smtp.hysec.com  
  11.    smtp_connect_timeout 30  
  12.    router_id nginx_master  
  13.  
  14. }  
  15.  
  16. vrrp_instance VI_1 {  
  17.     state MASTER  
  18.     interface eth0  
  19.     virtual_router_id 51  
  20.     priority 101  
  21.     advert_int 1  
  22.     authentication {  
  23.         auth_type PASS  
  24.         auth_pass 1111  
  25.     }  
  26.     virtual_ipaddress {  
  27.         50.1.1.2  
  28.     }  

 

Backup:

  1. ! Configuration File for keepalived  
  2.  
  3. global_defs {  
  4. notification_email {  
  5.         wanghaikuo@hysec.com  
  6.         wanghaikuo@gmail.com  
  7.    }  
  8.  
  9.    notification_email_from wanghaikuo@hysec.com  
  10.    smtp_server smtp.hysec.com  
  11.    smtp_connect_timeout 30  
  12.    router_id nginx_backup  
  13.  
  14. }  
  15.  
  16. vrrp_instance VI_1 {  
  17.     state BACKUP  
  18.     interface eth0  
  19.     virtual_router_id 51  
  20.     priority 99  
  21.     advert_int 1  
  22.     authentication {  
  23.         auth_type PASS  
  24.         auth_pass 1111  
  25.     }  
  26.     virtual_ipaddress {  
  27.         50.1.1.2  
  28.     }  

 

验证:

  • 先后在主、从服务器上启动keepalived: /etc/init.d/keepalived start
  • 在主服务器上查看是否已经绑定了虚拟IP: ip addr
  • 停止主服务器上的keepalived: /etc/init.d/keepalived stop 然后在从服务器上查看是否已经绑定了虚拟IP:
  • 启动主服务器上的keepalived,看看主服务器能否重新接管虚拟IP

3.3 让keepalived监控NginX的状态

经过前面的配置,如果主服务器的keepalived停止服务,从服务器会自动接管VIP对外服务;一旦主服务器的keepalived恢复,会重新接管VIP。 但这并不是我们需要的,我们需要的是当NginX停止服务的时候能够自动切换。

keepalived支持配置监控脚本,我们可以通过脚本监控NginX的状态,如果状态不正常则进行一系列的操作,最终仍不能恢复NginX则杀掉keepalived,使得从服务器能够接管服务。

  • 如何监控NginX的状态

最简单的做法是监控NginX进程,更靠谱的做法是检查NginX端口,最靠谱的做法是检查多个url能否获取到页面。

  • 如何尝试恢复服务

如果发现NginX不正常,重启之。等待3秒再次校验,仍然失败则不再尝试。

根据上述策略很容易写出监控脚本。这里使用nmap检查nginx端口来判断nginx的状态,记得要首先安装nmap。监控脚本如下: 

  1. #!/bin/sh  
  2. # check nginx server status  
  3. NGINX=/usr/local/nginx/sbin/nginx  
  4. PORT=80  
  5.  
  6. nmap localhost -p $PORT | grep "$PORT/tcp open"  
  7. #echo $?  
  8. if [ $? -ne 0 ];then  
  9.     $NGINX -s stop  
  10.     $NGINX  
  11.     sleep 3  
  12.     nmap localhost -p $PORT | grep "$PORT/tcp open"  
  13.     [ $? -ne 0 ] && /etc/init.d/keepalived stop  
  14. fi 

  

不要忘了设置脚本的执行权限,否则不起作用。

假设上述脚本放在/opt/chk_nginx.sh,则keepalived.conf中增加如下配置: 

  1. vrrp_script chk_http_port {  
  2.     script "/opt/chk_nginx.sh"  
  3.     interval 2  
  4.     weight 2  
  5. }  
  6.  
  7. track_script {  
  8.     chk_http_port  

 

更进一步,为了避免启动keepalived之前没有启动nginx , 可以在/etc/init.d/keepalived的start中首先启动nginx: 

  1. start() {  
  2.     /usr/local/nginx/sbin/nginx  
  3.     sleep 3  
  4.     echo -n $"Starting $prog: "  
  5.     daemon keepalived ${KEEPALIVED_OPTIONS}  
  6.     RETVAL=$?  
  7.     echo  
  8.     [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog  

  

4 还可以做什么

对于简单重复性劳动,人总是容易犯错,这种事情最好交给机器去做。 比如,在这个案例中,作为统一接入服务器,可能经常要修改nginx的配置、nginx下面的html文件等。而且,一定要保证集群中的每台服务器的配置相同。 最好的做法是由配置管理服务器来管理,如果没有,也可以使用简单的linux文件同步来解决。

5 SSL配置

在nginx/conf下生成秘钥: 

  1. #生成RSA密钥  
  2. openssl dsaparam -rand -genkey -out myRSA.key 1024  
  3.  
  4. #生成CA密钥:(要输入一个自己记得的密码)  
  5. openssl gendsa -des3 -out cert.key myRSA.key  
  6.  
  7. #用这个CA密钥来创建证书,需要上一步创建的密码  
  8. openssl req -new -x509 -days 365 -key cert.key -out cert.pem  
  9.  
  10. #把证书设置为root专用  
  11. chmod 700 cert.*  
  12.  
  13. #生成免密码文件openssl rsa -in cert.key -out cert.key.unsecure 

 

如果要启用SSL,在nginx中进行如下配置: 

  1. # 这里是SSL的相关配置  
  2. server {  
  3.   listen 443;  
  4.   server_name www.example.com; # 你自己的域名  
  5.   root /home/www;  
  6.   ssl on;  
  7.   ssl_certificate cert.perm;  
  8.   #使用.unsecure文件可以在nginx启动时不输入密码    
  9.   ssl_certificate_key cert.key.unsecure;  
  10.   location / {  
  11.   #...  
  12.   }  

相关文章