DR 模式是通过改写请求报文的目标 MAC 地址,将请求发给真实服务器的,而真实服务器响应后的处理结果直接返回给客户端用户。DR 模式可以极大的提高集群系统的伸缩性。但是要求调度器 LB 与真实服务器 RS 都有一块网卡连接到同一物理网段上,必须在同一个局域网环境。DR 模式是互联网使用比较多的一种模式。 如果要提供互联网业务,要求每台服务器都具有外网 IP 地址。
① 客户端 192.168.1.10 向目标 vip:192.168.1.88 发出请求
② 调度器收到客户端请求后,根据负载均衡算法选择一台 active 的 real server(假设是 cong12),并把数据包的目标地址的 MAC 地址修改为 cong12 的 MAC 地址,然后把数据包发送到局域网里。
③ cong12 服务器在局域网收到这个数据包,发现数据包的目的地址和本机匹配(因为所有的 realserver 配置了相同的 VIP),MAC 地址和本机匹配,于是这个包被合法接受,开始处理数据包,随后重新封装报文,发送到局域网。
注意:RS 返回响应时,直接向源 IP(即客户端的 IP)返回数据包,不再经过 LVS 调度器。
④ 如果 client 与 LVS 同一网段,那么 client(192.168.1.10)将收到这个回复报文。如果跨了网段,那么报文通过 gateway/路由器经由 Internet 返回给用户。
lvs-dr 做的事情很少,也很简单,所以它的效率很高,不比硬件负载均衡设备差 多少。数据包、数据帧的大致流向是这样的:client --> lVS --> RS --> client
① 保证前端路由将目标地址为 VIP 报文统统发给 Director Server,而不是 RS
② RS 可以使用私有地址;也可以是公网地址,如果使用公网地址,此时可以通过互联网对 RIP 进行直接访问。
③ RS 跟 Director Server 必须在同一个物理网络中
④ 所有的请求报文经过 Director Server,但响应报文不会经过 Director Server
⑤ 不支持地址转换,也不支持端口映射
⑥ RS 可以是大多数常见的操作系统
⑦ RS 的网关绝不允许指向 DIP
⑧ RS 上的 lo 接口配置 VIP 地址
缺陷:唯一的缺陷在于它要求 LVS 调度器及所有应用服务器在同一个网段中,因此不能实现集群的跨网段应用。
主机 |
内网/外网 IP |
VIP |
角色 |
JClouds |
192.168.137.253 |
192.168.137.88 |
LVS |
Book |
192.168.137.252 |
192.168.137.88 |
httpd |
Client01 |
192.168.137.6 |
192.168.137.88 |
httpd |
从 lvs-dr 模式的工作原理我们可以看出负载调度器 ens33 有 2 个 IP 地址,所以我们需要配置 ens33 和 ens33:0 两个 IP
# 配置 VIP
ifconfig ens33:0 192.168.1.88/24
ifconfig ens33:0
# 加载 ip_vs 模块并安装 ipvsadm 软件包
modprobe ip_vs
yum -y install ipvsadm
# 使用 ipvsadm 创建负载分配策略
ipvsadm -A -t 192.168.1.88:80 -s wrr
# -g 表示 DR 模式 , -m 表示 IP NAT 模式
ipvsadm -a -t 192.168.137.88:80 -r 192.168.137.252:80 -g -w 1
ipvsadm -a -t 192.168.137.88:80 -r 192.168.137.6:80 -g -w 2
# 保存配置或规则
ipvsadm --save > /etc/sysconfig/ipvsadm
systemctl start ipvsadm
systemctl enable ipvsadm
# 查看负载均衡策略
ipvsadm -Ln
注:三个 LVS 模式中,只有 NAT 模式需要开启路由转发功能。 DR 和 TUN 模式不需要开启,也不需要把网关指向调度器。
Book & Client01 配置相同
① 关闭 ARP 转发
同一个广播域:配置了多个相同的 VIP 是不允许的, 要想实现,就必须让外面的网络, 无法发现这个 VIP 的存在。因此在 Linux 里面, 可以修改内核参数, 实现接口 IP 的广播不响应、不广播。
# 临时配置
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
# 或:
net.ipv4.conf.ens33.arp_ignore = 1
net.ipv4.conf.ens33.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
arp_ignore:定义了网卡在响应外部 ARP 请求时候的响应级别,即当 ARP 请求发过来后发现自己正是请求的地址是否响应。
arp_announce: 的作用是控制系统在对外发送 arp 请求时,如何选择 arp 请求数据包的源 IP 地址:
② 配置虚拟IP地址
# 生成回环口配置文件:
cd /etc/sysconfig/network-scripts/
cp ifcfg-lo ifcfg-lo:0
vim ifcfg-lo:0
#--------------------------
DEVICE=lo:0
IPADDR=192.168.1.88
NETMASK=255.255.255.255
ONBOOT=yes
NAME=loopback
#----------------------------
systemctl restart network
ifconfig lo:0
③ 配置Http服务
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "192.168.137.5" > /var/www/html/index.html
通过网络地址转换,客户端访问调度器时,调度器重写请求报文的目标地址,根据预设的调度算法,将请求分派给后端真实服务器;真实服务器的响应报文通过调度器时,报文源地址被重写再返回给客户,完成整个负载调度过程。但通常在流量比较大的情况下会造成调度器的瓶颈。因为服务数据的返回必须通过调度器出去。
客户端访问VIP1
CIP 客户端的 IP
VIP 是域名解析的 IP, 是集群对外的公网 IP
DIP 用来和后端服务器进行数据交互的 IP, 请求报文转发给后端服务器从此口出去
RIP 真实服务器的 IP
调度器使用 NAT 进行地址转换
客户端访问调度器时,调度器通过网络地址转换,调度器重写请求报文的目标地址,根据预设的调度算法,将请求分派给后端的真实服务器。
真实服务器返回处理结果
真实服务器的响应报文通过调度器时,报文的源地址被重写,再返回给客户,完成整个负载调度过程
主机名 |
内网ip |
外网ip |
角色 |
JClouds |
192.168.137.253 |
192.168.2.253 |
LVS |
Book |
192.168.137.252 |
httpd |
|
Client01 |
192.168.137.6 |
httpd |
# 关闭防火墙和 selinux(所有服务器)
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
sed -i '/SELINUX/s/enforcing/disabled/' /etc/selinux/config
#--------------------配置Book------------------------------
# 安装 httpd
yum install -y httpd
systemctl enable httpd
# 生成测试网页
echo "192.168.1.12" > /var/www/html/index.html
# 修改本机网关为JClouds的IP地址
vim /etc/sysconfig/network-scripts/ifcfg-ens33
systemctl restart network
# 测试网页
curl 192.168.1.12
#--------------------配置Client01------------------------------
yum install -y httpd
systemctl restart httpd
echo "192.168.137.6" > /var/www/html/index.html
# 修改本机网关为JClouds的IP地址
vim /etc/sysconfig/network-scripts/ifcfg-ens33
systemctl restart network
curl 192.168.137.6
JClouds主机 添加一块网卡
配置宿主机 vmnet1 ip 地址
cd /etc/sysconfig/network-scripts/
cp ifcfg-ens33 ifcfg-ens37
vim ifcfg-ens37
TYPE="Ethernet"
PROXY_METHOD="none"
BROWSER_ONLY="no"
BOOTPROTO="none"
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="ens36"
DEVICE="ens36"
ONBOOT="yes"
IPADDR="192.168.2.10"
PREFIX="24"
systemctl restart network
ifconfig ens36
# 打开路由转发功能
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p
LVS 现在已成为 Linux 内核的一部分,默认编译为 ip_vs 模块,必要时能够自动调 用。以下操作可以手动加载 ip_vs 模块,并查看当前系统中 ip_vs 模块的版本信息。
modprobe ip_vs
lsmod | grep ip_vs
cat /proc/net/ip_vs
# 安装 LVS 管理工具:ipvsadm
yum install -y ipvsadm
# 清除内核虚拟服务器表中的所有记录
ipvsadm -C
# 创建虚拟服务器
ipvsadm -A -t 192.168.2.10:80 -s rr
ipvsadm -a -t 192.168.2.10:80 -r 192.168.137.252:80 -m
ipvsadm -a -t 192.168.2.10:80 -r 192.168.137.6:80 -m
# 查看配置
ipvsadm -Ln
# 保存配置或规则
#LVS 的规则配置文件:/etc/sysconfig/ipvsadm
ipvsadm --save >/etc/sysconfig/ipvsadm
# 查看客户端连接分发器和 real server 的情况
ipvsadm -Lnc
# 查看分发情况
ipvsadm -Ln --stats
# 查看速率
ipvsadm -Ln --rate
# 清空当前的连接数量
ipvsadm -Z #虚拟服务表计数器清零
ipvsadm -Ln --stats
# 删除服务器节点
ipvsadm -d -t 192.168.2.10:80 -r 192.168.137.252:80
ipvsadm -Ln
# 删除整个虚拟服务器
ipvsadm -D -t 192.168.2.11:80
ipvsadm -Ln
DR 方式是通过 MAC,规模是一个交换网络。而 TUN 方式,是通过给数据包加上新的 IP 头部来实现,这个可以跨整个广域网。TUN 模式可以解决 DR 模式下不能跨网段的问题,甚至可以跨公网进行。
LVS/TUN 使用 IP Tunneling 技术,在 Director 机器和 Real Server 机器之间架设一个IP Tunnel,通过 IP Tunnel 将负载分配到 Real Server 机器上。Director 和 Real Server 之间的关系比较松散,可以是在同一个网络中,也可以是在不同的网络中,只要两者能够通过 IP Tunnel 相连就行。收到负载分配的 Real Server 机器处理完后会直接将反馈数据送回给客户,而不必通过 Director 机器。实际应用中,服务器必须拥有正式的 IP 地址用于与客户机直接通信,并且所有服务器必须支持 IP 隧道协议。
在原有的 IP 报文外再次封装一层 IP 首部,内部 IP 首部(源地址为 CIP,目标 IP 为 VIP),外层 IP 首部(源地址为 DIP,目标 IP 为 RIP)
① 当用户请求到达 Director Server,此时请求的数据报文会先到内核空间的 PREROUTING 链。 此时报文的源 IP 为 CIP,目标 IP 为 VIP 。
② PREROUTING 检查发现数据包的目标 IP 是本机,将数据包送至 INPUT 链
③ IPVS 比对数据包请求的服务是否为集群服务,若是,在请求报文的首部再次封装一层 IP 报文,封装源 IP 为 DIP,目标 IP 为 RIP。然后发至 POSTROUTING 链。 此时源 IP 为 DIP,目标 IP 为 RIP
④ POSTROUTING 链根据最新封装的 IP 报文,将数据包发至 RS(因为在外层封装多了一层 IP 首部,所以可以理解为此时通过隧道传输)。 此时源 IP 为 DIP,目标IP 为 RIP
⑤ RS 接收到报文后发现是自己的 IP 地址,就将报文接收下来,拆除掉最外层的 IP 后,会发现里面还有一层 IP 首部,而且目标是自己的 lo 接口 VIP,那么此时 RS 开始处理此请求,处理完成之后,通过 lo 接口送给 ens33 网卡,然后向外传递。此时的源 IP 地址为 VIP,目标 IP 为 CIP
⑥ 响应报文最终送达至客户端
① RIP、VIP、DIP 全是公网地址
② RS 的网关不会也不可能指向 DIP
③ 所有的请求报文经由 Director Server,但响应报文必须不能进过 Director Server
④ 此模式不支持端口映射
⑤ RS 的操作系统得支持隧道功能
缺点:由于后端服务器 RS 处理数据后响应发送给用户,此时需要租借大量 IP(特别是后端服务器使用较多的情况下)。
优点:实现 lvs-tun 模式时,LVS 调度器将 TCP/IP 请求进行重新封装并转发给后端服务器,由目标应用服务器直接回复用户。负载调度器和应用服务器之间是通过 IP 隧道来进行转发,故两者可以存在于不同的网段中(如异地机房,好处是可以容灾, 通过智能 dns(DNS view)实现边界 最近访问)。
注:其实企业中最常用的是 DR 实现方式。
主机 |
外网 IP |
VIP |
角色 |
JClouds |
192.168.137.253 |
192.168.137.88 |
LVS |
Book |
192.168.137.252 |
192.168.137.88 |
httpd |
Client01 |
192.168.137.6 |
192.168.137.88 |
httpd |
① 加载 ipip 隧道模块
modprobe ipip
lsmod | grep ipip
② 为 tunl0 设备配置 VIP
# 激活隧道
ip link set up tunl0
# 添加虚拟 ip
ip addr add 192.168.137.88 dev tunl0
ifconfig tunl0
# 加载 ip_vs 模块并安装 ipvsadm 软件包
modprobe ip_vs
yum -y install ipvsadm
systemctl enable ipvsadm
# 使用 ipvsadm 创建负载分配策略
ipvsadm -C
ipvsadm -A -t 192.168.137.88:80 -s rr
# -i 隧道模式
ipvsadm -a -t 192.168.137.88:80 -r 192.168.137.252:80 -i
ipvsadm -a -t 192.168.137.88:80 -r 192.168.137.6:80 -i
ipvsadm --save > /etc/sysconfig/ipvsadm
# 查看配置
ipvsadm -ln
Book & Client01 配置相同
① 查看加载 ipip 模块
modprobe ipip
lsmod | grep ipip
# 查看tunl0
ifconfig -a
② 关闭 ARP 转发
# 文件最后添加以下内容
vim /etc/sysctl.conf
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.tunl0.rp_filter = 0
③ 配置VIP
ifconfig tunl0 192.168.137.88 netmask 255.255.255.255 up
ifconfig tunl0
④ 配置 Httpd 服务
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "192.168.137.253" > /var/www/html/index.html
# 查看调度情况
ipvsadm -Lnc