设为首页 收藏本站

运维网

查看: 150|回复: 0

[经验分享] Keepalived实现高可用Nginx反向代理和基于NAT的LVS及分析

[复制链接]

尚未签到

发表于 4 天前 | 显示全部楼层 |阅读模式
  1. 前言
  keepalived是一个C语言开发的,能够基于Linux基础架构提供一个HA实现的软件。HA是基于VRRP协议实现,可以为LVS、Nginx、HAProxy等实现的LB提供高可用。
  下图是keepalived的软件架构图
DSC0000.gif

  主要核心模块:

  • Checkers:负责对Real Server进行健康检查。   
  • VRRP栈:实现了VRRP协议,实现了vrrp_sync_group扩展,不依赖于LVS可以独立的使用。例如下面第一个实验keepalived+nginx反代。   
  • IPVS Wrapper:将keepalived的控制数据转换成ipvs的规则   
  • Netlink Reflector:设定VRRP VIPs。
  2. 实验前提
  搭建时间服务器
  为192.168.23.0/24网络提供统一时钟,此网络中所有机器都开启ntpd守护进程,时间源指向192.168.23.123这台时间服务器。即在配置文件中server部分增加一条,并启动ntpd。
  # vim /etc/ntp.conf
  server 192.168.23.123
  # service ntpd start
  # chkconfig ntpd on
  3. 高可用反向代理
  这里使用LNNMP,在第一级N上实现反向代理的高可用。实验中上游服务器用2台nginx的WEB服务器,Mysql和PHP略去。LNNMP可以参照博文《Nginx之LNMP、LNNMP、LNNNMP架构实现及缓存技术》。
  3.1规划
DSC0001.jpg

  3.2 keepalived的安装
  CentOS6.4之后就已经收录了keepalived,因此直接可以yum安装。
# yum –y install keepalived  

  

# rpm -ql keepalived      

  

/etc/keepalived       

  

/etc/keepalived/keepalived.conf       

  

/etc/rc.d/init.d/keepalived       

  

/etc/sysconfig/keepalived       

  

/usr/sbin/keepalived  

  

……  

  可以看到默认的一个配置文件已经放在了/etc/keepalived下,只要对其根据规划修改就可以了。
  3.3 各服务器配置
  3.3.1 WEB1配置
  nginx.conf
# vim /usr/local/nginx/conf/nginx.conf  

  

user  nginx;      

  

worker_processes  auto;  

  

  

  

#pid        /var/run/nginx.pid;      

  

error_log   /var/log/nginx/error.log;  

  

  

  

events {      

  

    use epoll;       

  

    worker_connections  1024;       

  

}  

  

  

  

http {      

  

    include       mime.types;       

  

    default_type  application/octet-stream;  

  

  

  

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '      

  

                      '$status $body_bytes_sent "$http_referer" '       

  

                      '"$http_user_agent" "$http_x_forwarded_for"';  

  

  

  

    access_log  /var/log/nginx/access.log  main;  

  

  

  

    sendfile        on;      

  

    #tcp_nopush     on;  

  

  

  

    #keepalive_timeout  0;      

  

    keepalive_timeout 5;  

  

  

  

    #gzip  on;  

  

  

  

    server {      

  

        listen       80;       

  

        server_name  WEB1;       

  

        add_header X-upS  WEB1-$server_addr:$server_port;       

  

        #charset koi8-r;  

  

  

  

        #access_log  logs/host.access.log  main;  

  

  

  

        location / {      

  

            root   /web/nginx/static;       

  

            index  index.html index.htm;       

  

        }  

  

  

  

        #error_page  404              /404.html;  

  

  

  

        # redirect server error pages to the static page /50x.html      

  

        #       

  

        error_page   500 502 503 504  /50x.html;       

  

        location = /50x.html {       

  

            root   html;       

  

        }  

  

  

  

    }  

  

}  

  index.html
# vim /web/nginx/static/index.html  

  

  

  

  

  

static   

  

  

  

  

  

OK! This is a static page of WEB1  

  

  

  

  

  3.3.2 WEB2配置
  nginx.conf
# vim /usr/local/nginx/conf/nginx.conf  

  

user  nginx;      

  

worker_processes  auto;  

  

  

  

#pid        /var/run/nginx.pid;      

  

error_log   /var/log/nginx/error.log;  

  

  

  

events {      

  

    use epoll;       

  

    worker_connections  1024;       

  

}  

  

  

  

http {      

  

    include       mime.types;       

  

    default_type  application/octet-stream;  

  

  

  

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '      

  

                      '$status $body_bytes_sent "$http_referer" '       

  

                      '"$http_user_agent" "$http_x_forwarded_for"';  

  

  

  

    access_log  /var/log/nginx/access.log  main;  

  

  

  

    sendfile        on;      

  

    #tcp_nopush     on;  

  

  

  

    #keepalive_timeout  0;      

  

    keepalive_timeout 5;  

  

  

  

    #gzip  on;  

  

  

  

    server {      

  

        listen       8080;       

  

        server_name  WEB2;       

  

        add_header X-upS  WEB2-$server_addr:$server_port;       

  

        #charset koi8-r;  

  

  

  

        #access_log  logs/host.access.log  main;  

  

  

  

        location / {      

  

            root   /web/nginx/static;       

  

            index  index.html index.htm;       

  

        }  

  

  

  

        #error_page  404              /404.html;  

  

  

  

        # redirect server error pages to the static page /50x.html      

  

        #       

  

        error_page   500 502 503 504  /50x.html;       

  

        location = /50x.html {       

  

            root   html;       

  

        }  

  

    }      

  

}  

  index.html
# vim /web/nginx/static/index.html  

  

      

  

       

  

static       

  

       

  

       

  

OK! This is a static page of WEB2       

  

       

  

  

  3.3.3 Proxy1(keepalived MASTER)
  nginx.conf
# vim /usr/local/nginx/conf/nginx.conf  

  

user  nginx;  

  

worker_processes  auto;  

  

  

  

#pid        /var/run/nginx.pid;      

  

error_log   /var/log/nginx/error.log;  

  

  

  

events {      

  

    use epoll;       

  

    worker_connections  1024;       

  

}  

  

  

  

http {      

  

    include       mime.types;       

  

    default_type  application/octet-stream;  

  

  

  

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '      

  

                      '$status $body_bytes_sent "$http_referer" '       

  

                      '"$http_user_agent" "$http_x_forwarded_for"';  

  

  

  

    access_log  /var/log/nginx/access.log  main;  

  

  

  

    sendfile        on;      

  

    #tcp_nopush     on;  

  

  

  

    #keepalive_timeout  0;      

  

    keepalive_timeout 5;  

  

  

  

    #gzip  on;  

  

  

  

    upstream static {      

  

        server 192.168.23.80;       

  

        server 192.168.23.81:8080;  

  

  

  

        server 127.0.0.1:8080   backup;      

  

    }  

  

  

  

    server {      

  

        listen       80;       

  

        server_name  localhost;       

  

        add_header X-Proxy Proxy100-$server_addr:$server_port;       

  

        #charset koi8-r;       

  

        #access_log  logs/host.access.log  main;  

  

  

  

        location ~ \.(gif|jpg|jpeg|png|bmp|swf)$ {      

  

            expires 30d;       

  

        }  

  

  

  

        location ~ \.(js|css)$ {      

  

            expires 1h;       

  

        }  

  

  

  

        location / {      

  

            proxy_pass http://static;       

  

        }       

  

        #error_page  404              /404.html;  

  

  

  

        # redirect server error pages to the static page /50x.html      

  

        #       

  

        error_page   500 502 503 504  /50x.html;       

  

        location = /50x.html {       

  

            root   html;       

  

        }       

  

    }  

  

  

  

    server {      

  

        listen       8080;       

  

        server_name  sorry;       

  

        add_header X-Sorry  SorryServer-$server_addr:$server_port;       

  

        location / {       

  

            root html;       

  

            rewrite .* /maintenance.html break;       

  

        }  

  

    }  

  

}    

  

  

  maintenance.html
# vim /usr/local/nginx/html/maintenance.html  

  

  

  

  

  

       

  

Sorry  

  

       

  

  

  

Down for maintenance  

  

  

  keepalived.conf
# vim /etc/keepalived/keepalived.conf  

  

! Configuration File for keepalived  

  

  

  

global_defs {      

  

   router_id PROXY_HA1       

  

}  

  

  

  

vrrp_instance VI_PROXY_HA {      

  

    state MASTER  

  

  

  

    interface eth0      

  

    virtual_router_id 10  

  

  

  

    priority 100  

  

  

  

    advert_int 1      

  

    authentication {       

  

        auth_type PASS       

  

        auth_pass 192pass       

  

    }       

  

    virtual_ipaddress {       

  

        172.16.23.80       

  

    }  

  

}  

  3.3.4 Proxy2(keepalived BACKUP)
  nginx.conf
# vim /usr/local/nginx/conf/nginx.conf  

  

user  nginx;      

  

worker_processes  auto;  

  

  

  

#pid        /var/run/nginx.pid;      

  

error_log   /var/log/nginx/error.log;  

  

  

  

events {      

  

    use epoll;       

  

    worker_connections  1024;       

  

}  

  

  

  

http {      

  

    include       mime.types;       

  

    default_type  application/octet-stream;  

  

  

  

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '      

  

                      '$status $body_bytes_sent "$http_referer" '       

  

                      '"$http_user_agent" "$http_x_forwarded_for"';  

  

  

  

    access_log  /var/log/nginx/access.log  main;  

  

  

  

    sendfile        on;      

  

    #tcp_nopush     on;  

  

  

  

    #keepalive_timeout  0;      

  

    keepalive_timeout 5;  

  

  

  

    #gzip  on;  

  

  

  

    upstream static {      

  

        server 192.168.23.80;       

  

        server 192.168.23.81:8080;  

  

  

  

        server 127.0.0.1:8080   backup;      

  

    }  

  

  

  

    server {      

  

        listen       80;       

  

        server_name  localhost;       

  

        add_header X-Proxy Proxy101-$server_addr:$server_port;       

  

        #charset koi8-r;       

  

        #access_log  logs/host.access.log  main;  

  

  

  

        location ~ \.(gif|jpg|jpeg|png|bmp|swf)$ {      

  

            expires 30d;       

  

        }  

  

  

  

        location ~ \.(js|css)$ {      

  

            expires 1h;       

  

        }  

  

  

  

        location / {      

  

            proxy_pass http://static;       

  

        }       

  

        #error_page  404              /404.html;  

  

  

  

        # redirect server error pages to the static page /50x.html      

  

        #       

  

        error_page   500 502 503 504  /50x.html;       

  

        location = /50x.html {       

  

            root   html;       

  

        }       

  

    }  

  

  

  

    server {      

  

        listen       8080;       

  

        server_name  sorry;       

  

        add_header X-Sorry  SorryServer-$server_addr:$server_port;       

  

        location / {       

  

            root html;       

  

            rewrite .* /maintenance.html break;       

  

        }  

  

    }  

  

}  

  maintenance.html
# vim /usr/local/nginx/html/maintenance.html  

  

      

  

       

  

       

  

Sorry       

  

       

  

       

  

Down for maintenance       

  

  

  keepalived.conf
# vim /etc/keepalived/keepalived.conf  

  

! Configuration File for keepalived  

  

  

  

global_defs {      

  

   router_id PROXY_HA2       

  

}  

  

  

  

vrrp_instance VI_PROXY_HA {      

  

    state BACKUP  

  

  

  

    interface eth0      

  

    virtual_router_id 10  

  

  

  

    priority 99  

  

  

  

    advert_int 1      

  

    authentication {       

  

        auth_type PASS       

  

        auth_pass 192pass       

  

    }  

  

    virtual_ipaddress {       

  

        172.16.23.80       

  

    }  

  

}  

  从以上配置可以看出,使用唯一的资源就是VIP 172.16.23.80。这些配置都非常的简单,这里不做解释。关于nginx的配置,可以参照博文《Nginx之LNMP、LNNMP、LNNNMP架构实现及缓存技术》。
  为了区别,特意在nginx的代理服务器的配置中增加了header,2台代理是不一样的,这样在验证HA效果的时候可以判断是那一台代理服务器在工作。
  3.4 测试
  (1) 开启backup节点
  先开启Proxy2的nginx代理和keepalived服务,WEB1和WEB2的nginx的WEB服务。Proxy1的服务器暂不开启。
DSC0002.jpg

  上图中,启动了backup的keepalived。由于只有它一个节点,因此它成为主节点,并配置VIP开始工作。
DSC0003.jpg

DSC0004.jpg

  上面2图,使用了自定义的响应首部X-Proxy,说明了从172.16.23.80上80提供了代理,并轮询调度用户请求至上游服务器响应。
  (2) 开启master节点
  开启Proxy1的nginx代理和keepalived服务,由于Proxy1的优先级高,将成为名副其实的MASTER,将VIP资源夺回,配置在自身指定的接口上,同时Proxy2释放VIP资源。
DSC0005.jpg

  上图中master节点成为MASTER状态,配置VIP。
DSC0006.jpg

  而backup节点成为BACKUP状态,并释放IP资源。
DSC0007.jpg

DSC0008.jpg

  从首部信息看出,响应的代理服务器实际上发生了变化,这个Nginx代理服务器编译时修改了版本信息,因此Server:MeXP/1.0.1,这说明是另一个Proxy提供的代理服务。由于使用同样的VIP对外提供服务,因此X-Proxy是一样的,当然这个也可以设置不一样。
  依然实现对上游服务器的轮询调度。
  (3)小结
  从以上的测试中可以看到,VIP确实可以在不同的节点流动,但是有一个问题,如果nginx停止工作,VIP这个资源并不会转移,但是拥有VIP的节点实际上是不能提供WEB服务了。所以我们要增加对tcp 80端口的验证,只要WEB服务能够返回一个页面,或者能够返回状态码为200,就认为该节点正常,否则重新启动nginx或者迁移VIP资源。
  下来对keepalived的配置文件做一些改进。
  3.5 状态转换的通知机制
notify_master specify a shell script to be executed during transition to master statepathnotify_backupspecify a shell script to be executed during transition to backup state pathnotify_faultspecify a shell script to be executed during transition to fault statepath  由上表可知,keepalived在做状态变化的时候,可以调用一个脚本。这样我们可以把处理nginx服务的逻辑放在里面。
  我们要实现状态变成master,处理配置VIP还要启动nginx。其他状态都是移除VIP并关闭nginx。
  以backup节点为例,其配置文件修改如下:
! Configuration File for keepalived  

  

  

  

global_defs {      

  

   router_id PROXY_HA2       

  

}  

  

  

  

vrrp_instance VI_PROXY_HA {      

  

    state BACKUP  

  

  

  

    interface eth0      

  

    virtual_router_id 10  

  

  

  

    priority 99  

  

  

  

    advert_int 1      

  

    authentication {       

  

        auth_type PASS       

  

        auth_pass 192pass       

  

    }       

  

    virtual_ipaddress {       

  

        172.16.23.80       

  

    }       

  

    notify_master "/etc/rc.d/init.d/nginx start"       

  

    notify_backup "/etc/rc.d/init.d/nginx stop"       

  

    notify_fault "/etc/rc.d/init.d/nginx stop"       

  

}  

  这样,以后nginx启动的事情就可以交给keepalived来做了,所以在2台代理服务器上请停止nginx服务,并设置成开机不启动。
  # service nginx stop
  # chkconfig nginx off
  现在服务跟着主节点走,VIP也跟着主节点走。
  还是有一个问题,如果代理服务器上的nginx自己关闭了,怎么办?
  检测主节点nginx进程,如果失败就将权重减去一个大值,这样backup节点就提升为一个主节点,原主节点降为backup节点后会重启nginx服务,一旦启动成功,其权重恢复,这样重新投票它将重新获得主节点地位。
  master节点
# cat /etc/keepalived/keepalived.conf      

  

! Configuration File for keepalived  

  

  

  

global_defs {     

  

   router_id PROXY_HA1       

  

}       

  

vrrp_script chk_nginx {       

  

    script "killall -0 nginx"       

  

    interval 1       

  

    weight -5       

  

    fall 2       

  

    rise 1       

  

}       

  

vrrp_instance VI_PROXY_HA {       

  

    state MASTER       

  

    interface eth0       

  

    virtual_router_id 10       

  

    priority 100       

  

    advert_int 1       

  

    authentication {       

  

        auth_type PASS       

  

        auth_pass 192pass       

  

    }       

  

    track_script {       

  

        chk_nginx       

  

    }       

  

    virtual_ipaddress {       

  

        172.16.23.80       

  

    }       

  

    notify_master "/etc/rc.d/init.d/nginx start"       

  

    notify_backup "/etc/rc.d/init.d/nginx restart"       

  

    notify_fault "/etc/rc.d/init.d/nginx stop"       

  

}  

  backup节点
! Configuration File for keepalived  

  

  

  

global_defs {      

  

   router_id PROXY_HA2       

  

}       

  

vrrp_script chk_nginx {       

  

    script "killall -0 nginx"       

  

    interval 1       

  

    weight -2       

  

    fall 2       

  

    rise 1       

  

}       

  

vrrp_instance VI_PROXY_HA {       

  

    state BACKUP  

  

  

  

    interface eth0      

  

    virtual_router_id 10  

  

  

  

    priority 99  

  

  

  

    advert_int 1      

  

    authentication {       

  

        auth_type PASS       

  

        auth_pass 192pass       

  

    }       

  

    track_script {       

  

        chk_nginx       

  

    }     

  

    virtual_ipaddress {       

  

        172.16.23.80       

  

    }       

  

    notify_master "/etc/rc.d/init.d/nginx start"       

  

    notify_backup "/etc/rc.d/init.d/nginx restart"       

  

    notify_fault "/etc/rc.d/init.d/nginx stop"       

  

}  

  看看测试的效果,在BACKUP节点观察
DSC0009.jpg

  上图中首先启动BACKUP节点,它进入MASTER状态配置了VIP后,调用了/etc/rc.d/init.d/nginx脚本启动nginx服务。
  随后,启动MASTER节点,BACKUP节点转入BACKUP状态,移除VIP,调用了/etc/rc.d/init.d/nginx脚本停止nginx服务。
  4. 高可用LVS
  4.1 规划
DSC00010.jpg

  说明:
  使用VS/NAT完成。
  和上例的规划图非常相似,只不过keepalived内部集成IPVS Wrapper。
  因此需要修改master和backup的配置文件。注意如果在上例的基础上做,因为nginx代理监听tcp 80端口,为了避免引起疑惑,还是把nginx停止或移除较好。
  注:本实验中ipvs也要检查发往80端口的数据,但是这和上例实验本质是不同。因为ipvs在内核中就已经把数据报文截获,并处理转发。
  4.2 网关设置
  使用VS/NAT模型,LVS中Director做的是DNAT,所以要在内网主机上WEB1、WEB2、sorry server上配置路由,但是因为2个keepalived节点上的内网地址不同,路由实际上也是变化的,如何做呢?
  可以在master和backup上配置同一个内网地址资源192.168.23.105,这个资源和VIP一样是跟随着主节点的,并使它成为这几台为外部提供WEB服务的主机网关,因此配置接口增加网关配置。
  在内网主机上配置网关,如下:
  # vim /etc/sysconfig/network-scripts/ifcfg-eth0
  GATEWAY=192.168.23.105
  4.3 ipvsadm的安装
  安装ipvsadm是为了验证keepalived是否加入了规则,ipvsadm其实可以不安装
# yum -y install ipvsadm      

  

# ipvsadm -L -n       

  

IP Virtual Server version 1.2.1 (size=4096)       

  

Prot LocalAddress:Port Scheduler Flags       

  

  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn  

  可以看到没有任何规则
  4.4 WEB1
  提供测试页、计算测试网页的md5值
# cd /web/nginx/static/      

  

# vim test.html       

  

Just test for WEB1       

  

# md5sum test.html       

  

60f16b089b6c69717ffdd41fc0896652  test.html  

  4.5 WEB2
  提供测试页、计算测试网页的md5值
# cd /web/nginx/static/      

  

# vim test.html       

  

Just test for WEB2       

  

# md5sum test.html       

  

b75859919db38e0501fa02de82026078  test.html  

  4.6 master节点配置
  keepalived的配置、开通主机路由
! Configuration File for keepalived  

  

  

  

global_defs {     

  

   router_id PROXY_HA1       

  

}  

  

  

  

vrrp_sync_group VGM {      

  

   group {       

  

      VI_LVS_HA       

  

      VI_LOCAL_ADDR       

  

   }       

  

}  

  

  

  

vrrp_instance VI_LOCAL_ADDR {      

  

    state MASTER       

  

    interface eth1       

  

    vs_sync_daemon_inteface eth1       

  

    virtual_router_id 11       

  

    priority 100       

  

    advert_int 1       

  

    authentication {       

  

        auth_type PASS       

  

        auth_pass 168pass       

  

    }       

  

    virtual_ipaddress {       

  

        192.168.23.105       

  

    }       

  

}  

  

  

  

vrrp_instance VI_LVS_HA {      

  

    state MASTER       

  

    interface eth0       

  

    vs_sync_daemon_inteface eth0       

  

    virtual_router_id 10       

  

    priority 100       

  

    advert_int 1       

  

    authentication {       

  

        auth_type PASS       

  

        auth_pass 192pass       

  

    }  

  

  

  

    virtual_ipaddress {      

  

        172.16.23.80       

  

    }       

  

}  

  

  

  

virtual_server 172.16.23.80 80 {      

  

    delay_loop 6       

  

    lb_algo rr       

  

    lb_kind NAT       

  

    persistence_timeout 5       

  

    protocol TCP  

  

  

  

    sorry_server 192.168.23.121 8080  

  

  

  

    real_server 192.168.23.80 80 {      

  

        weight 1       

  

        HTTP_GET {       

  

            url {       

  

              path /test.html       

  

              digest 60f16b089b6c69717ffdd41fc0896652       

  

            }       

  

            connect_timeout 3       

  

            nb_get_retry 3       

  

            delay_before_retry 3       

  

        }       

  

    }  

  

  

  

    real_server 192.168.23.81 8080 {      

  

        weight 1       

  

        HTTP_GET {       

  

            url {       

  

              path /test.html       

  

              digest b75859919db38e0501fa02de82026078       

  

            }       

  

            connect_timeout 3       

  

            nb_get_retry 3       

  

            delay_before_retry 3       

  

        }       

  

    }       

  

}  

  

  

  

# sed -i 's/net.ipv4.ip_forward =.*/net.ipv4.ip_forward = 1/' /etc/sysctl.conf  

  

# sysctl –p  

  4.7 backup节点配置
  keepalived的配置文件、开通主机路由
! Configuration File for keepalived  

  

  

  

global_defs {     

  

   router_id PROXY_HA2       

  

}  

  

  

  

vrrp_sync_group VGM {      

  

   group {       

  

      VI_LVS_HA       

  

      VI_LOCAL_ADDR       

  

   }       

  

}  

  

  

  

vrrp_instance VI_LOCAL_ADDR {      

  

    state BACKUP       

  

    interface eth1       

  

    lvs_sync_daemon_inteface eth1       

  

    virtual_router_id 11       

  

    priority 99       

  

    advert_int 1       

  

    authentication {       

  

        auth_type PASS       

  

        auth_pass 168pass       

  

    }       

  

    virtual_ipaddress {       

  

        192.168.23.105       

  

    }       

  

}  

  

  

  

vrrp_instance VI_LVS_HA {      

  

    state BACKUP       

  

    interface eth0      

  

    lvs_sync_daemon_inteface eth0       

  

    virtual_router_id 10  

  

  

  

    priority 99      

  

    advert_int 1       

  

    authentication {       

  

        auth_type PASS       

  

        auth_pass 192pass       

  

    }  

  

  

  

    virtual_ipaddress {      

  

        172.16.23.80       

  

    }       

  

}  

  

  

  

virtual_server 172.16.23.80 80 {      

  

    delay_loop 6       

  

    lb_algo rr       

  

    lb_kind NAT       

  

    persistence_timeout 5       

  

    protocol TCP  

  

  

  

    sorry_server 192.168.23.121 8080  

  

  

  

    real_server 192.168.23.80 80 {      

  

        weight 1       

  

        HTTP_GET {       

  

            url {       

  

              path /test.html       

  

              digest 60f16b089b6c69717ffdd41fc0896652       

  

            }       

  

            connect_timeout 3       

  

            nb_get_retry 3       

  

            delay_before_retry 3       

  

        }       

  

    }  

  

  

  

    real_server 192.168.23.81 8080 {      

  

        weight 1       

  

        HTTP_GET {       

  

            url {       

  

              path /test.html       

  

              digest b75859919db38e0501fa02de82026078       

  

            }       

  

            connect_timeout 3       

  

            nb_get_retry 3       

  

            delay_before_retry 3       

  

        }       

  

    }       

  

}  

  

  

  

# sed -i 's/net.ipv4.ip_forward =.*/net.ipv4.ip_forward = 1/' /etc/sysctl.conf  

  

# sysctl –p  

  4.8 sorry server配置
  nginx的配置,并启动。maintenance.html内容已将在上面提供过了。
user  nginx;      

  

worker_processes  auto;  

  

  

  

#pid        /var/run/nginx.pid;      

  

error_log   /var/log/nginx/error.log;  

  

  

  

events {      

  

    use epoll;       

  

    worker_connections  1024;       

  

}  

  

  

  

http {      

  

    include       mime.types;       

  

    default_type  application/octet-stream;  

  

  

  

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '      

  

                      '$status $body_bytes_sent "$http_referer" '       

  

                      '"$http_user_agent" "$http_x_forwarded_for"';  

  

  

  

    access_log  /var/log/nginx/access.log  main;  

  

  

  

    sendfile        on;      

  

    #tcp_nopush     on;  

  

  

  

    #keepalive_timeout  0;      

  

    keepalive_timeout 5;  

  

  

  

    #gzip  on;      

  

    server {       

  

        listen       8080;       

  

        server_name  sorry;       

  

        add_header X-Sorry  SorryServer-$server_addr:$server_port;       

  

        location / {       

  

            root html;       

  

            rewrite .* /maintenance.html break;       

  

        }       

  

    }       

  

}  

  4.9 测试
  先启动backup节点,后启动master节点,看看backup节点的变化
DSC00011.jpg

  测试一下
DSC00012.jpg

  可以看到直接是由后端的real server响应的。其他测试不再赘述。
  4.10 keepalived节点究竟做了什么?
DSC00013.jpg

  1) DNAT
  keepalived的MASTER状态的节点获得VIP,同时它也成为了LVS的director,并且做DNAT后,把客户端数据发送至后端服务器,后端服务器响应请求,并发送数据给网关director,由网关替换源地址为VIP后,将数据发往客户端。
  2) VRRP协议心跳
  keepalived所有节点都在向组播地址发心跳包
  3) 健康状态检测
  不断的向内网探测后端服务器的健康状况,这里是用访问测试页并用其md5值来判断。这样的好处是,真正由WEB服务返回数据,比ping服务器、监控WEB服务的方式好。因为ping通一台主机或者监控web服务进程存在不能说明web服务能够真正的提供服务。
  4.11 sorry server
  将WEB1和WEB2上的测试网页test.html改名,2台keepalived节点的测试发现test.html找不到了,认为real server故障,便移除2台real server,最后只能指向sorry server。
DSC00014.jpg

  [ 抓包分析 ]
DSC00015.jpg

  可以看到对index.html的请求转向了192.168.23.121的8080来响应,返回维护页面。
  对测试页面test.html的访问返回了404错误,找不到test.html了。因此keepalived就在ipvs中把WEB1和WEB2的调度移除,加入sorry server。
  至此基于keepalived完成VS/NAT模型的高可用实验。
  4.12 总结
  可以看出,在NAT模式下,数据做了DNAT后,发往Real Server,所以服务器必须指定网关或路由,但是由于HA集群中当前为master的节点不一定,所以也不清楚究竟哪一个内网地址可以作为网关,因此再引入一个网关IP地址资源,让它跟随着master节点迁移,而网关指向这个地址就可以了。这样就能保证数据一般情况下会从来路返回给客户端。
  keepalived对测试页面的HTTP_GET测试,使用的是内网地址,按照配置的策略不断测试。只要keepalived启动,不管是否是主从节点,都会进行测试。
  5. 进阶双主模型
  这里就有了一个大的麻烦,为了解决数据报文的原路返回,使用了一个内网地址的资源192.168.23.105。
  如果做成一个双主模型,势必内网地址也得有2个,这样内网中上游服务器的路由又没有办法配置路由了。因为上游服务器返回数据的时候一定要原路返回,而上游服务器发出的包的目标地址是客户端IP,不是Director,所以上游服务器不知道从哪一个Director进来的,该发回给哪一个Director,因为只有在进来的Director上通过连接追踪才能替换源地址为VIP,并把数据包转发给客户端。
  如何解决呢?
  (1)VS/FullNAT
  淘宝实现FullNAT的并提供出来。
  根据目前淘宝大侠们的提供的信息,使用LVS FullNAT要向特定版本内核打补丁,重新编译内核。编译其提供的ipvsadm和keepalived。
  目前还没有完全调试完成。所以后续博文中将实现LVS的FULLNAT + Keepalived + nginx(WEB) 双主模型高可用实验。
  (2)VS/DR
  可以使用DR模型,客户端请求在前端被DNS调度到不同的keepalived的节点,这里是2个主节点,每一个主节点都把请求调度到上游服务器,上游服务器响应后,直接把响应的结果发个这个内网中某个路由器(包括网关),这个路由器能把数据发给下一跳路由器,就这样数据返回到了客户端。
  DR模型实现起来也不用像NAT模型那样需要配置内网的VRRP地址且让数据从Director原路返回。
  参考资料
  http://www.keepalived.org/LVS-NAT-Keepalived-HOWTO.html
  http://kb.linuxvirtualserver.org/wiki/IPVS_FULLNAT_and_SYNPROXY



运维网声明 1、欢迎大家加入本站运维交流群:群①:263444886群②:197202523群③:485755530群④:201730672群⑤:202807635运维网交流群⑥:281548029
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、其他单位或个人使用、转载或引用本文时必须注明原文的出处
4、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
5、运维网 - 服务您的运维操作管理专家!
6、联系人Email:admin@yunvn.com 网址:www.iyunv.com

点击关注更多内容
您需要登录后才可以回帖 登录 | 立即注册  

本版积分规则  允许回帖邮件提醒楼主

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服 E-mail:kefu@yunvn.com

本站由青云提供云计算服务

运维网--中国最专业的运维工程师交流社区

京ICP备14039699号-1 Copyright © 2012-2018

使用手机软件扫描微信二维码

关注我们可获取更多热点资讯

Good good study day day up !


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


独家合作伙伴: 青云cloud

快速回复 返回顶部 返回列表