如果你想采用一种更稳定、更通用的容器网络带宽限制方案,通常推荐直接在宿主机上,针对容器对应的 veth 虚拟网卡配置 tc 限速规则。原因也很明确:Docker 原生命令本身并不提供带宽限制功能,这类网络流量控制需要交给 Linux 的 tc 工具来完成,而且实际操作位置是在宿主机的网络命名空间中。具体实施时,一般需要先定位容器对应的 veth 接口,再通过添加 tbf 或 htb 规则实现出口带宽限速。另外还有一点非常关键:规则成功添加只是第一步,后续的持久化管理和自动清理机制同样需要提前规划。

目前最稳定且通用的做法,是在宿主机上为容器对应的 veth 虚拟网卡配置 tc(Traffic Control) 限速规则。由于 Docker 原生命令不支持网络带宽限制,因此必须借助 Linux 内核提供的 tc 工具,在宿主机网络命名空间中完成操作——无需进入容器内部,也不依赖额外镜像,同时还能降低权限管理与安全风险。
定位容器对应的 veth 接口
在桥接网络模式下,每个容器在宿主机侧通常都会对应一条 vethxxx 虚拟网卡,一端连接容器内的 eth0,另一端挂载到 docker0(或自定义 bridge 网桥)上。实际需要操作的是宿主机这一侧的 veth 接口:
- 查询容器 IP 和 MAC 地址:
docker inspect myapp | grep -A 5 "IPAddress|MacAddress" - 根据 MAC 地址定位 veth 名称:
ip -br link show | grep -B1 'aa:bb:cc:dd:ee:ff' | head -1 | awk '{print $1}' - 检查接口状态是否正常:
ip link show vethabcd12(通常应为 UP 状态)
用 tc 添加出口限速规则
带宽限制默认只作用于容器发往外部的流量,也就是 egress 出向流量,路径为:容器 → 宿主机 → 外网。规则必须配置在 veth 的宿主机端,并且执行相关命令需要 root 权限:
- 简单固定带宽限速(适合初次使用,推荐优先尝试):
tc qdisc add dev vethabcd12 root tbf rate 2mbit burst 32kbit latency 400ms - 先清除已有规则再重新设置(可避免规则冲突):
tc qdisc del dev vethabcd12 root - 如果需要保底带宽加弹性分配(例如多个容器共享总带宽),可以改用 HTB:
tc qdisc add dev vethabcd12 root handle 1: htb default 30tc class add dev vethabcd12 parent 1: classid 1:1 htb rate 2mbit ceil 3mbit
验证与注意事项
可以通过以下命令查看当前生效的限速规则:tc qdisc show dev vethabcd12
- 当前规则仅影响出向流量;如果要限制入向(ingress)带宽,通常需要借助 ifb 模块做流量重定向,配置复杂度较高,大多数场景下并不必要
- 容器销毁后,相关 tc 规则不会自动清除,建议结合脚本处理,或监听
docker events --filter 'event=destroy'事件自动清理 - 在
--network=host模式下,无法按单个容器粒度做网络限速,因为此时网络栈与宿主机完全共享
集群与自动化延伸
在单节点、多容器的环境中,容器网络带宽控制通常有两种常见方案:一种是给每个 veth 接口分别挂载 tbf 规则;另一种是使用 htb 统一划分 class,对不同容器的带宽配额进行集中管理。放到 Kubernetes 场景中,更稳妥的思路通常是优先选择支持 bandwidth 能力的 CNI 插件,例如 Calico + bandwidth plugin,或者 Cilium eBPF,然后通过 Pod annotation 以声明式方式完成带宽限速配置。除此之外,也可以直接使用 wondershaper vethabcd12 2048 0 这样的命令简化带宽控制操作(单位为 KB/s,其中上行设置为 0 表示不限速),这种方式更适合 CI/CD 流程中的临时测试环境,或者快速验证场景。
