V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
Ansen
V2EX  ›  Linux

请教一下如何优雅的使用 TC 对大量的 IP 限速

  •  
  •   Ansen · 117 天前 · 3521 次点击
    这是一个创建于 117 天前的主题,其中的信息可能已经有所发展或是发生改变。
    使用一台 ubuntu 22.04 为 100 个 IP 提供 nat 上网服务,目前我们需要对这 100 个 IP 进行限速

    假设总带宽为 1000mbit ,需要对每个 IP 的最大带宽限制为 10mbit ,且保证每个 IP 的带宽为 10mbit

    看了相关教程后,目前我能想到的是为每个 IP 都创建一个 rate 为 10mbit 的 htb 类配合 sfq 来进行限速
    这样就意味着 如果 3000 个 IP 就会有 3000 个 htb 子类和 sfq 规则, 这一点都不优雅了, 而且如此多的规则管理起来也是个麻烦事



    经过多次查找资料后, 有一个思路就是 将 N 个 IP 加到 ipset 集合里面中去, 然后在 mangle 中对这个集合添加 fwmark,

    然后 添加 tc filter 时匹配 该 fwmark, 理论上只需要添加一个 10mbit htb 类和 sfq 就行了


    但是根据我查到的资料, 同一个 htb 类下, 所有在线的成员平分该 htb 的 rate , 这就会导致 一个人使用时是 10mbi 带宽, 两个人同时使用就是 5mbit 的带宽了

    这就达不到最开始的需求了: 每个 IP 需要保证 10mbit 的带宽且最大仅可使用 10mbit 的带宽, 哪怕总带宽还有剩余


    PS: 隔壁公司装修, 吵得脑子都大了, 表述可能有点啰嗦了, 请见谅
    27 条回复    2024-08-09 14:41:07 +08:00
    zizon
        1
    zizon  
       117 天前
    没什么不优雅吧.你的需求确实就是要对每个 IP 单独 quality...

    写个脚本或者工具去管理就是了...
    Ansen
        2
    Ansen  
    OP
       117 天前
    @zizon #1 前期还好, 后面可能会有 10 几万 IP
    Ansen
        3
    Ansen  
    OP
       117 天前
    @Ansen #2 如果能通过 ipset 配置, 我只需要按带宽等级创建一些规则就可以了, 比如 10 15 20 30 分别一个规则, 然后通过管理 ipset 列表 达到 控制客户端 IP 使用不同的带宽的目的
    blackeeper
        5
    blackeeper  
       117 天前
    我觉得你可能需要一个路由器,比如 openwrt 、ikuai ?
    IP 限速不仅有 web 界面,操作也非常方便
    Ansen
        6
    Ansen  
    OP
       117 天前
    @blackeeper 肯定是业务需要了, 上面还会跑其它相应的 ACL 程序
    blackeeper
        7
    blackeeper  
       117 天前
    @Ansen 这些路由器也可以跑 ACL 的,都是 Linux 系统。
    而且这个路由器,你可以作为旁路由,不用替换掉你的 Ubuntu 服务器
    Ansen
        8
    Ansen  
    OP
       117 天前 via iPhone
    @blackeeper 实际业务场景很复杂,qos 只是里面的一个功能
    datocp
        9
    datocp  
       117 天前 via Android   ❤️ 2
    为什么你有 10 几万的 ip ???
    可不能教电信网管做坏事

    qos 最佳的学习从 tomato 入手。当你会 shell 写了 N 遍 tc 规则,就用 tomato 的 4 段 htb 就足够。

    再去研究下 iptables connbytes ,会发现又一片新大陆,原来可以以 1 秒抓到当前系统那些假定超过多少流量的 ip 。

    然后就看 shell 水平插值到 4 段 htb

    最终实现 100mbps
    将 60%的流量用于下载用户,高优先级
    将 100%的流量用于其他用户,实际怎么也还有 40%,次优先级
    上行用 1:2 限制了 p2p 到 80%无法淹没 20%的高优先级上行队列。
    通过用 shell 对下行变化的 ip 进行插值到 htb 树,就实现了动态限速,做到 100%的带宽利用。

    平时 100mps 吹牛带了 280+ip ,无视任何 p2p 存在。
    PTLin
        10
    PTLin  
       117 天前   ❤️ 2
    tc 基于 ebpf 的 edt 方案看来可以,直接用 epbf map 管理 ip 。
    Ansen
        11
    Ansen  
    OP
       117 天前 via iPhone
    @datocp 感谢指点,哈哈,具体业务不方便说,但是不是三大运营商
    Ansen
        12
    Ansen  
    OP
       117 天前 via iPhone
    @PTLin 我也看到 edt 了,但是资料少的可怜🥺(有可能是我没找到?) ,然后问 gpt ,又全是胡言乱语
    PTLin
        13
    PTLin  
       116 天前   ❤️ 1
    @Ansen 有一篇字节跳动写的文章试了下,确实可以跑,就是限速不是太稳定以及限速公式搞不明白。https://blog.csdn.net/ByteDanceTech/article/details/120878281
    defunct9
        14
    defunct9  
       116 天前
    开 ssh ,让我上去看看
    cslive
        15
    cslive  
       116 天前 via Android
    openwrt 怎么实现的,参考下
    kalayygl001
        16
    kalayygl001  
       116 天前
    直接 panabit 就好
    100M/100M 专线+1000M/50M pppoe 带 500 人
    做好应用分流
    相当流畅
    Ansen
        17
    Ansen  
    OP
       116 天前
    @kalayygl001 #16 目前没办法用其它设备来限速了, 项目方案已经确定了, 只有在 linux 上想办法了
    Donaldo
        18
    Donaldo  
       114 天前   ❤️ 1
    我没用过 tc ,之前用过 xdp 做防火墙,调研了一下说性能比 tc 好,考虑用 ebpf (可能结合 tc )么?这里找到了一个例子: https://github.com/xdp-project/xdp-cpumap-tc
    huangzhiyia
        19
    huangzhiyia  
       114 天前
    tc qdisc del dev $1 root
    tc qdisc add dev $1 root handle 1: htb default 20
    tc class add dev $1 parent 1:0 classid 1:1 htb rate 10mbit burst 1000mbit
    tc qdisc add dev $1 parent 1:1 handle 10: sfq
    tc filter add dev $1 parent 1: protocol ip prio 16 u32 match ip dst 0.0.0.0/0 flowid 1:1

    直接对所有 IP 进行限速,速率为 10mbit 突发 1000mbit ,连空闲宽带都不想给,就把突发也改成 10 mbit 即可。
    Ansen
        20
    Ansen  
    OP
       114 天前
    @zmaplex #19 这个脚本的实际效果是 所有 IP 加起来的速度不能超过 classid 1:1 中的 10mbit , 多个用户同时在线,每个用户的带宽就是 10mbit 除以 n
    这是我的测试结果

    Ansen
        21
    Ansen  
    OP
       114 天前
    @Ansen #20 我想要达到的结果是, 所有用户都能独享且最多能 10mbit
    huangzhiyia
        22
    huangzhiyia  
       114 天前   ❤️ 1
    @Ansen

    #!/bin/sh -e


    # 清除现有的 qdisc
    tc qdisc del dev ens33 root
    tc qdisc del dev ens33 ingress

    # 配置上传( egress )限速
    tc qdisc add dev ens33 root handle 1: htb default 30
    tc class add dev ens33 parent 1: classid 1:1 htb rate 10000kbit burst 15k

    # 限制特定 IP 地址的上传
    tc class add dev ens33 parent 1:1 classid 1:10 htb rate 10000kbit
    tc filter add dev ens33 protocol ip parent 1:0 prio 1 u32 match ip dst 192.168.102.134 flowid 1:10

    tc class add dev ens33 parent 1:1 classid 1:20 htb rate 10000kbit
    tc filter add dev ens33 protocol ip parent 1:0 prio 1 u32 match ip dst 192.168.102.135 flowid 1:20

    # 限制所有 IP 地址的上传
    tc class add dev ens33 parent 1:1 classid 1:30 htb rate 10000kbit
    tc filter add dev ens33 protocol ip parent 1:0 prio 2 u32 match ip dst 0.0.0.0/0 flowid 1:30

    # 配置下载( ingress )限速
    tc qdisc add dev ens33 handle ffff: ingress

    # 限制特定 IP 地址的下载
    tc filter add dev ens33 parent ffff: protocol ip prio 1 u32 match ip src 192.168.102.134 police rate 10000kbit burst 10k drop flowid :1
    tc filter add dev ens33 parent ffff: protocol ip prio 1 u32 match ip src 192.168.102.135 police rate 10000kbit burst 10k drop flowid :1

    # 限制所有 IP 地址的下载
    tc filter add dev ens33 parent ffff: protocol ip prio 2 u32 match ip src 0.0.0.0/0 police rate 10000kbit burst 10k drop flowid :1

    exit 0
    huangzhiyia
        23
    huangzhiyia  
       114 天前
    我测试的时候,这个是只有 7 Mbits/sec 左右,然后把 10000kbit 改成 15mbit 的时候,测试差不多就是 10 Mbits/sec 了
    huangzhiyia
        24
    huangzhiyia  
       114 天前
    @Ansen 不好意思,把特定 ip 写进去了,还是无效。看来没有太好的办法
    Ansen
        25
    Ansen  
    OP
       114 天前
    @zmaplex #24 是的,目前 class 和 ip 一对一的情况下,是能做到我的需求的, 但是一旦 IP 数量多了,管理上就会变得很困难
    dode
        26
    dode  
       99 天前
    一万个 IP 出去之前加一个交换机,交换机上设置 IP 限速
    Ansen
        27
    Ansen  
    OP
       97 天前
    @dode #26 交换机拿不到隧道的 IP
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5913 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 02:36 · PVG 10:36 · LAX 18:36 · JFK 21:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.