Linux网络带宽管理方案_限速与保障策略解析【指导】

6次阅读

tc 限速不准主因是 qdisc 类型选错(如误用 pfifo_fast)或根设备绑定错误(须用 egress root 而非 parent,禁用 ingress);容器需 clsact+cgroup2 实现进程级限速,iptables 限速须在 POSTROUTING 打标配合 egress 策略。

Linux 网络带宽管理方案_限速与保障策略解析【指导】

tc 命令限速不准?关键在 qdisc 类型和根设备选择

Linux 下用 tc 限速失效或波动大,多数情况不是命令写错,而是选错了队列规则(qdisc)类型或绑错了网络接口。默认的 pfifo_fast 不支持速率控制,必须显式指定如 htbtbf;且限速必须施加在 ** 出口方向(egress)**,不能对 loopback 或虚拟网卡(如 docker0)直接生效。

  • tc qdisc add dev eth0 root htb default 30 —— 必须用 root(非 parent),否则无法接管全部出向流量
  • 容器或 Docker 场景下,宿主机上对 eth0 限速只影响从宿主机发出的包,容器内进程的出向流量需在 docker0 或使用 clsact + tc filter 匹配 cgroup
  • tbf 简单但无分类能力,突发(burst)设太小会导致 TCP ACK 丢包、吞吐骤降;htb 更稳,但需配合 tc classtc filter 才能按 IP/端口 分流

保障某服务带宽不被挤占:用 htb + cgroup2 实现进程级隔离

单纯给 IP 或端口限速无法解决“同一台机器上多个服务争抢带宽”的问题。真正可控的方式是把进程归入 cgroup2,并用 tcclsact qdisc 结合 matchall 过滤器绑定到 cgroup。

  • 确认内核启用 cgroup2:检查 /proc/cgroupsmemory 行的第 4 列是否为 1;Ubuntu 22.04+ 默认启用
  • 创建 cgroup 并设置 net_cls:
    mkdir /sys/fs/cgroup/myapp   echo 0x00110011 > /sys/fs/cgroup/myapp/net_cls.classid

    其中 0x00110011 是主类 ID(前 16 位)+ 子类 ID(后 16 位),后续 tc class 需匹配前 16 位

  • 启动进程时加入 cgroup:sudo cgexec -g net_cls:/myapp curl http://example.com
  • 在网卡上挂 clsact:tc qdisc add dev eth0 clsact,再用 tc filter add dev eth0 parent ffff: protocol ip flower skip_sw indev eth0 classid 0x00110011

iptables + tc 联动做源 IP 限速:为什么 mangle 表 PREROUTING 不起作用

想对进来的连接限速(比如限制某客户端上传速度),不能在 PREROUTING 链打标记,因为 tc 的 egress 限速只管发出去的包,而 PREROUTING 处理的是刚进来的包——此时还没走到 egress 队列。正确路径是:对 ** 应答包(即服务器回包)** 打标,再在 egress 上按标记限速。

  • 给特定源 IP 的响应流量打标记:iptables -t mangle -A POSTROUTING -s 192.168.1.100 -j CLASSIFY --set-class 1:10
  • 对应 tc class 必须建在 root htb 下:tc class add dev eth0 parent 1: classid 1:10 htb rate 2mbit
  • 注意:若服务器启用了 conntrack,且连接是 NAT 过来的(如 SNAT),-s 应该匹配 NAT 后的源地址(通常是内网地址),而非原始客户端 IP

实时监控限速效果:别只看 ifconfig,要用 tc -s 和 ip -s

ifconfig eth0 显示的 RX/TX 是底层驱动收发计数,不反映 tc 是否真在丢包或延迟。实际策略是否生效,得查 tc 自身统计和 qdisc 排队状态。

  • 查看某 class 的实时丢包与排队长度:tc -s class show dev eth0,重点关注 droppedoverlimitsqlen
  • 查过滤器命中次数:tc -s filter show dev eth0 parent ffff:(clsact)或 tc -s filter show dev eth0 parent 1:(htb)
  • 验证 cgroup 绑定是否成功:cat /proc/[pid]/cgroup 看进程是否在目标 cgroup;再查 cat /sys/fs/cgroup/myapp/net_cls.classid 确认值一致
  • 误将限速设在 ingress(tc qdisc add dev eth0 ingress)会导致完全无效——ingress 在 Linux 中仅支持简单重定向,不支持速率整形

星耀云
版权声明:本站原创文章,由 星耀云 2026-01-05发表,共计1881字。
转载说明:转载本网站任何内容,请按照转载方式正确书写本站原文地址。本站提供的一切软件、教程和内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。
text=ZqhQzanResources