如何限制Docker镜像及容器的网络使用量或带宽?
限制Docker容器网络带宽/使用量的主机侧配置方案
我来给你分享几个不用修改Docker源码或容器内程序,纯靠主机配置就能实现容器网络限速的实用方案——都是生产环境里验证过的思路,完全满足你的需求:
核心逻辑
Docker容器的网络本质是主机网络命名空间的延伸,我们可以借助Linux内核自带的tc(流量控制)工具,直接操作容器对应的网络命名空间,或者主机侧的虚拟网卡(veth接口)来配置流量规则,全程不需要改动Docker或容器内的任何代码。
步骤1:定位容器的网络标识
首先得找到容器对应的网络入口,两种方式任选:
- 获取网络命名空间路径:这是最可靠的方式,执行命令拿到容器的网络命名空间挂载路径:
输出类似docker inspect -f '{{.NetworkSettings.SandboxKey}}' <容器名称或ID>/var/run/docker/netns/abc123def - 找到主机侧veth接口:执行
ip link查看所有网卡,找名字以veth开头的接口,再通过docker inspect <容器ID> | grep -A2 -B2 veth确认该接口对应的容器。
步骤2:配置容器出口带宽限制
用tc的TBF(令牌桶过滤器)实现稳定的出口限速,操作容器的网络命名空间即可:
# 替换成你的sandbox路径和目标限速值(这里是10Mbps) nsenter --net=/var/run/docker/netns/abc123def tc qdisc add dev eth0 root tbf rate 10mbit burst 10k latency 70ms
- 参数解释:
rate是长期稳定限速,burst是允许的临时突发流量,latency是令牌桶满时的最大等待延迟,按需调整即可。
步骤3:配置容器入口带宽限制
入口限速需要借助ifb虚拟接口中转流量,步骤稍多但同样简单:
- 先在主机上加载ifb模块并启用接口:
modprobe ifb ip link set dev ifb0 up
- 进入容器网络命名空间配置流量重定向和限速:
# 替换成你的sandbox路径和目标限速值(这里是5Mbps) nsenter --net=/var/run/docker/netns/abc123def tc qdisc add dev eth0 ingress nsenter --net=/var/run/docker/netns/abc123def tc filter add dev eth0 parent ffff: protocol ip u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev ifb0 nsenter --net=/var/run/docker/netns/abc123def tc qdisc add dev ifb0 root tbf rate 5mbit burst 10k latency 70ms
这样就把容器的入口流量限制在5Mbps以内了。
可选:直接操作主机侧veth接口
如果只是临时测试,也可以直接在主机的veth接口上配置规则:
# 替换成你的veth接口名和限速值 tc qdisc add dev vethabc123 root tbf rate 10mbit burst 10k latency 70ms
⚠️ 注意:容器重启后veth接口会重新生成,所以这种方式只适合临时场景,长期使用建议用下面的持久化方案。
持久化配置:自动为新容器限速
因为容器重启后网络标识会变化,我们可以写个脚本监听Docker启动事件,自动为新启动的容器配置限速规则:
#!/bin/bash # 提前加载ifb模块 modprobe ifb ip link set dev ifb0 up # 监听容器启动事件 docker events --filter 'event=start' | while read -r line; do CONTAINER_ID=$(echo "$line" | awk '{print $NF}') SANDBOX_PATH=$(docker inspect -f '{{.NetworkSettings.SandboxKey}}' "$CONTAINER_ID" 2>/dev/null) if [ -n "$SANDBOX_PATH" ]; then echo "Configuring rate limit for container $CONTAINER_ID..." # 配置出口限速10Mbps nsenter --net="$SANDBOX_PATH" tc qdisc add dev eth0 root tbf rate 10mbit burst 10k latency 70ms 2>/dev/null # 配置入口限速5Mbps nsenter --net="$SANDBOX_PATH" tc qdisc add dev eth0 ingress 2>/dev/null nsenter --net="$SANDBOX_PATH" tc filter add dev eth0 parent ffff: protocol ip u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev ifb0 2>/dev/null nsenter --net="$SANDBOX_PATH" tc qdisc add dev ifb0 root tbf rate 5mbit burst 10k latency 70ms 2>/dev/null fi done
把脚本保存为docker-rate-limit.sh,添加执行权限chmod +x docker-rate-limit.sh,再做成systemd服务开机自启:
# /etc/systemd/system/docker-rate-limit.service [Unit] Description=Docker Container Rate Limiter After=docker.service [Service] ExecStart=/path/to/docker-rate-limit.sh Restart=always [Install] WantedBy=multi-user.target
最后执行:
systemctl daemon-reload systemctl enable --now docker-rate-limit.service
这些方案完全基于主机侧配置,依赖Linux内核原生工具,兼容性和稳定性拉满,不用碰Docker或容器内的任何代码,完美匹配你的需求。
内容的提问来源于stack exchange,提问作者I Wonder
相关产品推荐
相关产品推荐

