LVS(Linux Virtual Server)即Linux虚拟服务器,是由章文嵩博士主导的开源负载均衡项目,目前LVS已经被集成Linux内核模块中。该项目在Linux内核中实现了基于IP的数据请求负载均衡调度方案,终端互联网用户从外部访问公司的外部负载均衡服务器,终端用户的Web请求会发送给LVS调度器,调度器根据自己预设的算法决定将该请求发送给后端的某台Web服务器,比如,轮询算法可以将外部的请求平均分发给后端的所有服务器。根据LVS工作模式的不同,真实服务器会选择不同的方式将用户需要的数据发送到终端用户,LVS工作模式分为NAT模式、TUN模式、以及DR模式。
LVS负载均衡调度技术是在LINUX内核中实现的,因此被称之为LINUX虚拟服务器。我们使用该软件配置LVS时候,不能直接配置内核中的IPVS,而需要使用IPVS的管理工具ipvsadm进行管理,当然我们也可以通过keepalived软件直接管理IPVS,并不是通过ipvsadm来管理ipvs。
小结:
a.真正实现调度的工具是IPVS,工作在LINUX内核层面。
b.LVS自带的IPVS管理工具是ipvsadm(工作在用户空间,负责为ipvs内核框架编写规则)。
c.keepalived实现管理IPVS及负载均衡器的高可用。
ipvsadm(工作在用户空间的命令行工具;写具体的规则;用于管理集群服务) / ipvs(工作在内核中的netfilter input钩子函数上)
LVS术语解释:
用直接路由技术实现虚拟服务器,调度器根据算法在选出真实服务器后,在不修改数据报文的情况下,将数据帧的MAC地址修改为选出的真实服务器的MAC地址,通过交换机将该数据帧发给真实服务器
要求Director Server与Real Server都有一块网卡连在同一物理网段上。
如上图:
a.当用户请求到达Director Server,此时请求的数据报文会先到内核空间的PREROUTING链。 此时报文的源IP为CIP,目标IP为VIP
b.PREROUTING检查发现数据包的目标IP是本机,将数据包送至INPUT链
c.IPVS比对数据包请求的服务是否为集群服务,若是,将请求报文中的源MAC地址修改为DIP的MAC地址,将目标MAC地址修改RIP的MAC地址,然后将数据包发至POSTROUTING链。 此时的源IP和目的IP均未修改,仅修改了源MAC地址为DIP的MAC地址,目标MAC地址为RIP的MAC地址
d.由于DS和RS在同一个网络中,所以是通过二层来传输。POSTROUTING链检查目标MAC地址为RIP的MAC地址,那么此时数据包将会发至Real Server。
e.RS发现请求报文的MAC地址是自己的MAC地址,就接收此报文。处理完成之后,将响应报文通过lo接口传送给eth0网卡然后向外发出。 此时的源IP地址为VIP,目标IP为CIP
f.响应报文最终送达至客户端
主机名 | ip | 服务 |
---|---|---|
lvs1 | 172.25.254.1 | ipvsadm |
lvs2 | 172.25.254.2 | apache |
lvs3 | 172.25.254.3 | apache |
1.在虚拟服务器lvs1上配置更高级的yum源(因为一般的配置只能获得基础的包,不能获得ipvsadm)
[root@lvs1 ~]# cd /etc/yum.repos.d/
[root@lvs1 yum.repos.d]# vim rhel-source.repo
1 [rhel-source]
2 name=Red Hat Enterprise Linux $releasever - $basearch - Source
3 baseurl=http://172.25.254.73/rhel6.5/
4 enabled=1
5 gpgcheck=0
6 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
7
8 [LoadBalancer]
9 name=Red Hat Enterprise Linux $releasever - $basearch - Source
10 baseurl=http://172.25.254.73/rhel6.5/LoadBalancer
11 enabled=1
12 gpgcheck=0
13 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
[root@lvs1 yum.repos.d]# yum clean all
[root@lvs1 yum.repos.d]# yum repolist
注意:lvs2和lvs3的yum源相同
2.在虚拟服务器lvs1上安装ipvsadm调度器,并查看调度器的规则策略和调度次数
[root@lvs1 ~]# yum install ipvsadm -y
[root@lvs1 ~]# ipvsadm -l
[root@lvs1 ~]# ipvsadm -nl #不解析
3.查看内核模块、查看编写策略
[root@lvs1 ~]# lsmod
[root@lvs1 ~]# lsmod | grep ip_vs
4.添加VIP(给所有的服务器把VIP配置到各自的NonARP网络设备上)
[root@lvs1 ~]# ip addr add 172.25.254.100/24 dev eth0
[root@lvs1 ~]# ip addr show
[root@lvs2 ~]# ip addr add 172.25.254.100/32 dev eth0
[root@lvs2 ~]# ip addr show
[root@lvs3 ~]# ip addr add 172.25.254.100/32 dev eth0
[root@lvs3 ~]# ip addr show
5.添加策略并保存
[root@lvs1 ~]# ipvsadm -A -t 172.25.254.100:80 -s rr #添加一台虚拟设备
[root@lvs1 ~]# ipvsadm -a -t 172.25.254.100:80 -r 172.25.254.2:80 -g #添加后端实际服务器
[root@lvs1 ~]# ipvsadm -a -t 172.25.254.100:80 -r 172.25.254.3:80 -g #添加后端实际服务器
[root@lvs1 ~]# ipvsadm -l
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.25.254.100:http rr
-> server2:http Route 1 0 0
-> server3:http Route 1 0 0
[root@lvs1 ~]# /etc/init.d/ipvsadm save
-A 增加一台虚拟设备
-a 添加真实服务器的操作
-t tcp服务地址
-s 调度算法(10中调度算法rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq)
-r 对应的真实ip
-g rh(路由)
rr 调度算法:轮询
6.给lvs2和lvs3安装apache服务,并编写默认发布页面,以便效果的查看
[root@lvs2 ~]# yum install httpd -y
[root@lvs2 ~]# cd /var/www/html/
[root@lvs2 html]# vim index.html
[root@lvs2 html]# cat index.html
lvs2
[root@lvs2 html]# /etc/init.d/httpd start
[root@lvs3 ~]# yum install httpd -y
[root@lvs3 ~]# cd /var/www/html/
[root@lvs3 html]# vim index.html
[root@lvs3 html]# cat index.html
lvs3
[root@lvs3 html]# /etc/init.d/httpd start
以上设定会产生随机访问情况,即lvs1、lvs2、lvs3都会被访问到(原因就是arp协议)
(因为当调度器执行询问时,后端服务器会随机产生应答,而且应答会保存在arptables里,下次直接从表格记录里面读取。)
当MAC地址绑定的是lvs1时,在lvs2和lvs3上采用轮询
当MAC地址绑定的是lvs2或者lvs3时,不采用轮询,直接访问MAC地址对应的后端服务器
[root@foundation73 ~]# curl 172.25.254.100
lvs3
[root@foundation73 ~]# curl 172.25.254.100
lvs3
[root@foundation73 ~]# curl 172.25.254.100
lvs3
[root@foundation73 ~]# arp -an | grep 100 #此时MAC绑定的是lvs3
? (172.25.254.100) at 52:54:00:06:0f:69 [ether] on br0
[root@foundation73 ~]# arp -d 172.25.254.100 #清除arptables记录
[root@foundation73 ~]# curl 172.25.254.100
lvs2
[root@foundation73 ~]# curl 172.25.254.100
lvs2
[root@foundation73 ~]# curl 172.25.254.100
lvs2
[root@foundation73 ~]# arp -an | grep 100 #此时MAC绑定的是lvs2
? (172.25.254.100) at 52:54:00:dd:44:49 [ether] on br0
[root@foundation73 ~]# arp -d 172.25.254.100
[root@foundation73 ~]# curl 172.25.254.100
lvs3
[root@foundation73 ~]# curl 172.25.254.100
lvs2
[root@foundation73 ~]# arp -an | grep 100 #此时MAC绑定的是lvs1
? (172.25.254.100) at 52:54:00:61:dd:0e [ether] on br0
在lvs2和lvs3上编写火墙策略,让调度器在执行询问172.25.254.100的时侯后端不予应答
1.安装arptables火墙策略,查看火墙策略
[root@lvs2 html]# yum search arptables
[root@lvs2 html]# yum install arptables_jf.x86_64 -y
[root@lvs2 html]# arptables -L
[root@lvs3 html]# yum search arptables
[root@lvs3 html]# yum install arptables_jf.x86_64 -y
[root@lvs3 html]# arptables -L
2.编写火墙策略并保存
[root@lvs2 html]# arptables -A IN -d 172.25.254.100 -j DROP #当网内广播需要172.25.254.100这个ip时,它丢弃所有网内的请求
[root@lvs2 html]# arptables -A OUT -s 172.25.254.100 -j mangle --mangle-ip-s 172.25.254.2 #当它自身需要在网内发包时,伪装为自己原本的ip172.25.254.2
[root@lvs2 html]# arptables -L
[root@lvs2 html]# /etc/init.d/arptables_jf save
[root@lvs2 html]# /etc/init.d/arptables_jf start
[root@lvs3 html]# arptables -A IN -d 172.25.254.100 -j DROP
[root@lvs3 html]# arptables -A OUT -s 172.25.254.100 -j mangle --mangle-ip-s 172.25.254.3
[root@lvs3 html]# arptables -L
[root@lvs3 html]# /etc/init.d/arptables_jf save
[root@lvs3 html]# /etc/init.d/arptables_jf start
先清除arptables的记录即删除绑定的MAC地址
[root@foundation73 ~]# arp -d 172.25.254.100
测试端再次进行测试,会发现数据经过调度器,实现轮询
[root@foundation73 ~]# curl 172.25.254.100
lvs2
[root@foundation73 ~]# curl 172.25.254.100
lvs3
[root@foundation73 ~]# curl 172.25.254.100
lvs2
[root@foundation73 ~]# curl 172.25.254.100
lvs3
[root@foundation73 ~]# curl 172.25.254.100
lvs2
[root@foundation73 ~]# curl 172.25.254.100
lvs3
[root@lvs1 ~]# ipvsadm -l
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.25.254.100:http rr
-> lvs2:http Route 1 0 3
-> lvs3:http Route 1 0 3