限制容器带宽需在宿主机veth接口操作:上传(egress)直接用tbf限速;下载(ingress)须经ifb虚拟设备中转,先挂ingress捕获点、再重定向至ifb0、最后在ifb0上设tbf限速。

限制容器网卡的上传与下载带宽,本质是把 tc 规则施加在容器对应的虚拟网络接口上。关键不在于“能不能”,而在于“在哪设、对谁设、方向别搞反”。上传(egress)可直接限,下载(ingress)必须绕道 ifb;容器用的是 veth 设备,不是 eth0,也不能在容器内部随意操作——除非你开了 NET_ADMIN 权限。
先找准容器的真实网卡设备
容器内的 eth0 是虚拟网卡,它在宿主机上对应一个 vethxxx 接口(如 vetha1b2c3)。必须找到这个宿主机侧的 veth 设备,才能施加 tc 规则:
- 运行 docker inspect 容器名 | grep -A 10 "NetworkSettings",查看
EndpointID或MacAddress - 执行 ip link show | grep -B 1 "xx:xx:xx"(用容器 MAC 前几位搜索),定位到宿主机上的 veth 设备名
- 确认该 veth 状态为 UP:ip link show dev vethxxxx,避免对 down 状态接口配置失败
上传带宽(出向):直接在 veth 上用 tbf 限速
容器向外发包(比如响应 HTTP 请求、上传文件)属于 veth 的 egress 流量,在宿主机上对 veth 接口设 root qdisc 即可生效:
- 清除旧规则:tc qdisc del dev vethxxxx root 2>/dev/null
- 添加限速(例如限 3Mbps):sudo tc qdisc add dev vethxxxx root tbf rate 3mbit burst 32kbit latency 100ms
- 验证:tc -s qdisc show dev vethxxxx,观察 packets 和 drops 计数是否变化
注意:rate 单位是 mbit(兆比特/秒),不是 MB/s;burst 推荐设为 rate 的 1/10 左右(3mbit → ~32kbit 合理),latency 控制排队上限,40–200ms 较稳妥。
下载带宽(入向):必须用 ifb 虚拟设备中转
Linux 内核不允许直接对 ingress 流量做带宽整形,只能捕获后重定向到 ifb 设备,再以 egress 方式限速:
- 加载模块并启用 ifb:sudo modprobe ifb numifbs=1 && sudo ip link set dev ifb0 up
- 在 veth 上挂 ingress 捕获点:sudo tc qdisc add dev vethxxxx handle ffff: ingress
- 将所有入向流量镜像到 ifb0:sudo tc filter add dev vethxxxx parent ffff: protocol ip u32 match ip src 0.0.0.0/0 action mirred egress redirect dev ifb0
- 在 ifb0 上限速(例如限 2Mbps 下载):sudo tc qdisc add dev ifb0 root tbf rate 2mbit burst 20kbit latency 300ms
⚠️ 顺序不能颠倒:先有 ingress,再 filter 重定向,最后在 ifb0 上加 root qdisc。重启宿主机后 ifb0 会 down,脚本中需显式 ip link set dev ifb0 up。
清理规则要彻底,否则残留影响后续测试
单删 root 不够,ingress 和 ifb 都得清,否则统计错乱、限速失效甚至 SSH 卡顿:
- sudo tc qdisc del dev ifb0 root 2>/dev/null
- sudo tc qdisc del dev vethxxxx root 2>/dev/null
- sudo tc qdisc del dev vethxxxx ingress 2>/dev/null
- sudo ip link set dev ifb0 down 2>/dev/null
建议封装成一键清理脚本,每次重配前先运行一遍。

















