iperf3 —— 网络带宽测试
一句话定义
iperf3 是测两点之间真实带宽的标准工具——一端跑 server、一端跑 client,client 持续往 server 推 / 拉数据 N 秒,输出实际吞吐。K8s 集群选 CNI / 排查"网络慢"必跑。
典型场景
- 装 K8s 之前:测节点间内网带宽
- CNI 选型对比:flannel vs cilium 各跑一遍看 overhead
- 排查"集群内通信慢":pod 间跑 iperf3
- 测公网出口
- 测跨可用区 / 跨机房链路
装
apt install -y iperf3 # Ubuntu / Debian
yum install -y iperf3 # CentOS / RHEL
brew install iperf3 # macOS
两端都要装 —— iperf3 是 client / server 模型。
注意:
iperf和iperf3是不同工具(v2 vs v3),互相不兼容——双方装版本要一致。现代用 iperf3。
基础:server + client
Server 端
# 在 m1 上
iperf3 -s
# Server listening on 5201
默认监听 5201/tcp。挂着,等 client 连。
Client 端
# 在 m2 上
iperf3 -c 10.0.24.28
# 默认 10 秒、TCP、单流
输出:
Connecting to host 10.0.24.28, port 5201
[ ID] Interval Transfer Bitrate
[ 5] 0.00-1.00 sec 115 MBytes 963 Mbits/sec
[ 5] 1.00-2.00 sec 116 MBytes 969 Mbits/sec
...
[ 5] 0.00-10.00 sec 1.13 GBytes 967 Mbits/sec receiver
Bitrate 列就是带宽。
Mbits/sec 是 bit。除以 8 = MB/s。
1 Gbps 实际看到 ~940-970 Mbits/sec 是正常的(含包头开销)。
核心 flag
iperf3 -c <server> # 默认 10 秒 TCP
iperf3 -c <server> -t 30 # 跑 30 秒
iperf3 -c <server> -t 0 # 无限跑(Ctrl-C 停)
iperf3 -c <server> -P 4 # 4 个并行流
iperf3 -c <server> -R # 反向:server → client
iperf3 -c <server> -u -b 100M # UDP,100 Mbps
iperf3 -c <server> -p 5202 # 自定义端口
iperf3 -c <server> -i 1 # 报告间隔 1 秒(默认 1)
iperf3 -c <server> -B 10.0.24.10 # client 绑定特定 IP
iperf3 -c <server> -J # JSON 输出(脚本用)
Server 端 flag
iperf3 -s # 默认 5201
iperf3 -s -p 5202 # 端口
iperf3 -s -D # 后台 daemon
iperf3 -s -B 10.0.24.28 # 绑定 IP
iperf3 -s -1 # 一次性(一个 client 结束就退出)
TCP vs UDP
TCP(默认)—— 测带宽
iperf3 -c m1 -t 30
显示两端能跑多少 TCP 带宽——这就是应用看到的。
UDP —— 测带宽 + 丢包
iperf3 -c m1 -u -b 1G -t 30
-b 1G 让 UDP 以 1 Gbps 发。UDP 不会自动 backoff、你设多少发多少。输出多了丢包率 / jitter:
[ ID] Interval Transfer Bitrate Jitter Lost/Total
[ 5] 0.00-30.00 sec 3.5 GBytes 999 Mbits/sec 0.012 ms 30/2123000 (0.0014%)
跨机房 / 不稳定链路用 UDP 测丢包率。
并行流 -P
iperf3 -c m1 -P 4 -t 30
# 同时 4 个 TCP 流
重要场景:单流测出的带宽 < 链路实际能力,但多流加起来达到。
iperf3 -c m1 # 单流 4 Gbps
iperf3 -c m1 -P 4 # 4 流 = 9.5 Gbps
10G 链路单流通常 4-5G、多流接近 9.5G——CPU / buffer 限制。测真实链路能力用 -P 4 或 -P 8。
反向测试 -R
iperf3 -c m1 # client → server 上行
iperf3 -c m1 -R # server → client 下行
双向都要测——不对称网络(家宽 / VPN)上下行差很多。
JSON 输出(自动化)
iperf3 -c m1 -t 10 -J > result.json
jq '.end.sum_received.bits_per_second' result.json
# 967834567
写监控脚本周期性测带宽抓异常。
实战场景
1. K8s 集群节点间带宽测试
# m1 跑 server
ssh m1 'iperf3 -s -D' # 后台
# m2 测到 m1 的带宽
ssh m2 'iperf3 -c 10.0.24.28 -t 10 -P 4'
# 反向测
ssh m2 'iperf3 -c 10.0.24.28 -t 10 -P 4 -R'
# 干掉 server
ssh m1 'pkill iperf3'
装 K8s 前测一遍:节点间内网带宽是否符合 1G / 10G 标称。
2. CNI 性能对比
测装 CNI 之前 / 之后(pod 间)的带宽:
# 节点间(baseline)
iperf3 -c <m1-IP> -P 4
# pod 间(跨节点)
kubectl run iperf-server --image=networkstatic/iperf3 --port=5201 --command -- iperf3 -s
kubectl run iperf-client --image=networkstatic/iperf3 --rm -it --command -- iperf3 -c iperf-server -P 4
CNI overhead = baseline - pod 间。
VXLAN 通常 5-15% overhead。eBPF(cilium)更小。
3. 测 LoadBalancer / Ingress 入口
# Service NodePort 暴露 iperf3 server
kubectl expose pod iperf-server --type=NodePort --port=5201
# 外部测
iperf3 -c <node-IP> -p <NodePort>
4. 跨可用区带宽 / 延迟
# AZ-A 节点跑 server
ssh az-a-1 'iperf3 -s -D'
# AZ-B 节点测
ssh az-b-1 'iperf3 -c az-a-1 -t 30 -P 4'
# 加上 mtr 看延迟分布
mtr -rn -c 30 az-a-1
5. 测公网
iperf 公网 server 列表(互联网上有公开的):
iperf3 -c iperf.he.net -t 30
iperf3 -c speedtest.serverius.net -t 30 -P 4
具体可用列表搜 "iperf3 public servers"。
常见踩坑
坑 1:版本不匹配
iperf3 -c m1
# iperf3: error - control socket has closed unexpectedly
两端 iperf3 版本差很多。装一致版本:
iperf3 -v # 看版本
apt install -y iperf3=3.16-* # 装特定版本
坑 2:firewall 挡 5201
iperf3 -c m1
# unable to connect to server: Connection refused / timeout
# Server 端开放端口
ssh m1 'ss -lntp | grep 5201' # 看 server 监听了没
iptables -L -n | grep 5201 # 看防火墙
云上通常要安全组放行 5201/tcp(UDP 测试要 5201/udp)。
坑 3:单流跑不满
iperf3 -c m1
# 4 Gbps(10G 链路)
不是网络限制——CPU / 单 TCP 流性能限制。加 -P 4:
iperf3 -c m1 -P 4
# 9.5 Gbps
10G NIC 通常需要多流 + 大 MTU + offload 才能跑满。
坑 4:UDP 测出来很低
iperf3 -c m1 -u -b 1G
# 实际跑 100 Mbps
UDP 默认 -b 1M。设要发多少:
iperf3 -c m1 -u -b 1G # 1 Gbps
iperf3 -c m1 -u -b 10G # 10 Gbps
但 UDP 发多少接收多少(不会 backoff)—— 注意会真把链路打满、影响别的流量。
坑 5:测 K8s pod 网络但抓不到 pod IP
# Pod 之间测
kubectl exec iperf-client -- iperf3 -c iperf-server-svc
# 实际走 service ClusterIP,含 kube-proxy DNAT overhead
要直接 pod-to-pod 用 PodIP:
kubectl get pod iperf-server -o jsonpath='{.status.podIP}'
# 10.244.0.5
kubectl exec iperf-client -- iperf3 -c 10.244.0.5
坑 6:忘了 stop server
ssh m1 'iperf3 -s -D' # 后台跑了
# 一直跑着、占 5201 端口、占内存
ssh m1 'pkill iperf3'
或者用 -1(one-shot):
ssh m1 'iperf3 -s -1' # 一个 client 跑完自动退
坑 7:报 "broken pipe" 或 "connection reset"
iperf3 -c m1
# iperf3: error - control socket has closed unexpectedly
可能:
- 中间 NAT timeout(长跑测试断了)
- MTU 不匹配
- TCP buffer 太小
# 缩短测试 + 多流
iperf3 -c m1 -t 10 -P 4
坑 8:测出来吞吐 = 0
iperf3 -c m1
# 0.00-1.00 sec 0 Bytes 0 bits/sec
实际网络断了 / TCP 阻塞。看 ss -tn 看连接状态、tcpdump 抓包。
坑 9:测一边强一边弱
iperf3 -c m1 # 10 Gbps
iperf3 -c m1 -R # 100 Mbps
很常见——不对称网络 / 出口策略 / 防火墙单向限速。继续 mtr 看路径。
坑 10:iperf3 不支持 multi-client
ssh m1 'iperf3 -s'
# 然后多个 client 同时连
# 一个连了之后、其它的等
iperf3 server 一次只服务一个 client。要并发测试 → 启动多个 server(不同端口)或者用 iperf2。