LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统。本项目在1998年5月由章文嵩博士成立,是中国国内最早出现的自由软件项目之一。章文嵩博士目前工作于中国国家并行与分布式处理重点实验室,主要从事集群技术、操作系统、对象存储与数据库的研究。
常用名词备注
使用LVS架设的服务器集群系统有三个组成部分。
1、前端负载均衡层
Load Balancer层,位于整个集群系统的最前端。由一台或多台负载调度器(Director Server)组成,LVS模块就安装在调度器上。调度器的作用类似于路由器,它含有完成LVS功能所设定的路由表,通过这些路由表把用户的请求分发给Array Server层的应用服务器(真实服务器)。同时在调度器上,还要安装对真实服务器服务的监控模块Ldirectord,Ldirectord模块用于检测各个真实服务器的健康状况,在真实服务器不可用时把它从LVS路由表剔除,恢复时重新加入
Director Server是整个LVS集群系统的核心。Linux2.6的内核默认支持LVS功能
2、中间服务器群组层
Array Server层,由一组实际运行的应用服务器/真实服务器组成,真实服务器(Real Server)可以是web服务器,mail服务器,DNS服务器,FTP服务器,视频服务器中的一个或多个。每个真实服务器之间可以通过高速LAN或分布在各地的WAN相连接。在实际应用中,调度器也可以兼任真实服务器的角色。
3、底层数据共享存储层
SharedStorage层,为所有Real Server提供共享存储空间和内容一致性的存储区域。在物理上,一般由磁盘阵列设备组成,为了提供内容一致性,一般通过NFS网络文件系统共享数据,但是NFS在繁忙的业务系统中,性能不是很好,此时可以采用集群文件系统,例如Red Hat的GFS文件系统,oracle提供的OCFS2文件系统。
实验所需:
服务器 | IP地址 |
---|---|
director | 192.168.159.135 |
RS1 | 192.168.159.132 |
RS2 | 192.168.159.136 |
大多数商品化的IP负载均衡硬件都是使用此方法,如Cisco的LocalDirector、F5的Big/ip。详细介绍4个步骤如下:
1)客户端发送请求到达director
2)director根据负载均衡算法改写目标地址为后端的RIP并转发给该后端主机,和NAT一样
3)当后端主机(RS)处理完请求后,将响应数据交给director
4)Director改写源地址为VIP后传给客户端
1、RIP和DIP一般处于同一私有网段中。但并非必须,RS的网关要指向DIP,这样能保证将响应数据交给Director
2、支持端口映射,可修改请求报文的目标端口;
3、VS/NAT模式的最大缺点使Director负责所有进出数据:不仅处理客户端发起的请求,还负责将响应传输给客户端。而响应数据一般比请求数据大得多,调度器Director容易出现瓶颈。(也就是像7层负载的处理方式一样,但却没有7层负载那么多功能)
4、vs必须使linux系统,RS可以是任何系统
缺点:在整个过程中,所有输入输出的流量都要经过LVS调度器,调度器网络I/O压力就会非常大,因此很容易称为瓶颈,特别使对请求流量很小,而响应流量很大的web类应用来说更为如此;
优点:NAT模式配置管理简单,由于使用了NAT技术,LVS调度器及应用服务器可以在不同网段中,网络架构灵活,应用服务器只需要进行简单的网络设定即可加入集群。
1)、客户端发送请求到达director,也就是CIP:VIP ;
2)、director将请求报文重新封装一个mac地址首部dip-mac:rip-mac,所以DIP和RIP需要相同的物理网络实现arp通信,源IP地址和目标IP地址不变,只是修改源mac地址为DIP的mac地址,目标mac地址改为RIP的mac地址;然后发送给RS;
3)、RS发现目标地址是自己的MAC地址处理报文,并且RS本地会还接口Lo配置为VIP,响应报文从Lo的VIP发送给eth0网卡,所以响应报文首部cip-mac:Lo-mac,最后响应报文直接发送给客户端,此时源ip地址为VIP,目标地址为CIP;
注意:RS,director都有VIP,所以要确保请求报文只发送到director,常见的方法修改RS的内核参数arp_ignore、arp_announce设置为1,使RS不影响其他主机的ARP通信。
补充:两个内核参数设定说明
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_announce
arp_ignore 定义是否相应
arp_announce 是否介绍通告,是否通知别人
1)确保前端路由器将目标ip为vip的请求报文发往director
2)、RS的RIP可以使用私网或公网地址;
3)、RS跟director在同一物理网络;
4)、请求报文经由director,响应报文直接发往client;
5)、此模式不支持端口映射;
6)、RS支持大多数的OS;
7)、RIP的网关不能指向DIP,以确保响应报文不经由director;
缺点:LVS调度器及应用服务器在同一个网段中,因此不能实现集群的跨网段应用。
优点:直接路由转发,通过修改请求报文的目标mac地址进行转发,效率提升明显
1)、客户端将请求发送前端的负载均衡器,请求报文源地址是CIP,目标地址为VIP。
2)、负载均衡器收到报文后,发现请求的在规则里面存在的地址,它将请求报文的首部再封装一层IP报文,将源地址改为DIP,目标地址改为RIP,并将此包发送给RS;
3)、RS收到请求报文后,会首先拆开第一层封装,然后发现里面还有一层IP首部的目标地址是自己Lo接口上的VIP,所以会再次处理请求报文(这种2次分装解封装的过程,就称为隧道模式)并将响应报文通过Lo接口送给eht0网卡然后直接发给客户端,这种模式也是需要设置Lo接口为VIP,并且不能在公网上
关于这种模式:
1)、DIP、VIP、RIP、都应该是公网地址;
2)、RS的网关不能指向DIP;
3)、请求报文要经由Director,响应报文不经由director;
4)、不知道端口映射
5)、RS的操作系统需要支持隧道功能
缺点:需要租用大量IP,特别是后端服务器使用较多的情况下
优点:LVS调度器将TCP/IP请求重新封装发给后端服务器,后端应用服务器之间通过IP隧道来进行转发,可以存在于不同的网段中
1)、客户端对VIP发起请求;
2)、director接收请求,发现是请求后端集群,对请求报文做full nat,源IP改为DIP,目标IP转换为任意后端RS的RIP,然后发往后端;
3)、RS收到请求后,进行响应,源IP为RIP,目标IP为DIP,内部路由到director;
4)、director收到响应报文后,进行full nat,源地址改为VIP,目标地址改为CIP;
关于这种模式:
1)、VIP是公网地址,RIP和DIP是死亡地址,且通常不在同一网络,因此RIP的网关一般不会指向DIP;
2)、RS收到的请求报文地址是DIP,因此只需响应给DIP,但director还要将其发往client;
3)、请求和响应报文都经由director;
4)、支持端口映射;
这种模式就像DNAT,它通过同时修改请求报文的源IP地址和目标IP地址进行转发,另外此模式还不是正式版本,需要在官方网站下周源码,编译系统内核才能使用。
[root@DR ~]# ip a
1: lo: mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet 192.168.159.250/32 scope global lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eno16777736: mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:2e:bc:ec brd ff:ff:ff:ff:ff:ff
inet 192.168.159.136/24 brd 192.168.159.255 scope global dynamic eno16777736
valid_lft 1695sec preferred_lft 1695sec
inet6 fe80::20c:29ff:fe2e:bcec/64 scope link
valid_lft forever preferred_lft forever
[root@DR ~]# ip addr add 192.168.159.250 dev lo
[root@DR ~]# ip a
1: lo: mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet 192.168.159.250/32 scope global lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:be:2f:65 brd ff:ff:ff:ff:ff:ff
inet 192.168.159.135/24 brd 192.168.159.255 scope global dynamic ens33
valid_lft 1036sec preferred_lft 1036sec
inet6 fe80::20c:29ff:febe:2f65/64 scope link
valid_lft forever preferred_lft forever
[root@DR ~]# ping 192.168.159.250
PING 192.168.159.250 (192.168.159.250) 56(84) bytes of data.
64 bytes from 192.168.159.250: icmp_seq=1 ttl=64 time=0.015 ms
64 bytes from 192.168.159.250: icmp_seq=2 ttl=64 time=0.016 ms
64 bytes from 192.168.159.250: icmp_seq=3 ttl=64 time=0.024 ms
64 bytes from 192.168.159.250: icmp_seq=4 ttl=64 time=0.021 ms
^C
--- 192.168.159.250 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2999ms
rtt min/avg/max/mdev = 0.015/0.019/0.024/0.003 ms
RS1
[root@RS1 ~]# ip a
1: lo: mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet 192.168.159.250/32 scope global lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eno16777736: mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:4a:7e:86 brd ff:ff:ff:ff:ff:ff
inet 192.168.159.132/24 brd 192.168.159.255 scope global dynamic eno16777736
valid_lft 1626sec preferred_lft 1626sec
inet6 fe80::20c:29ff:fe4a:7e86/64 scope link
valid_lft forever preferred_lft forever
RS2
[root@RS2 ~]# ip a
1: lo: mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet 192.168.159.250/32 scope global lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eno16777736: mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:2e:bc:ec brd ff:ff:ff:ff:ff:ff
inet 192.168.159.136/24 brd 192.168.159.255 scope global dynamic eno16777736
valid_lft 1695sec preferred_lft 1695sec
inet6 fe80::20c:29ff:fe2e:bcec/64 scope link
valid_lft forever preferred_lft forever
RS1
[root@RS1 ~]# vim /etc/sysctl.conf
[root@RS1 ~]# sysctl -p
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
[root@RS1 ~]# ip addr add 192.168.159.250/32 dev lo
[root@RS1 ~]# ip a
1: lo: mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet 192.168.159.250/32 scope global lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eno16777736: mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:4a:7e:86 brd ff:ff:ff:ff:ff:ff
inet 192.168.159.132/24 brd 192.168.159.255 scope global dynamic eno16777736
valid_lft 1643sec preferred_lft 1643sec
inet6 fe80::20c:29ff:fe4a:7e86/64 scope link
valid_lft forever preferred_lft forever
[root@RS1 ~]# ping 192.168.159.250
PING 192.168.159.250 (192.168.159.250) 56(84) bytes of data.
64 bytes from 192.168.159.250: icmp_seq=1 ttl=64 time=0.048 ms
64 bytes from 192.168.159.250: icmp_seq=2 ttl=64 time=0.082 ms
64 bytes from 192.168.159.250: icmp_seq=3 ttl=64 time=0.084 ms
64 bytes from 192.168.159.250: icmp_seq=4 ttl=64 time=0.117 ms
^C
--- 192.168.159.250 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3002ms
rtt min/avg/max/mdev = 0.048/0.082/0.117/0.026 ms
RS2
[root@RS2 ~]# vim /etc/sysctl.conf
[root@RS2 ~]# sysctl -p
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
[root@RS2 ~]# ip addr add 192.168.159.250/32 dev lo
[root@RS2 ~]# route add -host 192.168.159.250/32 dev lo
[root@RS2 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.159.2 0.0.0.0 UG 100 0 0 eno16777736
192.168.159.0 0.0.0.0 255.255.255.0 U 100 0 0 eno16777736
192.168.159.250 0.0.0.0 255.255.255.255 UH 0 0 0 lo
//安装net-tools
DR
[root@DR ~]# route add -host 192.168.159.250/32 dev lo
[root@DR ~]#
RS1
[root@RS1 ~]# route add -host 192.168.159.250/32 dev lo
[root@RS1 ~]#
RS2
[root@RS2 ~]# route add -host 192.168.159.250/32 dev lo
[root@RS2 ~]#
[root@DR ~]# ipvsadm -A -t 192.168.159.250:80 -s wrr
[root@DR ~]# ipvsadm -a -t 192.168.159.250:80 -r 192.168.159.132:80 -g
[root@DR ~]# ipvsadm -a -t 192.168.159.250:80 -r 192.168.159.136:80 -g
[root@DR ~]# ipvsadm -S > /etc/sysconfig/ipvsadm
[root@DR ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.159.250:80 wrr
-> 192.168.159.132:80 Route 1 0 0
-> 192.168.159.136:80 Route 1 0 0