本篇以Apache服务器为例讲述linux集群的lvs DR模式,dr与nat有相似处,本篇文章与上篇nat模式文章也有相似处。同样本篇先讲述lvs进行第7层健康检查情况,再讲述lvs进行第4层健康检查情况。同样都是集群技术,nat模式存在瓶颈,也就是瓶颈在HA分发器,而DR模式不存在瓶颈,可以极大提高网络带宽;不过NAT模式采用公网私有地址转换,nat模式节省稀缺的ipv4公网地址,而DR模式用到的ipv4地址都是公网地址(包括主从HA、各realserver用的ipv4都是公网ip),DR比较浪费地址;另外,dr模式中的主从HA服务器分别只要虚拟一个公网虚拟ip地址就行了,而nat模式中的主从HA服务器要分别各自模拟两个虚拟ip(一个是公网虚拟ip,一个是私网虚拟ip——供realserver作为网关用);dr模式中的各realserver服务器需要在lo地址上再绑定那个公网虚拟ip,而nat模式中的各realserver不需要这么做同样都是集群技术,lvs技术与nginx集群技术各有优缺点,场景不同选择方式也不一样,关于lvs与nginx的区别我已经专门写了一篇文章分析。本篇专门讲述lvs的DR技术

    实验环境:用4台linux虚机模拟,其中两台rhel5.6分别作为主从HA,上面配置keepalived和ipvsadm ;另外两台rhel4.6作为后端的realserver,上面搭建Apache服务器,此两台realserver模拟线上服务器。

    DR模式之所以不存在带宽瓶颈,是因为当realserver接收到HA分发的数据包,经过realserver处理后就直接发送到互联网上了,而不是像NAT模式那样realserver还要将处理好后的数据包再次转发给HA,然后HA还要返回给互联网(这是NAT模式形成瓶颈的原因)。见下面DR模式拓扑图,可以拿dr拓扑和nat拓扑作比较,其流量走向不同:

linux集群lvs dr模式(以Apache为例讲解)_第1张图片

    实验过程:

    将所有服务器的防火墙和selinux都关掉。用到的keepalived版本为keepalived-1.1.20.tar.gz,ipvsadm版本为ipvsadm-1.24.tar.gz。实验用的是DR模式rr算法。

    1.RS1的配置:

    在各realserver上只需搭建Apache、绑定虚拟ip到lo上以及取消arp转发功能等3大操作即可。

RS1的地址配成10.10.16.144

[root@RS1 ~]# vi /etc/sysconfig/network  ###修改主机名——修改hostname即可,一下的主机名都这么修改,修改保存后要重启服务器(reboot)才能生效。

    NETWORKING=yes

    HOSTNAME=RS1

[root@RS1 ~]# rpm -ivh httpd-2.0.52-38.ent.i386.rpm apr-util-0.9.4-21.i386.rpm httpd-suexec-2.0.52-38.ent.i386.rpm   ####安装Apache,由于这里realserver用的操作系统是rhel4.6,安装Apache操作和rhel5以上版本有所区别。

[root@RS1 ~]# vi /var/www/html/index.html   ###新建RS1 Apache主页面,作为用户访问测试用 

    RS1_ip:10.10.16.144

[root@RS1 ~]# vi /var/www/html/md5.html     ####在RS1的Apache目录里面新建md5.html网页,作为keepalived生成哈希值用,由于现在做的是lvs在7层做健康检查,要用到md5的哈希值验证

    ok,nimei!

[root@RS1 ~]# service httpd start

[root@RS1 ~]# chkconfig --level 35 httpd on

到这里,开始绑定虚拟公网ip到RS1的lo地址上,为了便于区别,这里绑定到lo:0,绑定虚拟公网ip目的是让realserver接收到的数据包经过处理后直接返回给互联网,而不是像nat模式那样还要将数据包返回给HA再由HA交给互联网。绑完公网ip后,还要取消arp响应,否则网络中会出现“这个公网ip对应多个mac地址回应数据”。可以用ifconfig lo:0 10.10.16.143绑到lo:0上,再将/proc/sys/net/ipv4/conf/lo/arp_ignore的值改为1,将/proc/sys/net/ipv4/conf/lo/arp_announce的值改为2,将/proc/sys/net/ipv4/conf/all/arp_ignore的值改为1,将/proc/sys/net/ipv4/conf/all/arp_announce的值改为2,这样就取消了了arp响应,这里可以写脚本将这两大步有条理的完成,脚本如下:

[root@RS1 ~]# vi realserver.sh   ###如果机器重启了,此脚本要重新运行一次,因为脚本里的添加ip的命令不是永久保存ip的

#!/bin/bash

#description: Config realserver


VIP=10.10.16.143

 

case "$1" in

start)

       /sbin/ifconfig lo:0 $VIP netmask 255.255.255.255 broadcast 10.10.16.255 up

       /sbin/route add -host $VIP dev lo:0

       echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore

       echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce

       echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore

       echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce

       sysctl -p >/dev/null 2>&1

       echo "RealServer Started !"

       ;;

stop)

       /sbin/ifconfig lo:0 down

       /sbin/route del $VIP >/dev/null 2>&1

       echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore

       echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce

       echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore

       echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce

       echo "RealServer Stoped !"

       ;;

*)

       echo "Usage: $0 {start|stop}"

       exit 1

esac

exit 0

[root@RS1 ~]# chmod 755 realserver.sh    ###给脚本赋可执行权限

[root@RS1 ~]# ./realserver.sh start      ####执行脚本,完成上述所述的两大步;也可以执行./realserver.sh stop取消lo:0和打开arp响应,调试的时候可以这么做 

到这里RS1的配置完成。


    2.RS2的配置

    RS2的配置和RS1的配置基本上相同,不同的是ip地址个Apache网页内容。

RS2的ip配成10.10.16.146

[root@RS2 ~]# rpm -ivh httpd-2.0.52-38.ent.i386.rpm apr-util-0.9.4-21.i386.rpm httpd-suexec-2.0.52-38.ent.i386.rpm 

[root@RS2 ~]# vi /var/www/html/index.html 

    RS2_ip:10.10.16.146

[root@RS2 ~]# cat /var/www/html/md5.html    ###注意到RS1、RS2的两个md5.html内容不一样,其生成对应的哈希值也不一样

ok,fuck!

[root@RS2 ~]# service httpd start

[root@RS2 ~]# chkconfig --level 35 httpd on

将RS1的realserver.sh脚本拷贝到RS2,赋权限执行start后,RS2的配置也完成。


    3.主HA的配置

    正如RS1和RS2的配置有很多相似处一样,主从HA的配置也有很多相似处。

[root@HA_master ~]# yum install gcc gcc-c++ openssl-devel kernel-devel -y

[root@HA_master ~]# tar zxf keepalived-1.1.20.tar.gz

[root@HA_master ~]# cd keepalived-1.1.20

[root@HA_master keepalived-1.1.20]# ./configure --sysconfdir=/etc --with-kernel-dir=/usr/src/kernels/2.6.18-238.el5-i686/

[root@HA_master keepalived-1.1.20]# make &&make install

[root@HA_master ~]# cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf_bak  ###记得养成备份配置文件的习惯

[root@HA_master ~]# genhash -s 10.10.16.144 -p 80 -u /md5.html   ####分别获取两个realserver的哈希值,将此哈希值分别拷贝到各HA的keepalived配置文件中,该哈希值作为验证作用

MD5SUM = 5a1074db9fdd7753f086403e299c32ba

[root@HA_master ~]# genhash -s 10.10.16.146 -p 80 -u /md5.html

MD5SUM = 5e300b0518b2b3ef570559828ebf47ab

[root@HA_master ~]# vi /etc/keepalived/keepalived.conf   ####将keepalived的配置文件改成如下:

! Configuration File for keepalived


global_defs {

   notification_email {

     [email protected]      ###可以将此处的邮箱地址改成自己的

   }

   notification_email_from [email protected]

   smtp_server 192.168.200.1        ####可以将此处的发送邮箱ip地址改成自己公司的邮件服务器ip

   smtp_connect_timeout 30

   router_id LVS_DEVEL

}


vrrp_instance web {

    state MASTER       ####将此处状态标识成master,若是从的写成backup或slave,名称的选取没有限制

    interface eth0     ###将此处的网卡名称写成系统真实存在的网卡名(即eth0),如果有两个网卡,即增加了eth1,则将此处代码段整体复制,在新的代码段中将此处命名eth1

    virtual_router_id 24      ###为了保证通信不和其他机器冲突,将此处的id写成自己独特的,id最大值是255

    priority 100        ###将优先级也修改一下,默认是51,主HA的优先级要高于从HA,区分HA是主还是从靠的就是这里的优先级区分

    advert_int 1

    authentication {

        auth_type PASS

        auth_pass 1124      ###可以将此处的验证码修改成自己的,默认是1111

    }

    virtual_ipaddress {

        10.10.16.143      ###将此处的虚拟ip地址修改成预算好的虚拟公网ip(10.10.16.143)

    }

}


virtual_server 10.10.16.143 80 {        #####配置realserver部分

    delay_loop 6

    lb_algo rr        ####这里的算法采用rr算法,也可以选别的算法

    lb_kind DR        ####这里的模式写成DR,注意要大写

    persistence_timeout 0       ####默认的连接时间是50秒,这里为了实验效果更明显,写成0,实际生产中要选择一个适当的数值

    protocol TCP


    real_server 10.10.16.144 80 {       #####配置第一台realserver

        weight 1

        HTTP_GET {         ####这里的名称最好写成HTTP_GET,我试了好几个别的名字用来取代HTTP都没有成功。

            url {

              path /md5.html        ###验证哈希值的网页

              digest 5a1074db9fdd7753f086403e299c32ba         #####将上面获得的哈希值分别写在此处

            }

            connect_timeout 3

            nb_get_retry 3

            delay_before_retry 3

        }

    }


    real_server 10.10.16.146 80 {

        weight 1

        HTTP_GET {

            url {

              path /md5.html

              digest 5e300b0518b2b3ef570559828ebf47ab

            }

            connect_timeout 3

            nb_get_retry 3

            delay_before_retry 3

        }

    }

}

[root@HA_master ~]# cp /usr/local/sbin/keepalived /usr/sbin

[root@HA_master ~]# service keepalived start

[root@HA_master ~]# chkconfig --level 35 keepalived on

[root@HA_master ~]# ln -s /usr/src/kernels/2.6.18-238.el5-i686/ /usr/src/linux

[root@HA_master ~]# tar zxf ipvsadm-1.24.tar.gz

[root@HA_master ~]# cd ipvsadm-1.24

[root@HA_master ipvsadm-1.24]# make &&make install

    ok,到这里,keepalived和ipvsadm都安装好了,现在用ipvsadm工具测试能否在HA上检测到realserver状态:

linux集群lvs dr模式(以Apache为例讲解)_第2张图片

    上面截图表明在主HA上能检测到realserver状态,也就是主HA配置完成。


    4.从HA的配置

[root@HA_slave ~]# yum install gcc gcc-c++ openssl-devel kernel-devel -y

[root@HA_slave ~]# tar zxf keepalived-1.1.20.tar.gz

[root@HA_slave ~]# cd keepalived-1.1.20

[root@HA_slave keepalived-1.1.20]# ./configure --sysconfdir=/etc --with-kernel-dir=/usr/src/kernels/2.6.18-238.el5-i686/

[root@HA_slave keepalived-1.1.20]# make &&make install

[root@HA_slave ~]# cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf_bak

[root@HA_slave ~]# genhash -s 10.10.16.146 -p 80 -u /md5.html

MD5SUM = 5e300b0518b2b3ef570559828ebf47ab

[root@HA_slave ~]# genhash -s 10.10.16.144 -p 80 -u /md5.html

MD5SUM = 5a1074db9fdd7753f086403e299c32ba

    走到这里,可以将主HA的keepalived配置文件拷贝到从HA的keepalived配置文件目录下,稍加修改即可:

[root@HA_slave ~]# cat /etc/keepalived/keepalived.conf

! Configuration File for keepalived


global_defs {

   notification_email {

     [email protected]

   }

   notification_email_from [email protected]

   smtp_server 192.168.200.1

   smtp_connect_timeout 30

   router_id LVS_DEVEL

}


vrrp_instance web {

    state BACKUP    ####标识为备用状态

    interface eth0

    virtual_router_id 24

    priority 96   #####优先级修改为比主HA的小

    advert_int 1

    authentication {

        auth_type PASS

        auth_pass 1124

    }

    virtual_ipaddress {

        10.10.16.143

    }

}


virtual_server 10.10.16.143 80 {

    delay_loop 6

    lb_algo rr

    lb_kind DR

    persistence_timeout 0

    protocol TCP


    real_server 10.10.16.144 80 {

        weight 1

        HTTP_GET {

            url {

              path /md5.html

              digest 5a1074db9fdd7753f086403e299c32ba

            }

            connect_timeout 3

            nb_get_retry 3

            delay_before_retry 3

        }

    }


    real_server 10.10.16.146 80 {

        weight 1

        HTTP_GET {

            url {

              path /md5.html

              digest 5e300b0518b2b3ef570559828ebf47ab

            }

            connect_timeout 3

            nb_get_retry 3

            delay_before_retry 3

        }

    }

}

[root@HA_slave ~]# cp /usr/local/sbin/keepalived /usr/sbin

[root@HA_slave ~]# service keepalived start

[root@HA_slave ~]# chkconfig --level 35 keepalived on

[root@HA_slave ~]# ln -s /usr/src/kernels/2.6.18-238.el5-i686/ /usr/src/linux

[root@HA_slave ~]# tar zxf ipvsadm-1.24.tar.gz

[root@HA_slave ~]# cd ipvsadm-1.24

[root@HA_slave ipvsadm-1.24]# make &&make install

    到这里,也可以用ipvsadm工具检测一下realserver的状态,如下面截图:

linux集群lvs dr模式(以Apache为例讲解)_第3张图片

    ok,上面截图表明在从HA上面也可以检测到realserver,到这里从HA的配置已经完成,也就是lvs DR模式对7层健康检查方法已经基本配置完成,下面做一些测试:

查看主HA的ip地址,发现eth0上绑定了“虚拟公网ip”:

linux集群lvs dr模式(以Apache为例讲解)_第4张图片

    查看从HA的IP地址,发现没有绑定任何地址,因为只要主HA活着,从HA就一直做备胎,只有当主HA挂掉,从HA才会从备胎转换成master,但是当主HA故障修复完成后,从HA又会自动让位变成备胎,主HA依然是主HA:

linux集群lvs dr模式(以Apache为例讲解)_第5张图片

下面看一下RS1的ip地址状态,发现多了一个lo:0地址:

linux集群lvs dr模式(以Apache为例讲解)_第6张图片

再看一下RS2的ip地址,发现也多了一个lo:0地址:

linux集群lvs dr模式(以Apache为例讲解)_第7张图片

    现在用宿主机的3个浏览器分别访问10.10.16.143,发现返回的结果是来自RS1和RS2:

linux集群lvs dr模式(以Apache为例讲解)_第8张图片

    再在从HA服务器上用文本浏览器(curl)再次验证从10.10.16.143返回的值,发现当用户访问虚拟公网ip时,RS1、RS2都工作,此时HA实现的是分发轮询。

linux集群lvs dr模式(以Apache为例讲解)_第9张图片

    现在让主HA网卡睡眠1分钟,即模拟主网卡故障,看从HA是否装换成主HA:

[root@HA_master ~]# ifdown eth0 &&sleep 60 &&ifup eth0

linux集群lvs dr模式(以Apache为例讲解)_第10张图片

    发现从HA已顺利转成master,虚拟公网ip10.10.16.143跳到了从HA的eth0上面,这表明,主从HA有了配合,转成主HA的从HA会做主HA相同的工作,二者的功能相同。当主HA恢复时,从Ha又从主状态变为从状态。

    当RS1挂了,看看用户访问时,HA是否还会把数据包分发到坏的RS1上面:(可以让RS1网卡睡眠或停止工作、RS1停机、RS1 Apache挂掉等模拟RS1挂掉)

linux集群lvs dr模式(以Apache为例讲解)_第11张图片

    发现当RS1挂了,HA不会把数据分发到RS1上了,而是将数据只分发到RS2上处理,如果有多台realserver则HA会把数据分发到除了RS1以外的其他realserver处理。当RS1恢复正常,则HA仍会将数据分发到RS1上处理,这说明了HA和realserver之间的配置是正确的,即HA的keepalived配置文件中关于realserver配置区域的配置是正确的。


    ok,lvs工作对7层检查检查的实验模拟完成(lvs只会工作在第四层,不会工作在第7层,但是lvs可以对第7层与第四层健康检查),现在模拟lvs对第4层健康检查模式的实验,其实这两种模式的配置基本相同,不同的是主从HA的keepalived的配置文件中关于realserver的配置,各realserver的配置不变。

下面是主HA的keepalived配置文件:

[root@HA_master ~]# cat /etc/keepalived/keepalived.conf

! Configuration File for keepalived


global_defs {

   notification_email {

     [email protected]

   }

   notification_email_from [email protected]

   smtp_server 192.168.200.1

   smtp_connect_timeout 30

   router_id LVS_DEVEL

}


vrrp_instance web {

    state MASTER

    interface eth0

    virtual_router_id 24

    priority 100

    advert_int 1

    authentication {

        auth_type PASS

        auth_pass 1124

    }

    virtual_ipaddress {

        10.10.16.143

    }

}


virtual_server 10.10.16.143 80 {

    delay_loop 6

    lb_algo rr

    lb_kind DR

    persistence_timeout 0

    protocol TCP


#    real_server 10.10.16.144 80 {

#        weight 1

#        HTTP_GET {

#            url {

#              path /md5.html

#              digest 5a1074db9fdd7753f086403e299c32ba

#            }

#            connect_timeout 3

#            nb_get_retry 3

#            delay_before_retry 3

#        }

#    }

#

#    real_server 10.10.16.146 80 {

#        weight 1

#        HTTP_GET {

#            url {

#              path /md5.html

#              digest 5e300b0518b2b3ef570559828ebf47ab

#            }

#            connect_timeout 3

#            nb_get_retry 3

#            delay_before_retry 3

#        }

#    }


      real_server 10.10.16.144 80 {

        weight 1

        TCP_CHECK{

          connect_port 80

          connect_timeout 3

          nb_get_retry 3

          delay_before_retry 3

         }

     }


    real_server 10.10.16.146 80 {

        weight 1

        TCP_CHECK{

          connect_port 80

          connect_timeout 3

          nb_get_retry 3

          delay_before_retry 3

        }

   }

}


下面是从HA的keepalived配置文件内容:

[root@HA_slave ~]# cat /etc/keepalived/keepalived.conf

! Configuration File for keepalived


global_defs {

   notification_email {

     [email protected]

   }

   notification_email_from [email protected]

   smtp_server 192.168.200.1

   smtp_connect_timeout 30

   router_id LVS_DEVEL

}


vrrp_instance web {

    state BACKUP

    interface eth0

    virtual_router_id 24

    priority 96

    advert_int 1

    authentication {

        auth_type PASS

        auth_pass 1124

    }

    virtual_ipaddress {

        10.10.16.143

    }

}


virtual_server 10.10.16.143 80 {

    delay_loop 6

    lb_algo rr

    lb_kind DR

    persistence_timeout 0

    protocol TCP


#    real_server 10.10.16.144 80 {

#        weight 1

#        HTTP_GET {

#            url {

#              path /md5.html

#              digest 5a1074db9fdd7753f086403e299c32ba

#            }

#            connect_timeout 3

#            nb_get_retry 3

#            delay_before_retry 3

#        }

#    }

#

#    real_server 10.10.16.146 80 {

#        weight 1

#        HTTP_GET {

#            url {

#              path /md5.html

#              digest 5e300b0518b2b3ef570559828ebf47ab

#            }

#            connect_timeout 3

#            nb_get_retry 3

#            delay_before_retry 3

#        }

#    }


      real_server 10.10.16.144 80 {

weight 1

TCP_CHECK{

 connect_port 80

 connect_timeout 3

 nb_get_retry 3

 delay_before_retry 3

}

     }


    real_server 10.10.16.146 80 {

weight 1

TCP_CHECK{

 connect_port 80

 connect_timeout 3

 nb_get_retry 3

 delay_before_retry 3

}

   }

}

    分别保存并重启keepalived,按照lvs对第7层健康检查模式去验证,会发现lvs对第4层健康检查仍然正常。这里的配置文件实际上就是把配置对第7层健康检查用的realserver区域注释掉,添加配置对第4层健康检查区域的代码。


    ok,到这里,使用rr算法的DR模式的LVS基于7层健康检查和基于4层健康检查的配置已经完成!