(1)客户端发送请求到 Director Server (负载均衡器),请求的数据报文(源IP地址是 CIP,目标IP地址是VIP)到达内核空间。
(2)Director Server 和 Real Server 在同一个网络中,数据通过二层数据链路层来传输。
(3)内空间判断数据包的目标IP地址是本机VIP,此时IPVS(IP拟服务器)比对包的务是否是集群服务,是集群服务就重新封装数据包。修改源 MAC 地址为 Directo Sertver 的MAC地址,修改目标 MAC 地址为 Real Server 的 MAC 地址,源IP地址与目标IP地址没有改变,
(4)到达 Real Server 的请求报文的 MA 地址是自身的 MAC 地址,就接收此报文。数据包重新封装报文(源IP地址为IP地址,目标 IP地址为 VIP)将响应报文通过 lo 接口传送给物理网卡,然后向外发出。
(5)Real server 直接将响应报文传送到客户端。
(1)Director server和 Real server必须在同一个物理网络中。
(2)Real Server可以使用私有地址,也可以使用公网地址。如果使用公网地址,可以通过互联网对RIP进行直接访问。
(3)Director server作为群集的访问入口,但不作为网关使用。
(4)所有的请求报文经由 Director server,但回复响应报文不能经过 Director server。
(5)Real server的网关不允许指向Director server IP,即Real Server发送的数据包不允许经过 Director Server。
(6)Real server 上的lo接口配置VIP 的IP地址。
问题描述
当公网中的用户发起请求发送至路由器中,此时肯定需要走的是负载均衡器这台服务器,而不是走的真实服务器1。
这里就会出现一个问题,因为内网在转发数据帧的时候即使用ARP(广播)来查询目标MAC地址的时候目标ip地址就是vip地址(即在DR负载均衡服务器那个集群中)。负载均衡服务器与节点服务器都要配置相同的vip地址,所以这里就会出现混乱。
如果此时ARP解析,解析的是真实服务器1,那么从外网中进来的业务请求就不会经过负载均衡器而是直接交给真实服务器,如此实现不了负载均衡的效果那么我们怎么解决呢?
解决方式
那么我们只需要让在ARP响应的时候真实服务器1不进行响应即可。使用虚接口lo:0承载VIP地址,设置内核参数arp_ipnore=1,系统请求只响应目的IP地址为本地IP地址的ARP请求。
RealServer返回报文(源IP地址是VIP地址)经过路由器转发,重新封装报文时,需要先获取路由器的MAC地址。发送ARP请求时,Linux,默认使用IP包的源IP地址(即VIP)作为ARPi请求包中的源IP地址,而不使用发送接口的IP地址(如:ens33接口)。
路由器收到ARP请求后,将更新ARP表项,原有的VIP对应Director的MACA地址表会被更新为VIP对应RealServer的MAC地址。
问题描述
真实服务器想要将数据帧发送给路由器的时候,源ip地址变成虚拟ip地址,目标ip地址变成用户的ip地址,实际上只是做了一个源目转换。
根据三层转发原理可以知道通过改变MAC地址来进行数据帧的转发,那么真实服务器想要将返回的信息发送给用户就必须要经过路由器。路由器的ip地址真实服务器是肯定知道的,因为在同一个网段,但是它不知道路由器的MAC地址,那么就会进行第二次ARP请求(广播)。
而此时的ARP广播的源地址却是lo:0
的IP地址(VIP地址),且在进行泛洪的时候会带上真实服务器的源MAC地址因为第一次ARP请求的时候我们好不容易让路由器去识别负载均衡器上的MAC地址,在真实服务器进行第二次ARP请求的时候,路由器这边会发现ip地址已经记录过了,这里又来了一个相同的请求,但MAC地址不一致那么就要更新,会把原来vip地址所对应的MAC地址更新成真实服务器的MAC地址,那么以后再从用户端发送来的请求又会再次的发送给真实服务器,不经过负载均衡器,导致负载均衡失效。
解决方法
对节点服务器进行处理,修改其内核,让系统不适用ip包的源地址来设置ARP请求的源地址,而选择发送接口的ip地址,即数据帧先从lo:0出去到达ens33后再去到路由器,设置了这条内核信息后,就不会再使用lo:0的虚拟ip地址了而是使用ens33的真实ip地址发送到路由器中如此,就不会和负载均衡的vip冲突,真实服务器又知道如何去到路由器。
修改/etc/systctl.conf
文件
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.all.arp_ignore = 1
使服务器只响应目的的地址为物理网卡的ipd地址为ARP请求报文。
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_announce = 2
使服务器使用发送报文的网卡的IP地址做ARP请求报文的源IP地址。
DR 服务器:192.168.154.13
Web 服务器1:192.168.154.14
Web 服务器2:192.168.154.15
vip:192.168.154.10
客户端:192.168.154.11
1)配置负载调度器(192.168.154.13)
systemctl stop firewalld.service
setenforce 0
modprobe ip_vs
cat /proc/net/ip_vs
yum -y install ipvsadm
(1)配置虚拟 IP 地址(VIP:192.168.154.10)
cd /etc/sysconfig/network-scripts/
cp ifcfg-ens33 ifcfg-ens33:0 #若隧道模式,复制为ifcfg-tunl0
vim ifcfg-ens33:0
DEVICE=ens33:0
ONBOOT=yes
IPADDR=192.168.80.188
NETMASK=255.255.255.255
ifup ens33:0
ifconfig ens33:0
(2)调整 proc 响应参数
#由于 LVS 负载调度器和各节点需要共用 VIP 地址,需要关闭 icmp 的重定向,不充当路由器。
vim /etc/sysctl.conf
net.ipv4.ip_forward = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.ens33.send_redirects = 0
sysctl -p
(3)配置负载分配策略
ipvsadm-save > /etc/sysconfig/ipvsadm
systemctl start ipvsadm
ipvsadm -C
ipvsadm -A -t 192.168.80.188:80 -s rr
ipvsadm -a -t 192.168.80.188:80 -r 192.168.80.12:80 -g #若隧道模式,-g替换为-i
ipvsadm -a -t 192.168.80.188:80 -r 192.168.80.13:80 -g
ipvsadm
ipvsadm -ln #查看节点状态,Route代表 DR模式
2)部署共享存储(NFS服务器:192.168.80.12)
systemctl stop firewalld.service
setenforce 0
yum -y install nfs-utils rpcbind
mkdir /opt/kgc /opt/benet
chmod 777 /opt/kgc /opt/benet
vim /etc/exports
/usr/share *(ro,sync)
/opt/kgc 192.168.80.0/24(rw,sync)
/opt/benet 192.168.80.0/24(rw,sync)
systemctl start rpcbind.service
systemctl start nfs.service
3)配置节点服务器(192.168.154.14、192.168.154.15)
systemctl stop firewalld.service
setenforce 0
(1)配置虚拟 IP 地址(VIP:192.168.154.10)
#此地址仅用作发送 Web响应数据包的源地址,并不需要监听客户机的访问请求(改由调度器监听并分发)。因此使用虚接口 lo∶0 来承载 VIP 地址,并为本机添加一条路由记录,将访问 VIP 的数据限制在本地,以避免通信紊乱。
cd /etc/sysconfig/network-scripts/
cp ifcfg-lo ifcfg-lo:0
vim ifcfg-lo:0
DEVICE=lo:0
ONBOOT=yes
IPADDR=192.168.80.188
NETMASK=255.255.255.255 #注意:子网掩码必须全为 1
ifup lo:0
ifconfig lo:0
route add -host 192.168.80.188 dev lo:0
vim /etc/rc.local
/sbin/route add -host 192.168.80.188 dev lo:0:
chmod +x /etc/rc.d/rc.local
(2)调整内核的 ARP 响应参数以阻止更新 VIP 的 MAC 地址,避免发生冲突
vim /etc/sysctl.conf
......
net.ipv4.conf.lo.arp_ignore = 1 #系统只响应目的IP为本地IP的ARP请求
net.ipv4.conf.lo.arp_announce = 2 #系统不使用IP包的源地址来设置ARP请求的源地址,而选择发送接口的IP地址
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
sysctl -p
或者
echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
sysctl -p
yum -y install nfs-utils rpcbind httpd
systemctl start rpcbind
systemctl start httpd
--192.168.154.14---
mount.nfs 192.168.80.13:/opt/kgc /var/www/html
echo 'this is kgc web!' > /var/www/html/index.html
--192.168.154.15---
mount.nfs 192.168.80.13:/opt/benet /var/www/html
echo 'this is benet web!' > /var/www/html/index.html
4)测试 LVS 群集
在客户端使用浏览器访问 http://192.168.154.11/
也可以在虚拟机中测试,新开一台虚拟机使用以下命令
curl 192.168.154.10