一、DR模式集群
在TUN模式下,由于需要在LVS与真实服务器之间创建隧道连接,这样会增加服务器的负担。
与TUN模式类似,在DR模式中LVS依然只承担数据的入站请求,并且根据算法选择出合适的真实服务器,最终有后端真实服务器负责将响应数据包发送给客户端。
但是与隧道模式不同的是,DR模式中要求调度器与后端服务器必须在同一个局域网内,VIP地址也需要在调度器与后端所有的服务器间共享,因为最终的真实服务器给客户端回应数据包时需要设置源地址为VIP的地址,目标地址为为客户端的IP地址,这样客户端访问的是LVS调度器的VIP地址,回应的源地址也依然是VIP地址,客户端是感觉不到后端服务器的存在的,由于多台计算机都设置了同样一个VIP地址,所以在DR模式中要求调度器的VIP地址对外是可见的,客户端需要讲请求数据包发送到调度器主机,也就是LVS,而所有的真实服务器的VIP地址必须配置在Non-ARP的网络设备上,也就是该网络设备并不会向外广播自己的MAC及对应的IP地址,真实服务器的VIP对外是不可见的,但是真实服务器却可以接受目标地址为VIP的网络请求,并在回应数据包时将源地址设置为该VIP地址,LVS根据算法选出真实服务器后,在不修改数据报文的情况下,将数据帧的MAC地址修改为选择出的真实服务器的MAC地址,通过交换机将该数据帧发给真实服务器。整个过程中,真实服务器的VIP不需要对外可见
工作原理
基于直接路由来实现。当用户请求到达Director(负载均衡)之后,Director(负载均衡)将请求报文的目标地址(即VIP)改成选定的RS(真实服务器)地址,还要改写请求报文的mac地址,将请求发送到指定mac的RS(真实服务器),而RS(真实服务器)将响应直接返回给客户端,不经过Director(负载均衡)。这个方式是三种调度中性能最好的,也是我们生产环境中使用最多的。
特点:
- 1、集群节点和Director(负载均衡)必须在一个物理网络内
- 2、RIP可以使用公网地址或私有地址
- 3、Director(负载均衡)仅处理入站请求
- 4、集群节点网关不指向Director(负载均衡),故出站不经过Director(负载均衡)
- 5、不支持端口映射
- 6、大多数操作系统可以作为RS(真实服务器),要支持隔离arp广播
- 7、Director(负载均衡)服务器的压力比较小
优点:VS/DR跟VS/TUN方法相同,负载调度器中只负责调度请求,而服务器直接将响应返回给客户,可以极大地提高整个集群系统的吞吐量。
缺点: 要求负载均衡器的网卡必须与RS物理网卡在一个物理段上
二、实战案例
案例需求
部署基于LVS DR模式的web集群
实验环境
五台安装CentOS7的虚拟机一台测试机,一台LVS分发器,一台路由器,两台web服务器
注意事项
- 关闭selinux
- 关闭防火墙
- 停止libvirtd.service服务
实验拓扑图
实验机器
角色 | 接口和IP |
---|---|
client | ens33=192.168.1.200 |
route | ens33=192.168.1.1;ens160=192.168.2.1 |
LVS | ens33=192.168.2.200;ens37=192.168.2.100(VIP) |
RS1&RS2 | ens33=192.168.2.210&220;lo:0=192.168.2.100(VIP) |
实验步骤
a、配置路由,开启转发
ens33=192.168.1.1
ens160=192.168.2.1
[root@route ~]# echo 1 > /proc/sys/net/ipv4/ip_forward
c、配置客户端
ens33=192.168.1.200
[root@client ~]# route add default gw 192.168.1.1
c、LVS负载均衡器设置
ens33=192.168.2.200
ens37=192.168.2.100(VIP)
[root@lvs ~]# route add default gw 192.168.2.1
[root@lvs ~]# ipvsadm -A -t 192.168.2.100:80 -s rr
[root@lvs ~]# ipvsadm -a -t 192.168.2.100:80 -r 192.168.2.220:80 -g
[root@lvs ~]# ipvsadm -a -t 192.168.2.100:80 -r 192.168.2.210:80 -g
d、RS1&RS2设置
RS1=192.168.2.220
RS2=192.168.2.210
添加VIP并设置网关,调整内核参数
RS1
[root@rs1 ~]# route add default gw 192.168.2.1
[root@rs1 ~]# ifconfig lo:0 192.168.2.100 netmask 255.255.255.255 up
[root@rs1 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@rs1 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
RS2
[root@rs2 ~]# route add default gw 192.168.2.1
[root@rs2 ~]# ifconfig lo:0 192.168.2.100 netmask 255.255.255.255 up
[root@rs2 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@rs2 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
安装web服务,生成测试页面
RS1
[root@rs1 ~]# dnf install httpd -y
[root@rs1 ~]# echo "rs1" > /var/www/html/index.html
[root@rs1 ~]# systemctl start httpd.service
RS2
[root@rs2 ~]# dnf install httpd -y
[root@rs2 ~]# echo "rs2" > /var/www/html/index.html
[root@rs2 ~]# systemctl start httpd.service
e、客户端测试
[root@client ~]# elinks http://192.168.2.100 --dump
rs2
[root@client ~]# elinks http://192.168.2.100 --dump
rs1
[root@client ~]# elinks http://192.168.2.100 --dump
rs2
[root@client ~]# elinks http://192.168.2.100 --dump
rs1
三、部署中的问题
我们知道,每台主机都有一个arp表,这个arp表记录了已知主机的IP地址和对应的mac地址,计算机在进行数据包封装的时候,会读取这个表当中的内容,做为封装数据包的依据,比如说我要给192.168.1.100这台主机发送一个数据包,现在我知道这台主机的IP地址了,但是它的mac地址是多少呢?这就需要查看arp表当中的记录,如果查看到了就直接使用192.168.1.100以及对应的mac地址做为数据包的目的地,但是如果查看不到,计算机就会发送arp广播,在网络上去询问“192.168.1.100你的mac地址是多少?我是xxx,这是我的mac地址”,一旦对方主机给予回应了,双方就会将对应的信息记录到自己的arp表中,以便于下次使用,而我们知道不管是在DR模式还是在tun模式当中所有的主机都配置了一个叫VIP的东西,那么以我们下面的这个架构图为例
当路由器(192.168.2.1)发送arp广播询问谁是192.168.2.100的时候就会出现一个问题,我们期望的是RIP=192.168.2.2的这台分发器去响应这个arp广播,这样路由器才能把客户端的请求包正确的发送给分发器,分发器再去根据自己的算法将请求分配给RS,也就是RIP为2.3和2.4的主机,但是如果是RS去响应这个arp的话,那么数据包就不能按照我们预想的去传递,所以在DR模式和TUN模式中我们要抑制RS主机针对于VIP的arp响应,同时我们还要告诉RS主机在发送arp广播时,不允许使用VIP去声明自己,这就需要我们通过调整内核参数来实现
arp_ignore 控制系统在收到外部的arp请求时,如何响应。常用的取值主要有0,1,2,3~8较少用到:
0:响应任意网卡上接收到的对本机IP地址的arp请求(包括环回网卡上的地址),而不管该目的IP是否在接收网卡上。
1:只响应目的IP地址为接收网卡上的本地地址的arp请求。
2:只响应目的IP地址为接收网卡上的本地地址的arp请求,并且arp请求的源IP必须和接收网卡同网段。
由于在DR$TUN模式中我们RS的VIP都不是绑定在实体网卡上,所以我们要使用1这个值来抑制RS主机的arp响应
arp_announce 控制系统在对外发送arp请求时,如何选择arp请求数据包的源IP地址。常用的取值有0,1,2。
0:允许使用任意网卡上的IP地址作为arp请求的源IP
1:尽量避免使用不属于该发送网卡子网的本地地址作为发送arp请求的源IP地址。也就是说,比如我的主机有两个IP地址,一个是1.100,一个是2.100,但是我发现我需要给2.200这台主机发送一个数据包,那此时如果需要发送arp请求的话呢我就要尽量使用2.100去声明我自己,而尽量去避免使用1.100去声明自己;但是如果我需要给3.200这台主机发送数据包呢?那就会使用2这个级别
2:忽略IP数据包的源IP地址,选择该发送网卡上最合适的本地地址作为arp请求的源IP地址。同样使用上面的例子如果给3.200发送数据包的话,你的主机发现自己用哪个IP地址去声明自己都不合适,你的主机就会查看一下路由记录,如果路由记录告诉你的主机发往3网段的数据包都要交给1.1这个网关,那你的主机就会使用1.100去声明自己,如果是交给2.1这个网关的话,你的主机就会使用2.100去声明自己。这就是所谓的最合适的
由于在DR$TUN模式中我们RS的VIP都不是绑定在实体网卡上,而实体网卡以及响应的设置信息,才是最合适的,我们就要使用2这个值来控制RS主机如何发送arp请求
同样由于CentOS8默认开启了反向路由校验功能,会影响TUN模式的运行,所以我们还要关闭这个功能,所谓反向路由校验,就是在一个网卡收到数据包后,把源地址和目标地址对调后查找路由出口,从而得到反转后路由出口。然后根据反向路由出口进行过滤,简单来说就是开了这个功能数据包就只能从进入的接口出去。而这个功能我们需要调整另外一个内核参数来实现
arp_filter
0:关闭反向路由校验
1:开启严格的反向路由校验。对每个进来的数据包,校验其反向路由是否是最佳路由。如果反向路由不是最佳路由,则直接丢弃该数据包。
2:开启松散的反向路由校验。对每个进来的数据包,校验其源地址是否可达,即反向路由是否能通(通过任意网口),如果反向路径不通,则直接丢弃该数据包。