LVS笔记
LVS (Linux Virtual Server)
LVS要达到的目标是通过LVS提供的负载均衡技术和Linux操作系统实现一个高性能,高可用的服务器群集。使用LVS架设的服务器集群系统有三个部分组成:最前端的负载均衡层(Loader Balancer),中间的服务器群组层,用Server Array表示,最底层的数据共享存储层,用Shared Storage表示。在用户看来所有的应用都是透明的,用户只是在使用同一个服务器提供的服务。
基本工作原理
- 用户向负载均衡调度器(Director Server)发起请求,调度器将请求发往至内核空间
- PREROUTING链首先会接收到用户请求,判断目标IP确定是本机IP,将数据包发往INPUT链
- IPVS是工作在INPUT链上的,当用户请求到达INPUT时,IPVS会将用户请求和自己已定义好的集群服务进行比对,如果用户请求的就是定义的集群服务,那么此时IPVS会强行修改数据包里的目标IP地址及端口,并将新的数据包发往POSTROUTING链
- POSTROUTING链接收数据包后发现目标IP地址刚好是自己的后端服务器,那么此时通过选路,将数据包最终发送给后端的服务器
其实企业中最常用的是 DR 实现方式,而 NAT 配置上比较简单和方便,后续实践中会总结 DR 和 NAT 具体使用配置过程
缩写说明
- DS:Director Server。指的是前端负载均衡器节点。
- RS:Real Server。后端真实的工作服务器。
- VIP:向外部直接面向用户请求,作为用户请求的目标的IP地址。
- DIP:Director Server IP,主要用于和内部主机通讯的IP地址。
- RIP:Real Server IP,后端服务器的IP地址。
- CIP:Client IP,访问客户端的IP地址
- IPVS: IP Virtual Server
三种工作模式
1. NAT(网络地址转换)模式
NAT(Network Address Translation)是一种外网和内网地址映射的技术。每台Real Server的网关将是LVS服务器的地址,用户请求的数据进出都要经过LVS(所以它容易成为瓶颈)。当LVS服务器收到用户请求时会进行目标地址转换(DNAT),将请求IP修改为后端Real Server的IP,此时客户端IP不变,目标IP是VIP。Real Server响应用户请求时,需要再让LVS做源地址转换(SNAT),将返回的数据包源地址改为VIP。此时目标IP是客户端IP,而源IP是VIP,可以正常响应客户端请求。而对客户端来说仿佛是LVS进行的响应,无法感知到后端Real Server的存在。
2. DR(直接路由)模式
客户端请求依然由LVS接受,但是最终数据包由Real Server传输给用户,不再经过LVS转发,避免了NAT模式的瓶颈问题。DR模式的工作过程比较复杂:
当用户发起请求时,源地址是客户端IP,目标地址是VIP;而LVS调度器将请求转发给Real Server处理后再发送给用户,这个时候源IP是RIP,目标地址是客户端IP,但是客户端一开始并没有请求RIP,而用RIP去响应请求时CIP是不会接受的,所以就需要用VIP响应请求。在DR模式下LVS和Real server都需要配备一样的VIP(VIP的MAC地址和物理网卡是一样的)(Real Server通过将VIP绑定在loopback实现)。由于一个网段内多台服务器出现同样IP地址会引起冲突,所以要在LVS服务器上设置一个VIP一个DIP,而每个Real Server也有一个RIP和一个VIP,并且将Real Server的VIP地址做了隐藏和ARP抑制,不会应答广播,只在响应CIP时作为源地址使用。当产生请求时LVS将目标MAC地址修改为某台Real Server的MAC,该包就会被转发到相应的Real Server处理,此时源IP和目标IP都没变。Real Server收到LVS转发来的包时发现MAC是自己的,IP也是自己的,于是这个包被合法地接受。当Real Server返回响应时,只要直接向CIP返回即可,不再经过LVS。
数据包路径
- 当用户请求到达Director Server,此时请求的数据报文会先到内核空间的PREROUTING链。 此时报文的源IP为CIP,目标IP为VIP
- PREROUTING检查发现数据包的目标IP是本机,将数据包送至INPUT链
- IPVS比对数据包请求的服务是否为集群服务,若是,将请求报文中的源MAC地址修改为DIP的MAC地址,将目标MAC地址修改RIP的MAC地址,然后将数据包发至POSTROUTING链。此时的源IP和目的IP均未修改,仅修改了源MAC地址为DIP的MAC地址,目标MAC地址为RIP的MAC地址
- 由于DS和RS在同一个网络中,所以是通过二层来传输。POSTROUTING链检查目标MAC地址为RIP的MAC地址,那么此时数据包将会发至Real Server。
- RS发现请求报文的MAC地址是自己的MAC地址,就接收此报文。处理完成之后,将响应报文通过lo接口传送给eth0网卡然后向外发出。 此时的源IP地址为VIP,目标IP为CIP
- 响应报文最终送达至客户端
LVS-DR模式的特性
- 确保前端路由器将目标IP为VIP的请求报文发往Director:
- 在前端网关做静态绑定;
- 在RS上使用arptables;
- 在RS上修改内核参数以限制arp通告及应答级别;
- 修改RS上内核参数(arp_ignore和arp_announce)将RS上的VIP配置在lo接口的别名上,并限制其不能响应对VIP地址解析请求。
- RS的RIP可以使用私网地址,也可以是公网地址;RIP与DIP在同一IP网络;RIP的网关不能指向DIP,以确保响应报文不会经由Director;
- RS跟Director要在同一个物理网络;
- 请求报文要经由Director,但响应不能经由Director,而是由RS直接发往Client;
- 不支持端口映射;
- RS和DS必须在同一机房中
3. TUN隧道模式
LVS-Tun is an LVS original. It is based on LVS-DR. The LVS code encapsulates the original packet (CIP->VIP) inside an ipip packet of DIP->RIP, which is then put into the OUTPUT chain, where it is routed to the realserver. The realserver receives the packet on a tunl0 device and decapsulates the ipip packet, revealing the original CIP->VIP packet.
This is the less used method used in production environment.
安装工具 ipvsadm
1. 使用yum安装
yum install ipvsadmin
2. 使用ipvsadm进行管理,用法类似iptables
ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]] [-M netmask]
ipvsadm -D -t|u|f service-address
ipvsadm -C
ipvsadm -R
ipvsadm -S [-n]
ipvsadm -a|e -t|u|f service-address -r server-address [-g|i|m] [-w weight] [-x upper] [-y lower]
ipvsadm -d -t|u|f service-address -r server-address
ipvsadm -L|l [options]
#命令示例
ipvsadm -A -t 207.175.44.110:80 -s rr #给LVS服务器增加一个VIP,算法为rr模式
ipvsadm -a -t 207.175.44.110:80 -r 192.168.10.1:80 -m -w 1 #为VIP增加一个真实服务器的ip地址,并采用nat工作模式,权重为1
ipvsadm -a -t 207.175.44.110:80 -r 192.168.10.3:80 -m -w 2 #为VIP增加一个真实服务器的ip地址,并采用nat工作模式,权重为2
选项说明
-A:增加LVS的VIP记录
-a:增加real server记录
-E:修改LVS记录
-e:修改real server列表信息
-D:删除一条LVS记录
-d:删除real server列表信息
-R:恢复虚拟服务器规则
-S:保存虚拟服务器规则,或者service ipvsadm save,和iptables一样
-C:清除虚拟服务器列表所有记录
-L:显示列表信息,和iptables一样
-t | u:指定LVS提供tcp或者是udp服务,后面常跟选项 real-server-ip:port或者virtual-server-ip:port
-s:指定LVS的负载调度算法,后面接详细的调度算法,如-s rr | wrr | lc | wlc,不指定的话默认是wlc
-m LVS-NAT方式
-g LVS-DR方式
-i LVS-TUN方式
#保存规则
ipvsadm -Sn > /root/lvsrules.txt
#恢复规则
cat /root/lvsrules.txt | ipvsadm -R
DR(Direct Routing)直接路由模式搭建
https://docs.huihoo.com/hpc-cluster/linux-virtual-server/HOWTO/LVS-HOWTO.LVS-DR.html
https://blog.csdn.net/weixin_46074899/article/details/107850042
过程
Client发送请求 --> DS(调度器) -->prerouting --> INPUT -->postrouting -->RS(Real Server)–>lo --> 网卡eth0 -->Client
用户(client)发送请求给调度器(DS),DS调度器先把请求发往prerouting链(内核空间kernal space),确定请求的是不是VIP;到了INPUT链之后,如果请求的是集群服务,会在这里修改MAC地址,把源MAC地址改为DS的MAC地址,把目的MAC地址改为RS的MAC地址,此时IP仍然不变,处理完成后把请求发往postrouting链;postrouting链检测请求的是否为RS(会检测请求的MAC地址),如果是,接受请求,把请求通过回环接口发给出口的网卡,再发回给客户端。
部署前提
- 需要3台虚拟机:sever1 sever2 sever3
- server1作为lvs调度器
- server2和server3作为后端服务器
1. 在server2和server3中安装apache,做好测试页,以方便检测效果
yum install httpd -y
cd /var/www/html/
vim index.html
cat index.html ##分别写入vm2和vm3
2. 配置ipvsadm
在server1中
yum install ipvsadm -y
# 查看策略, -n 不解析(速度快)
ipvsadm -ln
# 添加策略:tcp,172.25.10.100的80端口访问,以轮询的调度算法
ipvsadm -A -t 172.25.10.100:80 -s rr
# 添加策略:tcp,172.25.254.100的80端口访问,以轮询的调度算法,使用DR模式转发到172.25.254.2的80端口
ipvsadm -a -t 172.25.10.100:80 -r 172.25.10.2:80 -g
# 添加策略:tcp,172.25.254.100的80端口访问,以轮询的调度算法,使用DR模式转发到172.25.254.3的80端口
ipvsadm -a -t 172.25.10.100:80 -r 172.25.10.3:80 -g
# 检查
ipvsadm -ln
3. 添加VIP
在server1、server2、server3中分别添加VIP地址
# 添加VIP地址到eth0上
ip addr add 172.25.10.100/24 dev eth0
# 检查
ip addr show
4. 测试
在客户端(真机)中:
curl 172.25.10.100
用上面的方法配置lvs,server1、server2、server3都有可能被访问到
- 如果绑定的MAC地址是server1,则在server2和3中轮询
- 如果绑定的MAC地址是sever2或sever3的,那么我们会发现,在测试端根本不会形成轮询,而是直接去了MAC绑定的后端服务器(显然这样是不允许的)
绑定的MAC地址是server1
# 查看绑定的MAC地址
arp -an
# 查询server1的地址,与server1的MAC地址一致
经ip addr show
# 在真机中执行, 观察在server2和server3中轮询
curl 172.25.10.100
绑定的MAC地址是server2 (或server3)
# 删除现有绑定的MAC地址
arp -d 172.25.10.100
# 查看绑定的MAC地址
arp -an
# 查询server2的地址,假定与server2的MAC地址一致
ip addr show
# 在真机中执行, 观察仅请求server2
curl 172.25.10.100
5. 解决方法
为避免以上情况, 只能绑定server1的MAC地址, 配置server2和server3的arp路由策略为arptables网络的用户控制过滤的守护进程.
在server2中
# 安装arptables
yum whatprovides arptables/*
yum install arptables-0.0.4-8.el7.x86_64 -y
# 当网内广播需要172.25.10.100这个ip时,它丢弃所有网内的请求
arptables -A INPUT -d 172.25.10.100 -j DROP
# 当它自身需要在网内发包时,伪装为自己原本的ip 172.25.254.2
arptables -A OUTPUT -s 172.25.10.100 -j mangle --mangle-ip-s 172.25.254.2
同样在server3中
# 安装arptables
yum whatprovides arptables/*
yum install arptables-0.0.4-8.el7.x86_64 -y
# 当网内广播需要172.25.254.100这个ip时,它丢弃所有网内的请求
arptables -A INPUT -d 172.25.10.100 -j DROP
# 当它自身需要在网内发包时,伪装为自己原本的ip172.25.254.3
arptables -A OUTPUT -s 172.25.10.100 -j mangle --mangle-ip-s 172.25.254.3
6. 测试
在真机中
# 删除现有绑定MAC地址
arp -d 172.25.10.100
# 反复执行此命令,观察server2和server3的轮询
curl 172.25.10.100
# 对比对应的mac
arp -an
在server1上
# 查看策略
[root@server1 ~]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.25.18.100:80 rr
-> 172.25.18.2:80 Route 1 0 2
-> 172.25.18.3:80 Route 1 0 3
LVS性能
https://docs.huihoo.com/hpc-cluster/linux-virtual-server/HOWTO/LVS-HOWTO.performance.html
关于DR模式的性能, 在 https://docs.huihoo.com/hpc-cluster/linux-virtual-server/HOWTO/LVS-HOWTO.LVS-DR.html 上有这样的说明
Francois JEANMOUGIN Francois (dot) JEANMOUGIN (at) 123multimedia (dot) com 06/06/2005
I have 38 realservers behind my director, incoming traffic (to director) goes up to 20Mb/s, outgoing (from realservers LVS-DR setup) up to 60Mb/s. I have about 1200 sites hosted. 36 virtual_server entries in keepalived.conf, 30 VIPs. There's no noticable load on the poor PIII/700 director that's handling the traffic.
However we have since realised that network hardware is specified in packets/sec and not Mbps (see 8000pps) and that every outgoing packet from a realserver is matched by an incoming packet to the director (possibly just an