如何限制容器的网络带宽
为什么需要限制网络带宽
在生产环境中,多个容器共享同一台主机的网络资源。如果某个容器占用过多带宽,可能导致其他服务的网络延迟增加甚至超时。限制容器网络带宽的作用包括:
- 防止资源争抢:避免单个容器耗尽带宽影响其他服务
- 保障关键业务:确保核心服务获得足够的网络资源
- 成本控制:在云环境按流量计费时,限制非关键服务的带宽消耗
- 避免连锁故障:网络拥堵可能触发服务雪崩
常用带宽限制方案
方案一:使用 tc(Traffic Control)
Linux 内核的流量控制工具,通过调整网络接口的队列规则实现带宽控制。
# 限制容器 eth0 的出口带宽为 1Mbps
tc qdisc add dev eth0 root tbf rate 1mbit burst 32kbit latency 400ms
# 限制入口带宽(需要 ifb 模块)
modprobe ifb
ip link set ifb0 up
tc qdisc add dev eth0 ingress
tc filter add dev eth0 parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev ifb0
tc qdisc add dev ifb0 root tbf rate 1mbit burst 32kbit latency 400ms
不过直接在容器内执行 tc 不太方便,而且容器重启后会丢失。
方案二:Docker 原生支持(–network 与内核配合)
Docker 本身没有直接提供 --bandwidth 参数,但可以通过 内核网络命名空间 + tc 的方式在宿主机上对容器的 veth 接口限速。
获取宿主机上容器的 veth 接口名:
# 获取容器 PID
PID=$(docker inspect -f '{{.State.Pid}}' container_name)
# 通过 PID 找到对应的 veth 接口(在宿主机上)
ip link | grep "veth"
根据 veth 接口名在宿主机上执行 tc:
tc qdisc add dev vethXXXX root handle 1: htb default 30
tc class add dev vethXXXX parent 1: classid 1:1 htb rate 10mbit
tc filter add dev vethXXXX protocol ip parent 1:0 prio 1 u32 match ip dst 0.0.0.0/0 flowid 1:1
方案三:网络插件方案(推荐)
如果使用 Docker Overlay 网络 或 Kubernetes,推荐使用 CNI 插件来管理带宽:
Weave Net
# 创建带带宽限制的网络
docker network create --driver weave \
--opt bandwidth=10mbit weave-net
Calico
Calico 支持 NetworkPolicy 结合限速配置,通过 egress/ingress 规则控制流量。
方案四:使用 docker-cli wrapper 或工具
wondershaper 是一个简单易用的 shell 脚本,可对接口限速:
# 在容器内安装并限制
apt-get install -y wondershaper
wondershaper eth0 1024 1024 # 上行和下行均为 1Mbps
生产环境最佳实践
- 优先使用编排平台的功能:Kubernetes 可通过 QOS 和 CNI 插件统一管理带宽
- 限制非关键服务的带宽:日志采集、数据备份等后台任务应当限速
- 监控与动态调整:结合 Prometheus 等监控工具,动态调整带宽限制
- 预留带宽:为关键服务预留最低保障带宽
- 分层限制:在容器、主机、网络设备三层同时做限制
常见问题
Q:限制带宽后容器性能下降明显?
A:带宽限制只在流量达到阈值时才生效,空闲时不会影响性能。如果持续受限,说明该容器确实需要调整带宽配额。
Q:tc 命令在容器内执行报错?
A:需要容器拥有 NET_ADMIN 能力(--cap-add=NET_ADMIN),或者直接在宿主机上对 veth 接口操作。
Q:限制 UDP 流量也有效吗?
A:tc 默认限制所有流量,但更精细地限制 UDP 需要额外的 filter 规则。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END


暂无评论内容