Docker容器网络限速与过滤需借助Linux内核工具:用tc在宿主机端veth接口配置egress带宽限制,用iptables的physdev模块在FORWARD链实现容器级包过滤,操作前须准确定位对应veth接口。

在 Docker 中配置容器网络流量限速和精准数据包过滤,不能依赖 docker run 原生命令直接实现——Docker 官方至今未提供 --network-bandwidth 或内置包过滤开关。实际操作必须借助 Linux 内核原生能力:以 tc 控制带宽,用 iptables(或 nftables)匹配并过滤特定数据包。核心前提是准确定位容器在网络栈中的“接入点”,即宿主机侧的 veth 接口。
定位容器对应的 veth 接口
每个桥接网络下的容器,在宿主机上都对应一个 veth* 虚拟网卡。这是所有后续操作的起点:
- 查容器 IP 和 MAC 地址:
docker inspect CONTAINER_NAME | grep -A 5 "IPAddress\|MacAddress" - 根据 MAC 查 veth 名称:
ip -br link show | grep -B1 'aa:bb:cc:dd:ee:ff'(替换为实际 MAC) - 确认接口归属(可选):
cat /sys/class/net/veth*/address | grep -A1 'aa:bb:cc:dd:ee:ff'
用 tc 实现单容器级带宽限速
限速必须作用于 veth 的宿主机端(如 vethabcd12),且仅对出向(egress)生效最稳定。入向(ingress)需 ifb 模块,一般不推荐初用:
- 限制出向总带宽为 3Mbps:
tc qdisc add dev vethabcd12 root tbf rate 3mbit burst 32kbit latency 400ms - 若需分层控制(如保底 + 借用),改用 HTB:
tc qdisc add dev vethabcd12 root handle 1: htb default 30,再添加 class 和 filter - 删除现有规则(重置前必做):
tc qdisc del dev vethabcd12 root
用 iptables 实现容器粒度的数据包过滤
过滤规则应部署在宿主机的 FORWARD 链,匹配经由 veth → docker0 → 外部的流量。关键在于用 physdev 模块识别物理出入接口:
- 禁止该容器访问某 IP 段:
iptables -I FORWARD -m physdev --physdev-in vethabcd12 -d 192.168.100.0/24 -j DROP - 只允许容器发 HTTP/HTTPS 流量:
iptables -I FORWARD -m physdev --physdev-in vethabcd12 -p tcp -m multiport --dports 80,443 -j ACCEPT,再加一条-j DROP拦截其余 - 记录匹配包用于调试:
iptables -I FORWARD -m physdev --physdev-in vethabcd12 -p icmp -j LOG --log-prefix "ICMP_FROM_CONTAINER: "
注意事项与验证方法
规则生效后需验证是否真正作用于目标容器,避免误配影响全局:
-
tc qdisc show dev vethabcd12确认限速队列已加载 -
iptables -L FORWARD -v -n | grep vethabcd12查看匹配计数器是否递增 - 在容器内用
iperf3 -c SERVER_IP测试带宽,或用curl -sI http://example.com | head -1验证过滤逻辑 - 容器重启后
veth名称会变,脚本化管理或使用docker-limit类工具可自动同步规则











