DR模式实现

在 HAProxy 中,DR 模式 指的是 Direct Routing(直接路由) ,是一种经典的 L4 层负载均衡模式,也是实现高并发、高性能负载均衡的常用方案。

核心原理

  1. 前端统一入口 :客户端请求发送到 HAProxy 的虚拟 IP(VIP),HAProxy 作为负载均衡器接收请求。
  2. 路由转发 :HAProxy 不修改数据包的目标 IP(仍为 VIP),只修改数据包的 MAC 地址为后端真实服务器(Real Server)的 MAC 地址,然后将数据包转发到后端服务器。
  3. 后端直接响应 :后端服务器处理完请求后,直接将响应数据包发送给客户端,不经过 HAProxy 中转。
  4. ARP 欺骗规避 :为了让后端服务器能识别 VIP 并接收数据包,需要在后端服务器上绑定 VIP 到回环网卡(lo),同时关闭 ARP 响应(避免 VIP 被局域网其他设备解析)。

核心特点

特点 说明
高性能 响应数据包不经过 HAProxy,减少了负载均衡器的带宽瓶颈,支持更高并发
L4 层转发 基于 IP + 端口转发,不解析应用层数据(如 HTTP 头)
无数据改写 仅修改 MAC 地址,数据包内容(源 / 目标 IP)不变
后端需配置 VIP 必须在所有后端服务器上配置 VIP,否则无法接收请求

适用场景

  • 高并发、大流量的 TCP/UDP 服务(如电商秒杀、直播、游戏服务器)。
  • 对负载均衡器带宽压力敏感的场景(避免 HAProxy 成为瓶颈)。

示例图:

配置:

创建五个虚拟机分别为 client(客户端) router(路由器) vsnode(调度器) RS1 RS2

路由器有两张网卡分别为 eth0 和 eth1

在路由器中:

bash 复制代码
#停止 ipvsadm 服务,并设置其开机不自启
[root@router ~]# systemctl disable --now ipvsadm.service    
Removed "/etc/systemd/system/multi-user.target.wants/ipvsadm.service".

#清空系统中所有已配置的 LVS (IPVS) 规则
[root@router ~]# ipvsadm -C    

#在路由器中使用自己配置的脚本配置两个网卡
[root@router ~]# vmset.sh eth0 172.25.254.100 vsnode
[root@router ~]# vmset.sh eth1 192.168.0.100 vsnode noroute、

#设定内核路由功能
[root@router ~]# echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf
[root@router ~]# sysctl  -p
net.ipv4.ip_forward = 1

#数据转发策略
[root@router ~]# iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to-source 192.168.0.100
[root@vsnode ~]# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 172.25.254.100

在调度器中:

bash 复制代码
[root@vsnode ~]# vmset.sh  eth0 192.168.0.200 vsnode noroute

#用 vim 编辑器打开 CentOS/RHEL 系统中 eth0 网卡的 NetworkManager 配置文件,该文件用于定义网卡的 IP 地址、网关、DNS 等网络参数。
[root@vsnode ~]# vim /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0


[ipv4]
method=manual
address1=192.168.0.200/24,192.168.0.100
address2=192.168.0.50/24

#检测
root@vsnode system-connections]# route  -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.0.100   0.0.0.0         UG    100    0        0 eth0
192.168.0.0     0.0.0.0         255.255.255.0   U     100    0        0 eth0
192.168.0.0     0.0.0.0         255.255.255.0   U     100    0        0 eth0
[root@vsnode system-connections]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:41:e5:8b brd ff:ff:ff:ff:ff:ff
    altname enp3s0
    altname ens160
    inet 192.168.0.200/24 brd 192.168.0.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet 192.168.0.50/24 brd 192.168.0.255 scope global secondary noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::e40:8975:6b9:fea8/64 scope link noprefixroute
       valid_lft forever preferred_lft forever

在客户端中:

bash 复制代码
[root@client ~]# vmset.sh  eth0 172.25.254.99 client
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/4)
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:e5:75:af brd ff:ff:ff:ff:ff:ff
    altname enp3s0
    altname ens160
    inet 172.25.254.99/24 brd 172.25.254.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fee5:75af/64 scope link tentative noprefixroute
       valid_lft forever preferred_lft forever
client


#检测
[root@client ~]# ping 192.168.0.200
PING 192.168.0.200 (192.168.0.200) 56(84) 比特的数据。
64 比特,来自 192.168.0.200: icmp_seq=1 ttl=128 时间=1.08 毫秒

RS1:

bash 复制代码
[root@RS1 ~]# vmset.sh eth0 192.168.0.10 RS1 noroute

#修改 eth0 网卡的 IPv4 网关地址为 192.168.0.100
[root@RS1 ~]# nmcli connection modify eth0 ipv4.gateway 192.168.0.100
[root@RS1 ~]# nmcli connection reload
[root@RS1 ~]# nmcli connection up eth0

#查看内核路由表
[root@RS1 ~]# route  -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.0.100   0.0.0.0         UG    100    0        0 eth0
192.168.0.0     0.0.0.0         255.255.255.0   U     100    0        0 eth0

#在lo上设定vip
[root@RS1 ~]# cd /etc/NetworkManager/system-connections/
[root@RS1 system-connections]# cp -p eth0.nmconnection lo.nmconnection
[root@RS1 system-connections]# vim lo.nmconnection
[connection]
id=lo
type=loopback
interface-name=lo

[ethernet]

[ipv4]
address1=127.0.0.1/8
address2=192.168.0.200/32
method=manual

[root@RS1 system-connections]# nmcli connection reload
[root@RS1 system-connections]# nmcli connection up lo
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/6)
[root@RS1 system-connections]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet 192.168.0.200/32 scope global lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
       
 #arp禁止响应,修改 Linux 内核的 ARP 响应策略,将 all(所有网卡)的 arp_ignore 参数设置为 1,这是 LVS/HAProxy DR 模式中避免 VIP 地址冲突的关键配置
[root@rs1 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@rs1 ~]# echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
[root@rs1 ~]# echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
[root@rs1 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce

RS2:

bash 复制代码
[root@RS2 ~]# vmset.sh eth0 192.168.0.20 RS2 noroute
[root@RS2 ~]# nmcli connection modify eth0 ipv4.gateway 192.168.0.100
[root@RS2 ~]# nmcli connection reload
[root@RS2 ~]# nmcli connection up eth0
[root@RS2 ~]# route  -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.0.100   0.0.0.0         UG    100    0        0 eth0
192.168.0.0     0.0.0.0         255.255.255.0   U     100    0        0 eth0

#在lo上设定vip
[root@RS2 ~]# cd /etc/NetworkManager/system-connections/
[root@RS2 system-connections]# cp -p eth0.nmconnection lo.nmconnection
[root@RS2 system-connections]# vim lo.nmconnection
[connection]
id=lo
type=loopback
interface-name=lo

[ethernet]

[ipv4]
address1=127.0.0.1/8
address2=192.168.0.200/32
method=manual

[root@RS2 system-connections]# nmcli connection reload
[root@RS2 system-connections]# nmcli connection up lo
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/6)
[root@RS2 system-connections]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet 192.168.0.200/32 scope global lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
       
#arp禁止响应
[root@rs2 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@rs2 ~]# echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
[root@rs2 ~]# echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
[root@rs2 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce

测试结果:

相关推荐
鹤落晴春10 小时前
【K8s】Pod调度、configMaps
云原生·容器·kubernetes
张忠琳11 小时前
【runc 1.4.2】(Part 2)runc 1.4.2 超深度分析 — CLI层:main.go、命令文件、runner、信号处理、TTY
云原生·kubernetes·runc
阿里云云原生13 小时前
AI 提效是“假象”还是“红利”?用 LoongSuite + SLS 构建组织级 AI 编码度量看板
云原生
Java识堂14 小时前
如何对微服务进行拆分?
微服务·云原生·架构
Plastic garden16 小时前
K8s知识(3) Pod亲和性,调度
云原生·容器·kubernetes
霸道流氓气质17 小时前
从MySQL到云原生:全面解析阿里云PolarDB数据库及其与MySQL的核心差异
数据库·mysql·云原生
张忠琳17 小时前
【client-go v0.36.1】(store Part 1)Store 超深度分析 — 模块定位、接口层次、类结构、KeyFunc体系、构造初始化
云原生·kubernetes·informer·store·client-go
heimeiyingwang19 小时前
【架构实战】网关架构设计:微服务的统一入口
微服务·云原生·架构
sbjdhjd20 小时前
04 (下) | K8S微服务实战:从 Service 到金丝雀发布
运维·微服务·云原生·kubernetes·开源·云计算·excel
java_cj20 小时前
K8s入门第一课:从零理解Kubernetes核心概念与架构设计
运维·云原生·容器·架构·kubernetes