系列一文章简述了LVS常见的五种工做模式,接下来主要讲述LVS的工做原理
LVS负责四层均衡负载调度,当咱们要定义集群的调度规则时须要借助于一个管理工具,就是ipvsadm
。而ipvsadm
定义的规则最终是经过IPVS
来实现,也就是说ipvsadm
是IPVS
的管理工具,ipvsadm
工做于用户空间,IPVS
工做于内核空间,二者之间的关系比如iptables与netfliter。html
IPVS
支持TCP/UDP协议,会从TCP SYNC包开始为一个TCP链接全部的数据包创建状态跟踪机制,保证一个TCP链接中全部的数据包能到同一个后端。因此IPVS是基于TCP状态机进行控制管理,只感知TCP头而不对TCP的payload进行查看;所以,对IPVS后端服务器集群还有一个假定,那就是全部后端都具备一样的应用层的服务功能,可是因为IPVS能够给后端设定权重,因此每一个后端的服务的能力能够不一样。linux
`IPVS(IP Virtual Server)发展史:nginx
IPVS
就已经之内核补丁的形式出现。IPVS
软件就是合并到linux内核的经常使用版本的内核补丁的集合。IPVS
已经成为linux官方标准内核的一部分并做为Netfilter的一个模块存在当Client访问服务时,会访问VIP及其对应的端口,因此LVS接收到的请求报文首先通过PREROUTING链而后进行路由判断,因为此时的DIP为VIP,为设备IP(网卡接口上有配置)因此请求报文会通过INPUT链,此时若是IPVS
发现报文访问的VIP和端口与定义的规则相匹配,IPVS
会根据定义好的规则和算法将报文直接发往POSTROUTING链,最后报文会从LVS发出到达后端RS。算法
咱们以LVS的DR模式为例,安装好ipvsadm
后在调度机上执行如下命令后端
ipvsadm -A -t VIP:port -s rr ipvsadm -a -t VIP:port -r RIP1 -g ipvsadm -a -t VIP:port -r RIP2 -g //本案例中配置以下 //ipvsadm -A -t 192.168.0.100:80 -s rr //ipvsadm -a -t 192.168.0.100:80 -r 192.168.0.4 -g //ipvsadm -a -t 192.168.0.100:80 -r 192.168.0.5 -g
ipvsadm -A -t VIP:port -s rrcentos
-A 选项为添加一条虚拟服务器记录,即建立一个LVS集群
-t 标识建立的LVS集群服务为tcp协议,VIP:port 标识集群服务IP及端口号
-s Scheduling 调度之意,后面参数为指定的调度算法,有rr、wrr、lc、wlc、lblc、lblcr、dh、sh、sed、nq,默认为wlc,其中rr为Round-Robin缩写,表明轮询算法
因此在建立好一个LVS服务集群后,咱们须要设置具体的后端RS、调度算法等信息服务器
ipvsadm -a -t VIP:port -r RIP -g负载均衡
-a 选项表示添加一个RS到集群中
-t 同上
-r 用于指定须要添加的RIP(RS对应IP)
-g 表示LVS工做模式为DR模式,-i为TUN模式,-m为NAT模式curl
配置完后咱们经过 ipvsadm -Ln
查看生效的规则,但要注意一点,若是没有提早将规则进行保存,在设备重启后配置会消失,因此咱们配置完须要用 service ipvsadm save 保存命令,重启后用 service ipvsadm reload
从新载入规则。除此以外,能够用-S将LVS规则保存在指定文件中,经过-R进行重载tcp
ipvsadm -S > file ipvsadm -R < file
为模拟集群环境,咱们准备了四台虚拟机分别为客户端、LVS服务器、RealServer一、RealServer2
首先配置LVS,在yum安装ipvsadm
后,此时系统尚未把ipvs模块加载进系统,须要咱们执行ipvsadm命令才会加载进去或者modprobe ip_vs。
在配置完规则后,能够经过 ipvsadm -ln 查看已经生效的集群规则,固然为了重启继续使用目前配置的规则,能够-S 进行保存。
因为VIP须要绑定在LVS的网卡上并进行ARP广播(对于外部来讲,VIP对应设备就是LVS,对应的arp请求只能由LVS响应),咱们添加VIP 192.168.0.100/24 到 ens33:0上。
[root@LVS ~]# yum install ipvsadm -y [root@LVS ~]# lsmod | grep ip_vs [root@LVS ~]# //此时ipvsadm未启用 [root@LVS ~]# ipvsadm -A -t 192.168.0.100:80 -s rr [root@LVS ~]# ipvsadm -a -t 192.168.0.100:80 -r 192.168.0.4 -g [root@LVS ~]# ipvsadm -a -t 192.168.0.100:80 -r 192.168.0.5 -g [root@LVS ~]# lsmod | grep ip_vs ip_vs_rr 12600 1 ip_vs 145497 3 ip_vs_rr nf_conntrack 133095 7 ip_vs,nf_nat,nf_nat_ipv4,nf_nat_ipv6,xt_conntrack,nf_conntrack_ipv4,nf_conntrack_ipv6 libcrc32c 12644 4 xfs,ip_vs,nf_nat,nf_conntrack //ipvsadm已启用 [root@LVS ~]# 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.0.100:80 rr -> 192.168.0.4:80 Route 1 0 0 -> 192.168.0.5:80 Route 1 0 0 //ipvsadm规则生效 [root@LVS ~]# ifconfig ens33:0 192.168.0.100/32 up
首先部署好http服务,这边是采用nginx。因为接收数据包的目的IP为VIP,须要在lo上添加VIP,由于RS的VIP不是用来通信,这里必定要设置/32位掩码!
[root@RealServer1 ~]# rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm [root@RealServer1 ~]# yum install nginx -y [root@RealServer1 ~]# nginx //启动nginx [root@RealServer1 ~]# vi /usr/share/nginx/html/index.html //改成 RealServer1 192.168.0.4 [root@RealServer1 ~]# curl 127.0.0.1 RealServer1 192.168.0.4 //至此部署好了http服务 [root@RealServer1 ~]# ifconfig lo:0 192.168.0.100/32 up //将VIP添加到lo:0上,掩码为/32
到这里,会误觉得都已配置彻底、集群能够正常服务,但在Client实际测试的时候会发现ARP询问VIP时,LVS、RS一、RS2都会进行应答,致使均衡负载未生效。
[root@Client ~]# arping -I ens33 192.168.0.100 ARPING 192.168.0.100 from 192.168.0.3 ens33 Unicast reply from 192.168.0.100 [00:0C:29:AF:6B:F7] 1.778ms Unicast reply from 192.168.0.100 [00:0C:29:AC:67:31] 1.852ms Unicast reply from 192.168.0.100 [00:0C:29:BD:38:DA] 1.860ms Unicast reply from 192.168.0.100 [00:0C:29:BD:38:DA] 1.860ms Unicast reply from 192.168.0.100 [00:0C:29:BD:38:DA] 1.860ms //会发现有三个设备响应ARP请求,最终为 00:0C:29:BD:38:DA(RS1) [root@Client ~]# arping -I ens33 192.168.0.2 ARPING 192.168.0.2 from 192.168.0.3 ens33 Unicast reply from 192.168.0.2 [00:0C:29:AF:6B:F7] 1.500ms [root@Client ~]# arping -I ens33 192.168.0.4 ARPING 192.168.0.4 from 192.168.0.3 ens33 Unicast reply from 192.168.0.4 [00:0C:29:BD:38:DA] 1.609ms [root@Client ~]# arping -I ens33 192.168.0.5 ARPING 192.168.0.5 from 192.168.0.3 ens33 Unicast reply from 192.168.0.5 [00:0C:29:AC:67:31] 1.603ms //三台设备分别为LVS、RS一、RS2
由于RS的lo上已配置VIP,因为arp_ignore
默认为0,设备默会响应VIP对应的ARP请求。配置说明参考 Linux内核参数之arp_ignore和arp_announce
arp_ignore
arp_ignore
参数要求配置为1。arp_announce
arp_announce
参数要求配置为2。[root@RealServer1 ~]# echo "1">/proc/sys/net/ipv4/conf/all/arp_ignore [root@RealServer1 ~]# echo "1">/proc/sys/net/ipv4/conf/lo/arp_ignore [root@RealServer1 ~]# echo "2">/proc/sys/net/ipv4/conf/all/arp_announce [root@RealServer1 ~]# echo "2">/proc/sys/net/ipv4/conf/lo/arp_announce
配置完RealServer一、RealServer2的arp_ignore
、arp_announce
后,在Client上测试服务
[root@Client ~]# arping -I ens33 192.168.0.100 ARPING 192.168.0.100 from 192.168.0.3 ens33 Unicast reply from 192.168.0.100 [00:0C:29:AF:6B:F7] 1.301ms Unicast reply from 192.168.0.100 [00:0C:29:AF:6B:F7] 0.827ms Unicast reply from 192.168.0.100 [00:0C:29:AF:6B:F7] 0.887ms Unicast reply from 192.168.0.100 [00:0C:29:AF:6B:F7] 0.801ms //由LVS响应ARP请求 [root@Client ~]# curl 192.168.0.100 RealServer2 192.168.0.5 [root@Client ~]# curl 192.168.0.100 RealServer1 192.168.0.4 [root@Client ~]# curl 192.168.0.100 RealServer2 192.168.0.5 [root@Client ~]# curl 192.168.0.100 RealServer1 192.168.0.4 //由RealServer一、RealServer2 1:1 轮询响应请求
至此咱们手动配置好了一个最基础的DR-LVS集群,但缺点也很明显:
因此后续介绍keepalived-LVS集群来解决上述问题
参考文章
LVS 官方文档
ipvsadm命令详解
LVS的调度算法
Linux内核参数之arp_ignore和arp_announce