Ingress 流量整形

💡 原文中文,约6800字,阅读约需17分钟。
📝

内容提要

文章介绍了通过Linux IFB虚拟网卡实现入口流量整形,以限制B组服务器到S3的带宽(如10Gbps),避免影响A组用户。相比直接丢弃包的policing(导致TCP拥塞控制使实际速度降至5-7Gb),IFB将入口流量重定向到可做出口qdisc的设备,使用HTB队列稳定限速至约950Mbps。文章还解释了为何速度略低于设定值(因计算包含包头),以及TCP自时钟机制如何通过延迟ACK平滑控制发送速率。

🔎

延伸解读

为什么 policing 会导致带宽减半

文章指出,直接使用 policing(丢弃超速包)会触发 TCP 拥塞控制,导致实际带宽远低于设定值。例如,限速 10Gbps 时实际只能达到 5-7Gbps,且不稳定。这是因为丢包使 TCP 发送端误判网络拥塞,大幅降低 cwnd,形成 AIMD 震荡。理解这一点有助于评估为何需要更精细的流量整形方案。

IFB 如何实现入口整形

IFB 虚拟网卡将入口流量重定向到一个可施加出口 qdisc 的设备,从而复用 egress 的整形能力。文章通过 HTB 队列将特定 IP 的流量限制在设定速率,实测稳定在 950Mbps 左右。这种方案避免了丢包,使 TCP 窗口平滑增长,适合需要精确控制入口带宽的场景。

限速值为何略低于设定

tc 计算速率时基于完整数据包大小(如 1500 字节),而 iperf3 等工具显示的是 TCP 负载(MSS,如 1448 字节)。因此,设定 1Gbps 时实际吞吐约为 965Mbps。理解这一差异有助于正确解读测试结果,避免误以为配置有误。

TCP 自时钟与平滑发送

IFB 整形通过延迟 ACK 而非丢包来控制发送速率,ACK 像时钟脉冲一样驱动发送端,使 cwnd 平滑增长。文章还提到 send buffer 可能成为瓶颈,进一步限制发送速率。这解释了为何整形后 TCP 行为与 policing 截然不同,更利于稳定利用带宽。

Q&A

什么是Linux IFB虚拟网卡?它如何实现入口流量整形?

IFB(Intermediate Functional Block)是Linux内核中的一个虚拟网络设备,它可以将原本的入口(ingress)流量重定向到一个可以配置出口(egress)qdisc的设备上,从而利用现有的出口流量整形机制来对入口流量进行整形。具体来说,通过tc的mirred动作将物理网卡收到的包重定向到IFB设备,然后在IFB上配置HTB等qdisc,实现限速。

为什么直接使用policing(丢弃超速包)会导致实际带宽远低于设定值?

因为policing通过丢弃超速的包来限速,这会导致TCP发送端检测到丢包,触发拥塞控制算法(如CUBIC)大幅降低拥塞窗口(cwnd),从而降低发送速率。实际测试中,使用policing限速1Gbps时,实际吞吐只有约850Mbps,且不稳定。

在IFB流量整形中,为什么实际吞吐是950Mbps而不是设定的1Gbps?

因为tc在计算速率时使用的是skb的大小(包括以太网帧头等),而iperf3等工具显示的是TCP负载(MSS)的速率。例如,1500字节的帧中TCP负载为1448字节,所以1Gbps的限速实际对应约965Mbps的TCP吞吐。

IFB流量整形如何利用TCP的self-clocking机制实现平滑限速?

IFB将入口包缓存并按固定速率释放,只有被释放的包才会进入网络栈并触发ACK返回。ACK的返回节奏决定了发送端可以继续发送新包的时机,从而平滑地控制发送速率。由于包没有被丢弃,只是ACK延迟,cwnd不会大幅下降,因此吞吐稳定。

在IFB整形场景中,为什么cwnd曲线看起来平滑而不是像policing那样震荡?

因为IFB整形时包没有被丢弃,只是ACK延迟,所以cwnd不会因丢包而大幅下降。此外,当发送速率接近限速时,cwnd可能不再是瓶颈,而是受限于发送缓冲区(sndbuf)或ACK时钟,因此cwnd增长平稳。

如何配置IFB和HTB来限制特定IP的入口带宽?

首先加载ifb模块并创建ifb0接口,然后将物理网卡(如bond0)的入口流量重定向到ifb0,接着在ifb0上配置HTB队列,创建两个class:一个限速(如10Gbps),另一个不限速,最后通过u32过滤器将特定源IP的流量匹配到限速class。

🏷️

标签

➡️

继续阅读