DR模式是通过改写请求报文的目标MAC地址,将请求发给服务器,服务器将响应处理结果直接返回客户端,可以极大提高集群的伸缩性,但要求调度器LB与节点服务器RS连接一个物理网段,必须在同一个局域网环境。
Lvs-dr的工作原理:Director(调度器)收到请求,将请求转发给了我们的realserver(服务器 ),但是接下来的工作就是我们的realserver和我们的客户端进行通讯,原理图如下:
1)MAC地址转换过程
例 场景设备清单:
2)client(客户端)基本信息:
IP:192.168.1.101向目标vip发出请求,Director接收此时IP包头及数据帧头信息如下:
souce mac(源mac)访问者,dest mac (目标mac地址)被访问者
3) Director分发器根据负载均衡算法选择一台active的realserver
(假设是192.168.1.62),将此RIP所在网卡的mac地址作为目标mac地址,发送到局域网里
4) realserver(192.168.1.62)在局域网中收到这个帧,拆开后发现目标IP(VIP)
与本地匹配,于是处理这个报文。随后重新封装报文,发送到局域网
5) 如果client与LVS同一网段,那么client(192.168.1.101)将收到这个回复报文。如果跨了网段,那么报文通过gateway/路由器经由Internet返回给用户。
归纳总结:
DR(Direct Routing 直接路由模式)此模式时LVS 调度器只接收客户发来的请求并将请求转发给后端服务器,后端服务器处理请求后直接把内容直接响应给客户,而不用再次经过LVS调度器
1)接收client的请求,根据你设定的负载均衡算法选取一台realserver的ip
2)以选取的这个ip对应的mac地址作为目标mac,然后重新将IP包封装成帧转发给这台RS
3)在hash table中记录连接信息
lvs-dr做的事情很少,也很简单,所以它的效率很高,不比硬件负载均衡设备差多少。数据包、数据帧的大致流向是这样的:client --> VS --> RS --> client
1.4 DR模式特点
保证路由将目标地址为VIP报文统统发给Director Server,而不是RS(解决方法:在路由器做静态地址路由绑定,将对于VIP的地址仅路由到Director Server)
RS可以使用私有IP,也可以是公网地址,如果使用公网地址,此时可以通过互联网对RIP进行直接访问
RS跟Director Server必须在同一个物理网络中
所有的请求报文经由Director Server,响应报文直接从所连接的节点直接响应给客户端,不经过调度器
不支持地址转换,也不支持端口映射
RS可以是大多数常见的操作系统
RS的网关绝不允许指向DIP(因为我们不允许他经过director)
RS上的 lo (回环网卡)接口配置VIP地址
缺陷:唯一的缺陷在于它要求LVS 调度器及所有应用服务器在同一个网段中,因此不能实现集群的跨网应用。
2.1实验拓扑图
三台虚拟机:
VIP(虚拟IP地址):192.168.30.200/24
其中director做负载调度器:
ens33:172.16.30.11/24 ens37: 192.168.30.11/2
WEB节点1(rs01): ens33: 172.16.30.12/24
WEB节点2(rs02): ens33: 172.16.30.13/24
注:关闭所有主机的防火墙和selinux
从lvs-dr模式来讲负载调度器ens33有2个IP地址,所以我们需要配置ens33和ens33:0(子接口)两个IP
DIP===ens33=== 172.16.30.11 VIP===ens33:0=== 192.168.
vim /etc/sysconfig/network-scripts/ifcfg-ens33
配置以下信息:
IPADDR= 192.168.30.11
NETMASK=255.255.255.0
cd /etc/sysconfig/network-scripts/
cp ifcfg-ens33 ifcfg-ens33:0
vim ifcfg-ens33:0
修改以下部分
NAME=ens33:0
DEVICE=ens33:0
IPADDR=192.168.30.200 #使用空闲IP不能被占用
PREFIX=24
重启网卡
systemctl restart network
查看是否有ens33和ens33:0
ifconfig
LVS现在已成为Linux内核的一部分,默认编译为ip_vs模块,必要时能够自动调用。以下操作可以手动加载ip_vs模块,并查看当前系统中ip_vs模块的版本信息
modprobe ip_vs #加载ip_vs模块
lsmod | grep ip_vs #查看已加载系统模块信息
安装 ipvsadm ipvs管理工具包
yum -y install ipvsadm
使用ipvsadm创建负载分配策略:
清除策略:清除内核虚拟服务器表中的所有记录
ipvsadm -C
创建ipvs规则:
创建虚拟服务器,集群的VIP地址为192.168.30.200,针对tcp 的 80端口提供负载分流服务,使用的调度算法为轮询(rr 代表轮循算法)
ipvsadm -A -t 192.168.30.200:80 -s rr
选项:
-A 创建集群
-t 指定 VIP地址及TCP端口
-s 指定调度算法 rr(轮询)、wrr(加权轮询)、lc (最少连接)、wlc(加权最少连接)
添加服务器节点:
ipvsadm -a -t 192.168.30.200:80 -r 192.168.30.12:80 -g -w 1
ipvsadm -a -t 192.168.30.200:80 -r 192.168.30.13:80 -g -w 1
选项:
-a 添加服务器的地址
-r 指定服务器的 IP 地址和端口
-g 表示route 也就是DR方式的LVS,(-m: NAT模式、-i:TUN模式)
-w 设置权重 (权重为0时表示暂停节点)
保存配置或规则:
要停止selinux,否则策略不会被保存
LVS的规则配置文件:/etc/sysconfig/ipvsadm
设置永久生效:
ipvsadm --save > /etc/sysconfig/ipvsadm #保存以上配置
当系统下次启动时会自动读取文件配置的规则
设置ipvsadm设置为开机自启:
systemctl enable ipvsadm --now #设置开启自启同时启动 ipvsadm
查看负载均衡策略:
ipvsadm -Ln
1)关闭APP转发(两台rs 操作一样)
同一个广播域: 配置了多个相同的VIP 是不允许的, 要想实现,就必须让外面的网络, 无法发现这个VIP的存在。因此在Linux里面, 可以修改内核参数, 实现接口IP的广播不响应、不广播
arp_ignore = 1 表示只回答目标 IP 是访问本地网络对应接口的arp请求
arp_announce = 2 只宣告本机网卡直连网络所在的ip的arp广播
临时生效:
echo 1 > /proc/sys/net/ipv4/conf/ens33/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/ens33/arp_announce
永久生效:(注意网卡名称)
vim /etc/sysctl.conf
在末尾添加以下信息
net.ipv4.conf.ens33.arp_ignore = 1
net.ipv4.conf.ens33.arp_announce = 2
使内核参数修改生效:
sysctl -p
arp_ignore 定义接收到 ARP 请求时的响应级别。
arp_ignore:定义了网卡在响应外部ARP请求时候的响应级别,即当ARP请求发过来后发现自己正是请求的地址是否响应
0:默认值,不管哪块网卡接收到了ARP请求,只要解析本机有这个MAC都给与响应
1:当一个主机有多块网卡,其中一块网卡接收到了ARP请求,发现所请求的MAC是本机另一块网卡的,这个时候接收到ARP请求的这块网卡就一定不响应,只有发现请求的MAC是自己的才给与响应
arp_announce 定义将自己地址向外通告时的通告级别
arp_announce: 的作用是控制系统在对外发送arp请求时,如何选择arp请求数据包的源IP地址
有三个值:
0:默认值,允许使用任意网卡的IP 地址作为 arp 请求源 IP
1: 尽量避免使用不属于该发送网卡子网的本地 地址作为发送arp请求的源IP地址
2: 选择该发送网卡上最合适的本地地址作为arp请求的源IP地址
arp_ignore和arp_announce参数示例:
1)当 arp_ignore参数配置为0时,eth1网卡上收到目的IP为环回网卡IP的arp请求,但是eth1也会返回arp响应,把自己的mac地址告诉对端
2) 当arp_ignore参数配置为1时,eth1网卡上收到目的IP为环回网卡IP的arp请求,发现请求的IP不是自己网卡上的IP,不会回arp响应
3)当arp_announce参数配置为0时,系统要发送的IP包源地址为eth1的地址,IP包目的地址根据路由表查询判断需要从eth2网卡发出,这时会先从eth2网卡发起一个arp请求,用于获取目的IP地址的MAC地址。该arp请求的源MAC自然是eth2网卡的MAC地址,但是源IP地址会选择eth1网卡的地址
4)当arp_announce参数配置为2时,eth2网卡发起arp请求时,源IP地址会选择eth2网卡自身的IP地址
生成回环配置文件;
cd /etc/sysconfig/network-scripts/
cp ifcfg-lo ifcfg-lo:0
vim ifcfg-lo:0
DEVICE=lo:0
IPADDR=192.168.30.200
NETMASK=255.255.255.255 #当子网掩码变成42位的时候就变成主机IP了
ONBOOT=yes
NAME=loopback
重启network 服务
systemctl restart network
ifconfig
第二台 sr02 服务器做同样操作
yum -y install httpd #安装apache
systemctl status httpd
echo "192.168.30.200" > /var/www/html/index.html
为了测试负载均衡,各个服务器的页面不同,可以先不挂载nfs共享存储
刷新浏览器:
注:测试时,不要在分发器上测试。那样测试是不行的
在LVS负载调度器中,通过查看节点状态可以观察当前的负载分配情况,对于轮询算法来说,每个节点所获得的连接负载应大致相当
[root@ds01 ~]# ipvsadm -Ln
LVS提供了source hashing,源地址hash(sh)算法,这样同一个ip的客户端总是分发给同一个real server
基于ip地址标识客户端的缺点:很多内网用户会伪装成公网ip,来访问服务器,不能人为的控制负载均衡
如果总是保持和一个RS会话,这台RS如果故障了,要确定另一个RS也有会话信息,所有的RS保持数据同步
会话保持同步的方法:
所有的RS把自己的会话信息保存到数据库当中(如memcached/redis软件)。