作者介绍:简历上没有一个精通的运维工程师。请点击上方的蓝色《运维小路》关注我,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。

我们上一章介绍了Web服务器,其中以Nginx为主,本章我们来讲解几个代理软件:Squid,Haproxy,LVS,FRP(内网穿透)。
上个小节我们介绍LVS的的NAT模式,但是这个NAT模式所有请求都会经过DR,容易出现瓶颈。今天我们来讲解另外一种模式:DR模式,只有请求会经过DR,请求返回并不会经过DR,而是直接有RS直接返回。这样就大大降低了DR的压力。
一、DR 模式(Direct Routing)的核心原理
DR 模式,即直接路由模式,是 LVS(Linux Virtual Server)中的一种高级工作模式,以其高效性而著称。与 NAT 模式不同的是,DR 模式不修改数据包的源IP和目标IP,而是通过更改数据包的目标MAC地址来实现流量的转发。这种模式特别适用于高性能要求的场景,因为它避免了NAT模式中的IP地址转换过程,从而降低了Director的工作负载。
关键流程:
-
客户端请求发送:客户端发送请求到VIP(Virtual IP),这个VIP实际上是Director对外暴露的服务IP。
-
Director接收并转发请求:Director接收到客户端的请求后,并不会修改请求包的目标IP或源IP,而是将请求包的目标MAC地址改为Real Server的MAC地址,然后将数据包直接转发给选定的Real Server。这里的关键点在于仅修改了MAC地址,保证了数据包在网络层可以直接到达Real Server。
-
Real Server处理请求:Real Server接收到请求后,会直接处理该请求,并且响应数据直接发回给客户端,绕过了Director。这是因为Real Server的响应数据包的源IP是VIP,目标IP是客户端的真实IP,这样可以确保响应能够正确地返回给客户端。
流量路径示意图:
arduino
请求方向:Client → [VIP] Director (只改MAC) → Real Server
响应方向:Client ← [VIP] Real Server 直接响应 ← 绕过Director
二、DR 模式的关键配置
1.网络拓扑
此图来源于网络

三、DR 模式的部署
bash
#把vip 临时添加到DR机器
ifconfig eth0:0 192.168.31.134 netmask 255.255.255.255 broadcast 192.168.31.134 up
# 添加 NAT 规则(将 VIP:80 的请求转发到 Real Server)
#添加ipvsadm规则
ipvsadm -A -t 192.168.31.134:80 -s rr
ipvsadm -a -t 192.168.31.134:80 -r 192.168.31.131:80 -g
ipvsadm -a -t 192.168.31.134:80 -r 192.168.31.132:80 -g

这里参数和NAT模式实际只是最后一个参数的区别,-m是NAT模式,-g是DR(路由)模式
bash
#把vip添加到本地回环
ip addr add 192.168.31.134/32 dev lo
#添加arp抑制,避免响应134的arp需求
#这样才能确认访问vip会先到达dr服务器的vip
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

yaml
[root@localhost ~]# tcpdump -i any port 80
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
20:30:04.772098 IP 192.168.31.44.57175 > localhost.localdomain.http: Flags [.], seq 927064611:927064612, ack 3222223343, win 1025, length 1: HTTP
20:30:04.772111 IP 192.168.31.44.57175 > localhost.localdomain.http: Flags [.], seq 0:1, ack 1, win 1025, length 1: HTTP
20:30:04.816754 IP 192.168.31.44.57175 > localhost.localdomain.http: Flags [P.], seq 1:538, ack 1, win 1025, length 537: HTTP: GET / HTTP/1.1
20:30:04.816776 IP 192.168.31.44.57175 > localhost.localdomain.http: Flags [P.], seq 1:538, ack 1, win 1025, length 537: HTTP: GET / HTTP/1.1
20:30:04.818282 IP 192.168.31.44.57288 > localhost.localdomain.http: Flags [S], seq 3838092750, win 64240, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
20:30:04.818314 IP 192.168.31.44.57288 > localhost.localdomain.http: Flags [S], seq 3838092750, win 64240, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
20:30:04.822822 IP 192.168.31.44.57288 > localhost.localdomain.http: Flags [.], ack 3020950689, win 1026, length 0
20:30:04.822843 IP 192.168.31.44.57288 > localhost.localdomain.http: Flags [.], ack 1, win 1026, length 0
20:30:04.865907 IP 192.168.31.44.57175 > localhost.localdomain.http: Flags [.], ack 182, win 1025, length 0
20:30:04.865920 IP 192.168.31.44.57175 > localhost.localdomain.http: Flags [.], ack 182, win 1025, length 0
20:30:06.038608 IP localhost.localdomain.36386 > 192.168.31.131.http: Flags [S], seq 3544855196, win 29200, options [mss 1460,sackOK,TS val 227196 ecr 0,nop,wscale 7], length 0
20:30:06.038634 IP localhost.localdomain.43838 > 192.168.31.132.http: Flags [S], seq 1825416513, win 29200, options [mss 1460,sackOK,TS val 227196 ecr 0,nop,wscale 7], length 0
20:30:06.038949 IP 192.168.31.132.http > localhost.localdomain.43838: Flags [S.], seq 3040237057, ack 1825416514, win 28960, options [mss 1460,sackOK,TS val 210212 ecr 227196,nop,wscale 7], length 0
20:30:06.038968 IP localhost.localdomain.43838 > 192.168.31.132.http: Flags [.], ack 1, win 229, options [nop,nop,TS val 227197 ecr 210212], length 0
20:30:06.038977 IP 192.168.31.131.http > localhost.localdomain.36386: Flags [S.], seq 165726405, ack 3544855197, win 28960, options [mss 1460,sackOK,TS val 216199 ecr 227196,nop,wscale 7], length 0
20:30:06.038981 IP localhost.localdomain.36386 > 192.168.31.131.http: Flags [.], ack 1, win 229, options [nop,nop,TS val 227197 ecr 216199], length 0
20:30:06.039008 IP localhost.localdomain.36386 > 192.168.31.131.http: Flags [R.], seq 1, ack 1, win 229, options [nop,nop,TS val 227197 ecr 216199], length 0
20:30:06.039026 IP localhost.localdomain.43838 > 192.168.31.132.http: Flags [R.], seq 1, ack 1, win 229, options [nop,nop,TS val 227197 ecr 210212], length 0
从抓包来看,只有DR接受到客户端请求链接,和DR转发到到后端RS的请求,并没有DR返回客户端的包。
运维小路
一个不会开发的运维!一个要学开发的运维!一个学不会开发的运维!欢迎大家骚扰的运维!
关注微信公众号《运维小路》获取更多内容。