【IT168 服务器频道】在"CDN缓存服务器的负载均衡"一文中,我们详细的介绍了单实例(vrrp_instance)、单虚拟地址(vip)实现负载均衡的方方面面,在这个应用场景中,它最主要的特征就是:主负载均衡器负责转发,而备份负载均衡器则处于等待状态,只有主负载均衡器失效,备份负载均衡器才承担用户请求转发任务。在多vrrp_instance负载均衡应用场景下,我将让两个负载均衡器都转发用户请求,其主要用意在于提高资源的利用率。
一、多vrrp_instance负载均衡需求描述
本方案要实现一个web及自定义的tcp服务的负载均衡.其中web为3个站点,运行在同一个服务器上,以虚拟机的方式实现;自定义的tcp服务,使用两个端口号,运行在不同的服务器上。
在这个环境中,共有14个服务器:2个负载均衡器(分别命名为 lvs-1、lvs-2),4个web服务器,4个运行自定义端口为3000 tcp服务的服务器,以及4个运行自定义端口为4000 tcp服务的服务器。本方案仍然使用负载均衡的DR模式,为了有效地使用紧缺的ip地址资源,我们只需要使用2个vip地址就可达到目的----web服务使用一个vip, 后面2个服务共用一个vip。为了更清楚地理解前面的描述,表1、2对整个需求进行了汇总。
负载均衡器 | Vip | Vrrp_instance | 角色 |
Lvs-1 | 61.135.93.99 60.135.93.100 | VI_WEB VI_CTCP | VI_WEB -à MASTER VI_CTCP-à BACKUP |
Lvs-2 | 61.135.93.99 60.135.93.100 | VI_WEB VI_CTCP | VI_WEB--à BACKUP VI_CTCP-à MASTER |
表1 负载均衡器需求汇总
项目 | Vip | 转发端口(TCP) | 转发规则 |
Web(bbs、blog、www) | 61.135.93.99 | 80 | 61.135.93.99:80à 61.135.93.x:80 |
自定义服务1 | 61.135.99.100 | 3000 | 61.135.93.100:3000à61.135.93.y: 3000 |
自定义服务2 | 61.135.93.100 | 4000 | 61.135.93.100:4000->61.135.93.z: 4000 |
表2 应用服务需求汇总
Web服务支持的3个站点均为动态网站,其运行环境为apache加php,因为涉及帐号登录,因此负载均衡过程必须启用会话保持。这里把3个站点整合到一个物理服务器上,既能保持服务配置的一致性,又能最大限度的利用资源。关于动态站点及apache虚拟的配置,请参看其他章节的内容。
二、多vrrp负载集群部署
参照"cdn缓存服务器集群部署"操作步骤,多vrrp_instance集群的部署也按真实服务器和负载均衡器2个环节来处理。
● 真实服务器上进行的操作
1、 编写负载均衡客户端配置脚本。本例中有3组真实服务器,每组服务器使用相同的lvs客户端配置脚本。配置脚本除了vip而外,其余的部分与本章其他部分所列的lvs客户端配置脚本完全相同。关于3个组vip地址使用情况,请看参表6-4,表6-5。
2、 检验lvs客户端配置脚本的正确性。
● 负载均衡器上的操作
1、 负载均衡器lvs_1
(1) 安装ipvsadm。方法如前文所叙。
(2) 安装keepalived。方法如前文所叙。
(3) 新增配置文件 /etc/keepalived/keepalived.conf。为了跟第二个lvs负载均衡器做比较,我在后面把2个配置文件放在一个表格里(表3),方便查看。
2、 负载均衡器lvs_2
(1)安装ipvsadm。方法如前文所叙。
(2)安装keepalived。方法如前文所叙。
(3)新增配置文件 /etc/keepalived/keepalived.conf。
负载均衡器lvs_1配置文件/etc/keepalived/keepalived.conf | 负载均衡器lvs_2配置文件/etc/keepalived/keepalived.conf |
#guration File for keepalived,writed by sery #global define global_defs { router_id lvs_1 } vrrp_sync_group VGM { group { VI_WEB } } vrrp_sync_group VGB { group { VI_CTCP } } vrrp_instance VI_WEB{ state MASTER interface eth0 lvs_sync_daemon_inteface eth0 virtual_router_id 51 priority 180 advert_int 5 authentication { auth_pass 1111 } virtual_ipaddress { 61.135.93.99 } } # setting port 80 forward virtual_server 61.135.93.99 80 { delay_loop 6 lb_algo wlc lb_kind DR persistence_timeout 10 protocol TCP real_server 61.135.99.80 80 { weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 80 } } real_server 61.135.93.81 80 { weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 80 } } real_server 61.135.93.82 80 { weight 90 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 80 } } real_server 61.135.93.83 80 { weight 90 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 80 } } } vrrp_instance VI_CTCP { state BACKUP interface eth0 lvs_sync_daemon_inteface eth0 virtual_router_id 52 priority 150 advert_int 5 authentication { auth_pass 2222 } virtual_ipaddress { 61.135.93.100 } } virtual_server 61.135.93.100 3000 { delay_loop 6 lb_algo wlc lb_kind DR persistence_timeout 50 protocol TCP real_server 61.135.93.84 3000{ weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 3000 } } real_server 61.135.93.85 3000{ weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 3000 } } real_server 61.135.93.86 3000{ weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 3000 } } real_server 61.135.93.87 3000{ weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 3000 } } } virtual_server 61.135.93.100 4000 { delay_loop 6 lb_algo wlc lb_kind DR persistence_timeout 50 protocol TCP real_server 61.135.93.88 4000{ weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 4000 } } real_server 61.135.93.89 4000{ weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 4000 } } real_server 61.135.93.90 4000{ weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 4000 } } real_server 61.135.93.91 4000{ weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 4000 } } } | #guration File for keepalived,writed by sery #global define global_defs { router_id lvs_2 } vrrp_sync_group VGM { group { VI_CTCP } } vrrp_sync_group VGB { group { VI_WEB } } vrrp_instance VI_WEB{ state BACKUP interface eth0 lvs_sync_daemon_inteface eth0 virtual_router_id 51 priority 150 advert_int 5 authentication { auth_pass 1111 } virtual_ipaddress { 61.135.93.99 } } # setting port 80 forward virtual_server 61.135.93.99 80 { delay_loop 6 lb_algo wlc lb_kind DR persistence_timeout 10 protocol TCP real_server 61.135.99.80 80 { weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 80 } } real_server 61.135.93.81 80 { weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 80 } } real_server 61.135.93.82 80 { weight 90 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 80 } } real_server 61.135.93.83 80 { weight 90 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 80 } } } vrrp_instance VI_CTCP { state MASTER interface eth0 lvs_sync_daemon_inteface eth0 virtual_router_id 52 priority 180 advert_int 5 authentication { auth_pass 2222 } virtual_ipaddress { 61.135.93.100 } } virtual_server 61.135.93.100 3000 { delay_loop 6 lb_algo wlc lb_kind DR persistence_timeout 50 protocol TCP real_server 61.135.93.84 3000{ weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 3000 } } real_server 61.135.93.85 3000{ weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 3000 } } real_server 61.135.93.86 3000{ weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 3000 } } real_server 61.135.93.87 3000{ weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 3000 } } } virtual_server 61.135.93.100 4000 { delay_loop 6 lb_algo wlc lb_kind DR persistence_timeout 50 protocol TCP real_server 61.135.93.88 4000{ weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 4000 } } real_server 61.135.93.89 4000{ weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 4000 } } real_server 61.135.93.90 4000{ weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 4000 } } real_server 61.135.93.91 4000{ weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 4000 } } } |
表3 lvs负载均衡器配置文件keepalived.conf
三、多vrrp_instance负载均衡集群功能测试
在进行测试之前,需要把lvs客户端、负载均衡器(keepalived)、各真实服务器上的服务都启动,并逐个检验其正确性,具体的检查方法可参照本章前面的内容,不再赘述。
● 健康检查功能(故障隔离)测试
多vrrp_instance健康检查功能(故障隔离)测试的方法与单vrrp_instance相同。因多vrrp_instance所涉及的服务较多(本案3个),因此需要多花些时间逐个测试。如果多vrrp_instance涉及的服务很多,则可采用随机抽样的方式进行测试,通过观察lvs负载均衡器的转发状态(ipvsadm)及lvs负载均衡器的系统日志了解健康检查测试的有效性。
● 负载均衡器失败切换
本案的多vrrp_instance负载均衡环境正常运行后,每个lvs负载均衡器都有MASTER和BACKUP两种状态,每一个lvs负载均衡器都承担转发任务。当我们在每个lvs负载均衡器上执行ipvsadm时,其输出结果正好交错的,即lvs-1上如果有非0输出时,则lvs_2相对应的项为0;反之亦然。表4为某运行环境lvs负载均衡器的输出截取对比。
Lvs_1 的ipvsadm输出(部分) | Lvs_2 的ipvsadm输出(部分) |
IP Virtual Server version Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 61.128.10.4:9000 wlc persistent 50 -> 61.128.10.16:9000 Route 200 4607 139 -> 61.128.10.17:9000 Route 200 4611 154 -> 61.128.10.5:9000 Route 100 2306 65 -> 61.128.10.8:9000 Route 100 2307 89 ……………………………… TCP 61.128.20.124:http wlc persistent 30 -> 61.128.20.98:http Route 100 0 0 -> 61.128.20.93:http Route 100 0 0 -> 61.128.20.81:http Route 100 0 0 -> 61.128.20.82:http Route 100 0 0 | IP Virtual Server version Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 61.128.10.4:9000 wlc persistent 50 -> 61.128.10.16:9000 Route 100 0 0 -> 61.128.10.17:9000 Route 100 0 0 -> 61.128.10.5:9000 Route 100 0 0 -> 61.128.10.8:9000 Route 100 0 0 …………………………… TCP 61.128.20.124:http wlc persistent 20 -> 61.128.20.98:http Route 100 821 1437 -> 61.128.20.93:http Route 100 823 1562 -> 61.128.20.82:http Route 100 823 1336 -> 61.128.20.81:http Route 100 825 1033 |
表4 多vrrp_instance 负载均衡器转发输出对比(注意观察ActiveConn InActConn的值)
现在,我们来停掉lvs_1的keepalived进程,观察lvs_2的系统日志,将会发现vrrp_instance(VI_WEB)从BACKUP状态变成MASTER.于是lvs_2负载均衡器有了两个 MASTER状态;另外lvs_2的ipvsadm的输出字段 "ActiveConn "的值将全部变成非零。同样,当我们启动lvs_1的keepalived进程、关闭lvs_2的keepalived进程,则lvs_1的状态都是MASTER,所有的转发请求都被转移到lvs_1。
在上述lvs_1和lvs_2手动切换过程中,我们可以通过在客户端浏览器地址栏输入站点名(dns解析域名到lvs的vip),来验证lvs的可用性。自定义服务可以通过在客户端执行 telnet 61.135.93.100 3000 及 telnet 61.135.93.100 4000 来初步验证。