实验目的:

利用keepalived实现高可用反向代理的nginx。以及双主模型的ipvs

实验环境:

node1:在nginx做代理时做反向代理节点,在keepalived实现LVS时做Director。VIP1:172.16.18.22 VIP2:172.16.18.23

node2:在nginx做代理时做反向代理节点,在keepalived实现LVS时做Director。VIP1:172.16.18.22 VIP2:172.16.18.23

node3:在nginx做代理时做web服务器。在keepalived实现时做real server

实验模型:

keepAlived+nginx实现高可用双主模型LVS_第1张图片

实验内容:

keepalived实现高可用nginx的反向代理

1,为实验提供应用程序:

安装nginx,keepalived.本实验我使用的是自己编译安装的nginx最新版本。大家也可以自己编译安装,也可以选择程序包安装。keepalived选择程序包安装!编译安装nginx此处不做说明。大家可以自己去寻找教程。

yum install keepalived

这两个程序需要在两个节点提供安装。

2,首先我们先配置nginx让他提供web服务。

编辑nginx的配置文件/usr/local/nginx/conf/nginx.conf  提供最基本的服务,先让他可以显示出页面来。

user root;
worker_processes 1;
#error_log logs/error.log;
events {
    worker_connections 1024;
}
http {
    include mime.types;
    default_type application/octet-stream;
    sendfile on;
    keepalive_timeout 65;
    gzip on;
    server {
        listen 80;
        server_name node1.aolens.com;
        location / {
            root /data/webapps/www;
            index index.html index.htm;
        }
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
            root /data/webapps/html;
        }
      location ~ \.php$ {
            root /data/webapps/www/;
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
            include fastcgi_params;
        }


下边来为nginx提供一个页面文件。启动nginx

访问页面node1

keepAlived+nginx实现高可用双主模型LVS_第2张图片

下边停止nginx,并且不让它开机启动

service nginx stop

chkconfig nginx off

[root@node1 ~]# chkconfig --list |grep nginx    
nginx 0:off 1:off 2:off 3:off 4:off 5:off 6:off

将配置文件发送到node2上。提供一个访问页面。启动nginx。

keepAlived+nginx实现高可用双主模型LVS_第3张图片

停止nginx,并且不让它开机启动

service nginx stop

[root@node2 ~]# service nginx stop    
Stopping nginx: [ OK ]    
[
root@node2 ~]# chkconfig nginx off    
[
root@node2 ~]# chkconfig --list |grep nginx    
nginx 0:off 1:off 2:off 3:off 4:off 5:off 6:off

好,这里我们的nginx服务就可以正常启动了。

3,下来我们来利用keepalived实现高可用。

前边我们安装好了keepalived编译配置文件/etc/keepalived/keepalived.conf

global_defs {   
notification_email {    
[email protected]     #邮箱    
}    
notification_email_from [email protected] #邮箱地址    
smtp_server 127.0.0.1                                #邮箱发往地址    
smtp_connect_timeout 30                            
}    
vrrp_script chk_nginx{                                #定义检测nginx    
    script "killall -0 nginx"                                #killall -0 nginx  检测nginx是否在线    
    interval 1                                                  #多长 时间检测一次    
    weight -5                                                  #如果不在线,权重-5    
    fall 2                                                         #不在线检测次数    
    raise 1                                                     #上线检测次数    
}    
vrrp_instance VI_1 {                                   #定义一个资源    
    state MASTER                                           #定义为主节点    
    interface eth0                                           #定义网卡    
    virtual_router_id 18                                   #虚拟路由ID    
    priority 100                                              #优先级    
    advert_int 1                                              #广播间隔    
    authentication {    
    auth_type PASS                                         #认证方式    
    auth_pass 1111                                         #认证密码    
}    
track_script{                                             #调用检测  
    chk_nginx
    }
    notify_master "/etc/init.d/nginx start"     #通知脚本,执行指定选项
    notify_backup "/etc/init.d/nginx stop"
    notify_fault "/etc/init.d/nginx stop"
    virtual_ipaddress {                                #虚拟路由地址
        172.16.18.22
    }
}

发送到node2 修改

state BACKUP

priority 99

我们先启动node2上的keepalived,会发现nginx跟随一起启动了,而且日志中显示此为主节点。因为node1节点此时没有上线。

[root@node2 ~]# service keepalived restart    
Starting keepalived: [ OK ]    
[
root@node2 ~]# service nginx status    
nginx (pid 11425 11424) is running...

tail /var/log/message

Sep 15 12:48:32 node2 Keepalived_vrrp[11313]: VRRP_Instance(VI_1) Transition to MASTER STATE

Sep 15 12:48:33 node2 Keepalived_vrrp[11313]: VRRP_Instance(VI_1) Entering MASTER STATE

Sep 15 12:48:33 node2 Keepalived_vrrp[11313]: VRRP_Instance(VI_1) setting protocol VIPs.

Sep 15 12:48:33 node2 Keepalived_healthcheckers[11312]: Netlink reflector reports IP 172.16.18.22 added

Sep 15 12:48:33 node2 Keepalived_vrrp[11313]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 172.16.18.22

Sep 15 12:48:38 node2 Keepalived_vrrp[11313]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 172.16.18.22

此时启动node1 ,会发现node1上的nginx也启动了。访问会发现是node2

keepAlived+nginx实现高可用双主模型LVS_第4张图片

[root@node1 ~]# service keepalived start    
Starting keepalived: [ OK ]    
[
root@node1 ~]# service nginx status    
nginx (pid 16512 16511) is running...

tail /var/log/message

Sep 15 16:00:49 node1 Keepalived_vrrp[16853]: VRRP_Instance(VI_1) Transition to MASTER STATE

Sep 15 16:00:49 node1 Keepalived_vrrp[16853]: VRRP_Instance(VI_1) Received lower prio advert, forcing new election

Sep 15 16:00:50 node1 Keepalived_vrrp[16853]: VRRP_Instance(VI_1) Entering MASTER STATE

Sep 15 16:00:50 node1 Keepalived_vrrp[16853]: VRRP_Instance(VI_1) setting protocol VIPs.

Sep 15 16:00:50 node1 Keepalived_healthcheckers[16852]: Netlink reflector reports IP 172.16.18.22 added

Sep 15 16:00:50 node1 Keepalived_vrrp[16853]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 172.16.18.22

发现主节点到了node1上,此时node2变为了备节点,而且发现node2的nginx已stop

Sep 15 13:47:56 node2 Keepalived_vrrp[11313]: VRRP_Instance(VI_1) Transition to MASTER STATE  
Sep 15 13:47:56 node2 Keepalived_vrrp[11313]: VRRP_Instance(VI_1) Received higher prio advert    
Sep 15 13:47:56 node2 Keepalived_vrrp[11313]: VRRP_Instance(VI_1) Entering BACKUP STATE    
[
root@node2 ~]# service nginx status    
nginx is stopped

访问会发现是node1

keepAlived+nginx实现高可用双主模型LVS_第5张图片

此时就实现了nginx的高可用,但是这种模式有着明显的缺陷,他只能在keepalived出现问题是可以完美切换,但是有没有想过如果是nginx程序出现故障了,那还能不能高可用呢?

假如:node1上的nginx出现问题,权限-5,此时node1上的权限低于node2,主节点会切到node2上,如果node1上的nginx起来,权限是不会+5的,也就是说此时node1上的权限是95,node2上的权限是99.主节点不会切回来,如果node2上的nginx挂了权限-5才会切到node1上来。这样如果主备节点的性能差距较大的话是很不理想的状况。

解决办法在全局段添加

vrrp_script chk_mantaince_down {
   script "[[ -e /etc/keepalived/down ]] && exit 1 || exit 0"
   interval 1
   weight -2
}
修改track_script,添加chk_mantaince_down
track_script {
  chk_haproxy
  chk_mantaince_down
}

这样当你在node1 上的nginx恢复,就可以在node2 节点/etc/keeplived下touch个down,权重就会再+5.也就是100,就会转回来了。

当然也可以利用脚本来监控,下边提供一个脚本仅供参考。

下面是一个notify.sh脚本的简单示例:  

#!/bin/bash    
# Author: MageEdu <
[email protected]
>    
# description: An example of notify script    
vip=172.16.100.1    
contact='
root@localhost
'    
notify() {    
mailsubject="`hostname` to be $1: $vip floating"    
mailbody="`date '+%F %H:%M:%S'`: vrrp transition, `hostname` changed to be $1"    
echo $mailbody | mail -s "$mailsubject" $contact    
}    
case "$1" in    
master)    
notify master    
/etc/rc.d/init.d/haproxy start    
exit 0    
;;    
backup)    
notify backup    
/etc/rc.d/init.d/haproxy stop    
exit 0    
;;    
fault)    
notify fault    
/etc/rc.d/init.d/haproxy stop    
exit 0    
;;    
*)    
echo 'Usage: `basename $0` {master|backup|fault}'    
exit 1    
;;    
esac

4,下来便需要使用nginx做反向代理。所以我们需要提供两个real server提供web 服务。

由于资源原因我们下边实现只提供一台real server。

好,前提说完下边我们来为新的real server提供nginx,让nginx提供web服务。

real server上的nginx我们选择yum安装。

安装好后访问以下

keepAlived+nginx实现高可用双主模型LVS_第6张图片

好的,访问没有问题。

下边我们来配置nginx的反向代理。在node1,node2上。

下来配置nginx让其具有反向代理的作用。

在nginx的配置文件中server段中添加如下段。

[root@node1 ~]# vim /usr/local/nginx/conf/nginx.conf

location = / {  
proxy_pass
http://172.16.18.3;    #执行代理主机    
proxy_redirect off;                     #关闭重写location并刷新从upstream server收到的报文的首部

proxy_set_header X-Forwarded-For Proxy_add_x_forwarded_for;

}

nginx加载

[root@node1 ~]# service nginx reload

访问node1节点

keepAlived+nginx实现高可用双主模型LVS_第7张图片

为node2添加同样的段落。

[root@node2 ~]# vim /usr/local/nginx/conf/nginx.conf

location = / {  
proxy_pass http://172.16.18.3;  
proxy_redirect off;
proxy_set_header X-Forwarded-For Proxy_add_x_forwarded_for; #将本地地址发给后端
}


5,配置keepalived,生成ipvs

node1作为Director转发所有real server的请求,且node1,node2具有高可用性保障Director正常工作。

配置keepalived的配置文件,生成ipvs规则

vrrp_instance VI_1 {             #在这个段落中提供virtual_ipaddress ,生成VIP
virtual_ipaddress {
172.16.18.22
    }
}
virtual_server 172.16.18.22 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    persistence_timeout 50
    protocol TCP
    real_server 172.16.18.3 80 {
        weight 1
        HTTP_GET {
            url {
              path /
              status_code 200
            }
            connect_timeout 2       #超时时间
            nb_get_retry 2            #重试2次
            delay_before_retry 2   #延迟1秒
        }
    }
}


下边启动keepalived。发现抓发规则已经生成。

[root@node1 ~]# service keepalived start 
Starting keepalived: [ OK ] 
[
root@node1 ~]# ipvsadm -L -n 
IP Virtual Server version 1.2.1 (size=4096) 
Prot LocalAddress:Port Scheduler Flags 
-> RemoteAddress:Port Forward Weight ActiveConn InActConn 
TCP 172.16.18.22:80 rr persistent 50 
-> 172.16.18.3:80 Route 1 0 0

node2 上keepalived同样配置,但要注意,如果你复制配置文件过去的话要记得修改优先级和notify为备节点。

配置node3做real server。先修改内核参数

[root@node3 html]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore    
[
root@node3 html]# echo 1 > /proc/sys/net/ipv4/conf/ens33/arp_ignore    
[
root@node3 html]# echo 2 > /proc/sys/net/ipv4/conf/ens33/arp_ignore    
[
root@node3 html]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_ignore

配置lo:0接口和路由。

[root@node3 html]# ifconfig lo:0 172.16.18.22 netmask 255.255.255.255 broadcast 172.16.18.22 up    
[
root@node3 html]# route add -host 172.16.18.22 dev lo:0

好的,real server配置OK 。

下边我们物理机访问VIP看看效果

keepAlived+nginx实现高可用双主模型LVS_第8张图片

可以看到我们访问Director上的VIP转发访问到了real server上去了。此时keepalived的IPVS功能转发成功

6,那么下来我们来配置双主模式的IPVS,所以我们需要两个VIP

VIP1还是用:172.16.18.22,VIP2还是用:172.16.18.23

双主模型

keepAlived+nginx实现高可用双主模型LVS_第9张图片

配置node1的配置文件 /etc/keepalived/keepalived.conf

vrrp_instance VI_1 {
    state MASTER 
    interface eth0
    virtual_router_id 18 
    priority 100 
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
       virtual_ipaddress {
172.16.18.22
    }
track_script{
chk_nginx
}
notify_master "/etc/init.d/nginx start"
notify_backup "/etc/init.d/nginx stop"
notify_fault "/etc/init.d/nginx stop"
}
vrrp_instance VI_2 {
    state BACKUP 
    interface eth0
    virtual_router_id 19 
    priority 99
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
       virtual_ipaddress {
172.16.18.23
    }
track_script{
chk_nginx
}
notify_master "/etc/init.d/nginx start"
notify_backup "/etc/init.d/nginx stop"
notify_fault "/etc/init.d/nginx stop" 
}
virtual_server 172.16.18.22 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    netmask 255.255.0.0
    protocol TCP
    real_server 172.16.18.3 80 {
        weight 1
        HTTP_GET {
            url {
              path /
              status_code 200
            }
            connect_timeout 1
            nb_get_retry 1
            delay_before_retry 1
        }
    }
}
virtual_server 172.16.18.23 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    netmask 255.255.0.0
    protocol TCP
    real_server 172.16.18.3 80 {
        weight 1
        HTTP_GET {
            url {
              path /
              status_code 200
            }
            connect_timeout 1
            nb_get_retry 1
            delay_before_retry 1
        }
    }
}

复制配置文件到node2,修改主节点为 VI_2,备节点是 VI_1。还有优先级。

node1,node2 都重启keepalived

ipvsadm -L -n 查看一下生成的ipvs规则。

[root@node1 ~]# ipvsadm -L -n    
IP Virtual Server version 1.2.1 (size=4096)    
Prot LocalAddress:Port Scheduler Flags    
-> RemoteAddress:Port Forward Weight ActiveConn InActConn    
TCP 172.16.18.23:80 rr    
-> 172.16.18.3:80 Route 1 0 0    
TCP 172.16.18.22:80 rr    
-> 172.16.18.3:80 Route 1 0 0

OK ,IPVS规则也没有问题,查看node2上的,方法一样。

7,测试keepalived与nginx配合运行以及双主模型的ipvs.

因为本实验只提供了一个realserver,所以就不做轮询的测试。

测试ipvs规则是否转义,转移后访问vip1,vip2是否正常  
测试nginx程序挂点会不会转移,

到此双主模型的LVS,高可用构建完毕,没有单点故障,任何一点故障不影响业务。

实验到此结束。