开发者社区> 科技小能手> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

基于LVS的Linux负载均衡技术实现(第二篇:基本NAT和DR结构的LVS集群构建)

简介:
+关注继续查看

下面是第一个实际的LVS配置的例子,整个的结构是基于NAT操作。在该例子中的结构比较简单:

 

 

上面的例子中,我暂时没有添加备份LVS Router,而只是通过一个主LVS Router来充当调度器。
配置步骤如下:
首先配置网络参数:
在LVS Router上的基本参数:
[root@localhost ~]# ifconfig | grep inet
inet addr:192.168.1.10 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe08:a162/64 Scope:Link
inet addr:10.0.0.10 Bcast:10.0.255.255 Mask:255.255.0.0
inet6 addr: fe80::20c:29ff:fe08:a16c/64 Scope:Link
[root@localhost ~]# sysctl -a | grep ip_forward
net.ipv4.ip_forward = 1
[root@localhost ~]# sysctl –p

在Real Server上的基本参数:
第一台:
[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0
# Advanced Micro Devices [AMD] 79c970 [PCnet32 LANCE]
DEVICE=eth0
ONBOOT=yes
BOOTPROTO=static
HWADDR=00:0c:29:b2:60:a5
IPADDR=10.0.0.100
NETMASK=255.255.0.0
GATEWAY=10.0.0.254
第二台:
[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0
# Advanced Micro Devices [AMD] 79c970 [PCnet32 LANCE]
DEVICE=eth0
ONBOOT=yes
BOOTPROTO=static
HWADDR=00:0c:29:b2:60:a5
IPADDR=10.0.0.200
NETMASK=255.255.0.0
GATEWAY=10.0.0.254

然后在LVS Router上安装piranha工具:
[root@localhost ~]# rpm -ihv ipvsadm-1.24.8.1.i386.rpm
[root@localhost ~]# rpm -ihv piranha-0.8.4-7.el5.i386.rpm
完成之后为piranha-gui设置密码并启动服务:
[root@localhost ~]# /usr/sbin/piranha-passwd 
New Password: 
Verify: 
Updating password for user piranha

[root@localhost ~]# service piranha-gui restart
Shutting down piranha-gui: [ OK ]
Starting piranha-gui: [ OK ]
[root@localhost ~]# chkconfig piranha-gui on

完成之后进入图形界面并在浏览器中输入:http://localhost:3636,输入用户名:piranha和刚才定义的密码,即可进入piranha configuration tool的配置界面:
在该界面中第一个要设置的地方是CONTROL/MONITORING,在该界面中将MONITOR中的选项:
Auto update勾选上,Update Interval将自动定义为10s,在服务没有启动之前LVS ROUTING TABLE和LVS PROCESS都不可见。完成之后选择Update information now。

在该界面的第二个要设置的地方是GLOBAL SETTINGS,在该界面中:
Primary server public IP:192.168.1.10 (真实外部地址)
Primary server private IP:10.0.0.10 (真实内部地址)
Use network type: NAT (LVS方式)
NAT Router IP: 10.0.0.254 (内部浮动IP)
NAT Router MASK: 255.255.0.0 (内部浮动掩码)
NAT Router Device: eth1:1 (运行浮动IP的设备)
选择接受配置

在该界面的第三个要设置的地方是REDUNDANCY,在该界面中:
由于没有在这个结构中加入冗余配置,所以可以将其DISABLE掉或者将其设置为ENABLE但是保持配置为空。在该例子中我的配置为空:
Redundant server public IP: 0.0.0.0
Redundant server private IP:
Heartbeat Interval (seconds): 6
Assume dead after (seconds): 18
Heartbeat runs on port: 539
Monitor NIC links for failure: 不勾选
选择接受配置

在该界面的第四个要设置的地方是VIRTUAL SERVERS:
每一个Virtual Servers代表所提供的一种服务,由于目前只有一种服务HTTP,所以选择ADD在提示中输入下面的信息:
Name: HTTP
Application port: 80
Protocal: TCP
Virtual Server Address: 192.168.1.250
Virtual IP Network Mask: 255.255.255.0
Firewall Mark: 
Device: eth0:1
Re-entry Time: 15
Service Timeout: 6
Quiesce: No
Load Monitor Tool: none
Scheduling: Weighted least-connections --加权最小连接法(默认)
Persistence: 
Persistence Network Mask: Unused
选择接受,并开启服务

在该界面的第五个要设置的地方是REAL SERVERS:
Name: localhost.localdomain
Address: 10.0.0.100
Weighted: 1
Name: localhost.localdomain
Address: 10.0.0.200
Weighted: 1
选择接受,并开启服务

在该界面的第六个要设置的地方是MONITORING SCRIPTS,保持默认即可

完成之后确认所有的配置都已经保存,这个LVS基本上就配置完成。最后的工作是在LVS的Router上启动主服务:
# service pulse start
# chkconfig pulse on
这个时候可以看到eth0:1和eth1:1已经自动建立:
[root@localhost ~]# ifconfig
eth0:1 Link encap:Ethernet HWaddr 00:0C:29:08:A1:62 
inet addr:192.168.1.250 Bcast:192.168.1.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
eth1:1 Link encap:Ethernet HWaddr 00:0C:29:08:A1:6C 
inet addr:10.0.0.254 Bcast:10.0.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
Interrupt:19 Base address:0x2080
并且相关服务也开启了:
[root@localhost ~]# service ipvsadm status
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddressort Scheduler Flags
-> RemoteAddressort Forward Weight ActiveConn InActConn
TCP 192.168.1.250:80 wlc
-> 10.0.0.200:80 Masq 1 0 0 
-> 10.0.0.100:80 Masq 1 0 15 
[root@localhost ~]# ps -ef | grep nanny
root 3614 3596 0 23:09 ? 00:00:03 /usr/sbin/nanny -c -h 10.0.0.100 -p 80 -s GET / 
HTTP/1.0\r\n\r\n -x HTTP -a 15 -I /sbin/ipvsadm -t 6 -w 1 -V 192.168.1.250 -M m -U none --lvs
root 3615 3596 0 23:09 ? 00:00:03 /usr/sbin/nanny -c -h 10.0.0.200 -p 80 -s GET / 
HTTP/1.0\r\n\r\n -x HTTP -a 15 -I /sbin/ipvsadm -t 6 -w 1 -V 192.168.1.250 -M m -U none --lvs
root 4078 3632 0 23:56 pts/1 00:00:00 grep nanny

同时开启两台真实服务器上的http服务,并在两台主机上的服务目录中分别建立同样的测试页面。
# chkconfig httpd on
# service httpd start

现在通过在客户端上访问LVS服务器进行测试:http://192.168.1.250,可以看到real server给出了页面。

这个时候piranha configuration tool界面刷新之后看到的当前ROUTER TABLE信息已经发生了改变:
CURRENT LVS ROUTING TABLE
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddressort Scheduler Flags
-> RemoteAddressort Forward Weight ActiveConn InActConn
TCP 192.168.1.250:80 wlc
-> 10.0.0.200:80 Masq 1 0 0
-> 10.0.0.100:80 Masq 1 0 0
而在当前LVS进程列表中也出现了内容:
CURRENT LVS PROCESSES
root 3678 0.0 0.1 1880 332 ? Ss 22:09 0:00 pulse
root 3702 0.0 0.2 1872 596 ? Ss 22:10 0:00 /usr/sbin/lvsd --nofork -c /etc/sysconfig/ha/lvs.cf
root 3720 0.0 0.2 1852 628 ? Ss 22:10 0:00 /usr/sbin/nanny -c -h 10.0.0.100 -p 80 -s GET / HTTP/1.0\r\n\r\n 
-x HTTP -a 15 -I /sbin/ipvsadm -t 6 -w 1 -V 192.168.1.250 -M m -U none --lvs
root 3721 0.0 0.2 1852 628 ? Ss 22:10 0:00 /usr/sbin/nanny -c -h 10.0.0.200 -p 80 -s GET / HTTP/1.0\r\n\r\n 
-x HTTP -a 15 -I /sbin/ipvsadm -t 6 -w 1 -V 192.168.1.250 -M m -U none --lvs

而在数次刷新页面之后就可以看到CURRENT LVS ROUTING TABLE的内容有所更新:
[root@localhost Desktop]# cat lvs
CURRENT LVS ROUTING TABLE
IP Virtual Server version 1.2.1 (size=4096)
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddressort Scheduler Flags
-> RemoteAddressort Forward Weight ActiveConn InActConn
TCP 192.168.1.250:80 wlc
-> 10.0.0.200:80 Masq 1 0 7
-> 10.0.0.100:80 Masq 1 0 6

也就是说访问量被平均分配到了两台主机上,如果我们找另外一个客户端做简单的压力测试:
命令:# ab -c 1000 -n 100000 http://192.168.1.250/index.html
获得的LVS ROUTING TABLE如下:
[root@localhost ~]# cat Desktop/lvs
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddressort Scheduler Flags
-> RemoteAddressort Forward Weight ActiveConn InActConn
TCP 192.168.1.250:80 wlc
-> 10.0.0.200:80 Masq 1 0 317
-> 10.0.0.100:80 Masq 1 0 1007

由于采用的是加权最小连接算法,所以负载不可能均分到两台服务器上。
此时配置文件的内容:
[root@localhost ~]# cat /etc/sysconfig/ha/lvs.cf 
serial_no = 67
primary = 192.168.1.10
primary_private = 10.0.0.10
service = lvs
backup_active = 1
backup = 0.0.0.0
heartbeat = 1
heartbeat_port = 539
keepalive = 6
deadtime = 18
network = nat
nat_router = 10.0.0.254 eth1:1
nat_nmask = 255.255.0.0
debug_level = NONE
monitor_links = 0
virtual HTTP {
active = 1
address = 192.168.1.250 eth0:1
vip_nmask = 255.255.255.0
port = 80
send = "GET / HTTP/1.0\r\n\r\n"
expect = "HTTP"
use_regex = 0
load_monitor = none
scheduler = wlc
protocol = tcp
timeout = 6
reentry = 15
quiesce_server = 0
server localhost.localdomain {
address = 10.0.0.100
active = 1
weight = 1
}
server localhost.localdomain {
address = 10.0.0.200
active = 1
weight = 1
}
}
实验到此成功。

现在我将这个实验的结构稍微做一下扩展,按照红帽所推荐的方案在结构中加入一备份 LVS ruoter,该备份LVS router的真实外网IP地址是192.168.1.20,真实内网IP是10.0.0.20。
按照上述的结构完成基本的网络配置:
[root@localhost ~]# ifconfig | grep inet
inet addr:192.168.1.20 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fecb:dd0b/64 Scope:Link
inet addr:10.0.0.20 Bcast:10.0.255.255 Mask:255.255.0.0
inet6 addr: fe80::20c:29ff:fecb:dd15/64 Scope:Link
开启IP转发:
[root@localhost ~]# sysctl -a | grep ip_forward
net.ipv4.ip_forward = 1

安装lvs相关软件包并进行基本配置:
[root@localhost ~]# rpm -ihv ipvsadm-1.24.8.1.i386.rpm
[root@localhost ~]# rpm -ihv piranha-0.8.4-7.el5.i386.rpm
完成之后为piranha-gui设置密码并启动服务:
[root@localhost ~]# /usr/sbin/piranha-passwd 
New Password: 
Verify: 
Updating password for user piranha 

[root@localhost ~]# service piranha-gui restart
Shutting down piranha-gui: [ OK ]
Starting piranha-gui: [ OK ]
[root@localhost ~]# chkconfig piranha-gui on

这里我偷了一个懒,因为不想再向第一台LVS Router那样一个一个通过piranha configuration tool配置参数,所以用scp将lvs.cf同步过来,并且开启服务:
# service pulse start
# chkconfig pulse on
完成之后进入图形界面,在浏览器中登录piranha configuration tools,需要修改的地方实际上有两处:
在该界面的第三个要设置的地方REDUNDANCY添加冗余配置:
Redundant server public IP: 192.168.1.20
Redundant server private IP: 10.0.0.20
Heartbeat Interval (seconds): 6
Assume dead after (seconds): 18
Heartbeat runs on port: 539
Monitor NIC links for failure: 不勾选
选择接受配置
另外在第一台LVS Router上也要做这方面的定义。

在该界面的第二个要设置的地方是GLOBAL SETTINGS,在该界面中:
Primary server public IP: 192.168.2.10 (真实外部地址)
Primary server private IP:10.0.0.20 (真实内部地址)
Use network type: NAT (LVS方式)
NAT Router IP: 10.0.0.254 (内部浮动IP)
NAT Router MASK: 255.255.0.0 (内部浮动掩码)
NAT Router Device: eth1:1 (运行浮动IP的设备)
选择接受配置

这样的话,配置文件的内容为:
[root@localhost ~]# cat /etc/sysconfig/ha/lvs.cf 
serial_no = 73
primary = 192.168.1.20
primary_private = 10.0.0.20
service = lvs
backup_active = 1
backup = 192.168.1.20
backup_private = 10.0.0.20
heartbeat = 1
heartbeat_port = 539
keepalive = 6
deadtime = 18
network = nat
nat_router = 10.0.0.254 eth1:1
nat_nmask = 255.255.0.0
debug_level = NONE
monitor_links = 0
virtual HTTP {
active = 1
address = 192.168.1.250 eth0:1
vip_nmask = 255.255.255.0
port = 80
send = "GET / HTTP/1.0rnrn"
expect = "HTTP"
use_regex = 0
load_monitor = none
scheduler = wlc
protocol = tcp
timeout = 6
reentry = 15
quiesce_server = 0
server localhost.localdomain {
address = 10.0.0.100
active = 1
weight = 1
}
server localhost.localdomain {
address = 10.0.0.200
active = 1
weight = 1
}
}

测试的方法很简单,第一台LVS Router现在是primary,那么正常情况下他提供服务,而备份lvs router开启pulse进程对第一台状态进行监控。现在将第一台LVS Router关闭,在短时间内客户端访问虚拟服务器将受到影响。但是在大概十秒左右的时间就可以访问成功,此时可以看到备份LVS Router已经成为primary并提供服务。如果此时再将已经关闭的第一台LVS Router开启,那么他将再次成为主LVS Router。
 

和NAT结构所不同的是,该LVS集群通过DR也就是direct route来实现。所谓direct route指的是LVS Router会将请求转发到真实服务器上,而每一台真实服务器都有能力通过一个特定的网关直接将外部请求转发出去。也就是说反馈的应答不会再通过原路即LVS Router走,而是通过其他出口出去。
这样做的好处是可以防止在大规模的LVS集群中因为调度器的性能问题而产生瓶颈,因此效率方面肯定要比NAT高。下面是一个基于DR实现的LVS结构图。我主要是在沿用上一个实验的一些结果。而DR和NAT的结构会有所改变。

下面的结构图是一个采用DR结构的实例:

 

 

 

如上图所示,我用一台windows主机做客户端,他的请求通过一台Linux路由器发送到LVS Router上。然后LVS Router再将请求转发到real server。而real server为了能够将请求不通过LVS Router转发出去则将网关直接指向了Router的内部接口。相当于每台real server都有直接将请求转发出去的能力,这样可以从很大程度上减少LVS Router的负载。

配置上面和刚才不同的地方是:
1.建立一台双网卡的Linux Router,并且开启ip_forward。
2.建立windows机器,配置地址为192.168.100.111,网关为192.168.100.30。
3.在主/备LVS Router上将网关指向Router的内部接口,并且重启网络和LVS相关服务。
4.比较关键的修改是real server上,需要将网关都指向Router的内部接口,这里是192.168.1.30。
5.必须在所有的real server上建立一个ifcfg-lo:1的接口,该接口的内容如下:
[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-lo:1
DEVICE=lo:1
IPADDR=192.168.1.250
NETMASK=255.255.255.255
NETWORK=192.168.1.250
ARP=no
TYPE=Ethernet
并且两台主机的ifcfg-lo:1文件内容是一样的。
(当时我曾经将子网掩码更改为255.255.255.0,结果出乎我意料,两台realserver只有一台能够启动网络,另外一台real server在启动网络的时候报错,提示地址被占用)
我猜测,添加这个接口的目的是要real server在收到请求之后能够冒充LVS Router对外部请求应答。

那么通过piranha所需要修改的地方包括:
a.取消private的地址;
b.更改real server地址为192.168.1.111和192.168.1.222
c.更改LVS类型为DR
完成之后保存,这是我在主LVS Router上获取的配置文件:
[root@localhost ha]# cat /etc/sysconfig/ha/lvs.cf
serial_no = 122
primary = 192.168.1.10
service = lvs
backup_active = 1
backup = 192.168.1.20
heartbeat = 1
heartbeat_port = 539
keepalive = 6
deadtime = 18
network = direct
nat_nmask = 255.255.255.0
debug_level = NONE
monitor_links = 1
virtual HTTP {
active = 1
address = 192.168.1.250 eth0:1
vip_nmask = 255.255.255.0
port = 80
send = "GET / HTTP/1.0\r\n\r\n"
expect = "HTTP"
use_regex = 0
load_monitor = none
scheduler = wlc
protocol = tcp
timeout = 6
reentry = 15
quiesce_server = 0
server localhost.localdomain {
address = 192.168.1.111
active = 1
weight = 1
}
server localhost.localdomain {
address = 192.168.1.222
active = 1
weight = 1
}
}

同时对备份LVS Router在原来基础上进行了一些修改,配置文件内容为:
[root@localhost ~]# cat /etc/sysconfig/ha/lvs.cf
serial_no = 122
primary = 192.168.1.20
service = lvs
backup_active = 1
backup = 192.168.1.20
heartbeat = 1
heartbeat_port = 539
keepalive = 6
deadtime = 18
network = direct
nat_nmask = 255.255.255.0
debug_level = NONE
monitor_links = 1
virtual HTTP {
active = 1
address = 192.168.1.250 eth0:1
vip_nmask = 255.255.255.0
port = 80
send = "GET / HTTP/1.0\r\n\r\n"
expect = "HTTP"
use_regex = 0
load_monitor = none
scheduler = wlc
protocol = tcp
timeout = 6
reentry = 15
quiesce_server = 0
server localhost.localdomain {
address = 192.168.1.111
active = 1
weight = 1
}
server localhost.localdomain {
address = 192.168.1.222
active = 1
weight = 1
}
}
注意我用蓝色标出的地方。有些人的配置中主/备LVS Router的配置文件是完全不一样的。尽管我没有测试过但是我总认为这样可能会导致一些问题的出现。
完成之后重启network以及lvs相关服务:pulse和ipvsadm。
检查服务:
主LVS Router上的信息:
[root@localhost ha]# service pulse status
pulse (pid 3664) is running...
[root@localhost ha]# service ipvsadm status
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddressort Scheduler Flags
-> RemoteAddressort Forward Weight ActiveConn InActConn
TCP 192.168.1.250:80 wlc
-> 192.168.1.111:80 Route 1 0 0 
-> 192.168.1.222:80 Route 1 0 0 
备份LVS Router上的信息:
[root@localhost ~]# service pulse status
pulse (pid 17459 17457 2260) is running...
[root@localhost ~]# service ipvsadm status
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddressort Scheduler Flags
-> RemoteAddressort Forward Weight ActiveConn InActConn
TCP 192.168.1.250:80 wlc
-> 192.168.1.111:80 Route 1 0 0 
-> 192.168.1.222:80 Route 1 0 0 

测试的时候可以在主/备LVS Router上开启wireshark并抓包。和NAT一样的是,如果default情况下有数据通过主LVS Router上过来的话,临时关闭主LVS Router,备份LVS Router会立刻通过heartbeat发现主LVS Router状态为失效,所以在这个时候如果在备份LVS Router上抓包会发现备份LVS Router此时会调用系统中的一个send_arp的命令向Router发送一个arp初始化信息,宣告原来的virtual server所对应的MAC地址改变,这个时候router会重新初始化mac-address-table。后续的外部请求将通过备份LVS Router进行转发。

另外在LVS配置的时候,real server上需要在启动系统之后检查自身的地址192.168.1.111和192.168.1.222是否能起来。我碰到的问题是192.168.1.111和192.168.1.222这两台真实服务器在正常重启之后这两个地址无法生效。而需要执行命令ifup eth0命令将这两个网卡带起来。也就是说白了,这两个地址不是很稳定。我的做法是可以将其加到/etc/rc.local文件中。在启动的时候确保网络接口启动。

(全文完)
 


本文转自 Bruceweien 51CTO博客,原文链接:http://blog.51cto.com/bruceweien/1068562


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Linux 文件压缩工具指南
文件的压缩和解压缩是计算历史上最有用的创造之一,但缺乏可移植性和开放工具是阻碍它发挥其应有作用的最主要的一个障碍。
867 0
23704
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载