iperf3を使ったLinux Serverのネットワーク速度測定とパフォーマンス診断

Network tutorial - IT technology blog
Network tutorial - IT technology blog

先週、チームで厄介な問題に対処した:アプリケーションが異常に遅くなり、開発者はデータベースのタイムアウトを訴え、DBAはクエリは速いと言い張っていた。2時間かけてログのデバッグとプロファイリングをした結果、原因は夕方になるとアプリサーバーとDBサーバー間の帯域幅が詰まっていることだとわかった。残念なのは、最初からiperf3で確認していれば5分で原因を特定できたはずだということだ。

それ以来、iperf3はネットワークに問題があると疑ったときに最初に実行するツールになった。この記事では、ネットワーク測定ツールを比較しながら、実際のシナリオでiperf3を正しく使う方法を紹介する。

ネットワークパフォーマンス測定ツール — どれをいつ使うか?

speedtest-cli — インターネット接続速度のみを測定

speedtest-cliはOoklaのサーバーに接続してダウンロード/アップロード速度を測定する。ISPが契約通りの速度を提供しているか確認したいときに便利だが、同じデータセンターやVPC内の2台のサーバー間の内部帯域幅を測定する場合にはまったく役に立たない。インターネット経由で測定するため、内部ネットワークは計測できないのだ。

netperf — クラシックだが時代遅れ

netperfは90年代に登場し、TCP/UDPの測定をサポートしており、詳細なメトリクスが豊富だ。問題は、このプロジェクトのメンテナンスが少なく、ドキュメントが古く、構文がiperf3より覚えにくい点だ。一部の最新ディストリビューションでは公式リポジトリに含まれていない。何度か試してみたが、iperf3の代わりに使う理由が見つからなかった。

iperf3 — DevOpsの標準的な選択肢

最も信頼しているのはiperf3だ。アメリカエネルギー省の研究ネットワークであるESnetによってメンテナンスされているため、コードはかなり堅牢だ。TCP・UDP、パラレルストリーム、リバースモード、自動化のためのJSON出力など、必要な機能が揃っている。ほとんどのディストリビューションの公式リポジトリに含まれており、インストール後すぐに使える。特別な設定は不要だ。

iperf3:強みと事前に知っておくべきこと

メリット:

  • 2台のサーバー間のポイント・ツー・ポイントの実際の帯域幅を測定 — インターネットに依存しない
  • UDPモードでパケットロスとジッターを検出 — TCPは速度を自動調整するため問題を隠してしまう
  • パラレルストリームで実際のトラフィックのような複数の同時接続をシミュレート
  • モニタリングスクリプトへの統合のためのJSON出力
  • リバースモードで双方向の帯域幅を確認
  • 軽量で複雑な設定が不要

知っておくべき制限:

  • 両端(サーバーとクライアント)にインストールして実行する必要がある
  • サーバー側のファイアウォールでポート5201を開放する必要がある
  • 外部へのインターネット接続速度は測定できない
  • iperf3はiperf2と後方互換性がない(プロトコルが完全に異なる)

状況に合ったツールの選択

何かインストールする前に、何を測定したいのかを明確にしよう:

  • ISPが約束した速度を提供しているか? → speedtest-cli
  • 内部サーバー間の帯域幅? → iperf3 TCPモード
  • ネットワークにパケットロスやジッターがあるか? → iperf3 UDPモード
  • InfiniBand/RDMAネットワーク(HPC環境)? → qperf
  • ツールをインストールせずに素早くテストしたい?curl + 内部サーバーからのファイルダウンロード(精度は劣るが便利)

Linuxへのiperf3のインストール

ほとんどのディストリビューションの公式リポジトリにiperf3が含まれており、インストール後すぐに使える:

# Ubuntu / Debian
sudo apt update && sudo apt install iperf3

# CentOS / RHEL / Rocky Linux
sudo dnf install iperf3

# Arch Linux
sudo pacman -S iperf3

インストール後のバージョン確認:

iperf3 --version
# iperf 3.14 (cJSON 1.7.15)

基本的な使い方 — サーバーとクライアント

基本的なモデルはシンプルだ:片方がサーバーモードで接続を待ち受け、もう片方のクライアントがテストを開始する。バックグラウンドでデーモンを常駐させる必要はない — 必要なときにサーバーを起動し、終わったら停止する。

サーバー側(接続を受け付ける側):

# フォアグラウンドで実行、ポート5201でリッスン
iperf3 -s

# バックグラウンドで実行してログを記録
iperf3 -s -D --logfile /var/log/iperf3.log

クライアント側(テストを開始する側):

# 基本テスト:TCP、10秒、1ストリーム
iperf3 -c 192.168.1.100

# より長いテスト — 30秒
iperf3 -c 192.168.1.100 -t 30

# 5GB転送後に停止(時間指定の代わりに)
iperf3 -c 192.168.1.100 -n 5G

正常なGigabitリンクの出力例:

[ ID] Interval           Transfer     Bitrate
[  5]   0.00-1.00   sec   112 MBytes   940 Mbits/sec
[  5]   1.00-2.00   sec   111 MBytes   933 Mbits/sec
...
[  5]   0.00-10.01  sec  1.09 GBytes   935 Mbits/sec    sender
[  5]   0.00-10.01  sec  1.09 GBytes   934 Mbits/sec    receiver

よく使う高度なオプション

パラレルストリーム — 実際のトラフィックをシミュレート

デフォルトでiperf3は1つのTCPストリームしか使わない。実際のアプリケーションは複数の接続を同時に開く。-Pを使って複数ストリームでテストしよう:

# 4つのストリームを並列で実行
iperf3 -c 192.168.1.100 -P 4

複数ストリームを使うと、特にレイテンシの高いリンクではTCPウィンドウスケーリングがより効果的に機能するため、合計帯域幅が高くなることが多い。

リバースモード — 逆方向の帯域幅を測定

# サーバーからクライアントへデータを送信(クライアント視点でのダウンロード)
iperf3 -c 192.168.1.100 -R

JSON出力 — 自動化への統合

iperf3 -c 192.168.1.100 -J > /tmp/result.json

# JSONからビットレートを取得
iperf3 -c 192.168.1.100 -J | python3 -c \
  "import sys,json; d=json.load(sys.stdin); print(d['end']['sum_received']['bits_per_second']/1e6, 'Mbps')"

UDPモード — パケットロスとジッターの検出

TCPはネットワークの問題を隠してしまう。パケットロスが発生すると、自動的に再送信して帯域幅を絞り込む — スループットが低いのはわかっても、原因がわからない。UDPにはそのような仕組みがない:パケットが失われれば、そのまま出力に報告される。パケットロスとジッターを正確に測定したい場合は、このモードを使うのが必須だ。

# ターゲット帯域幅1GbpsでUDPテスト
iperf3 -c 192.168.1.100 -u -b 1G

# 100Mbpsの帯域幅でテスト(1Gリンクの過負荷を避けるため)
iperf3 -c 192.168.1.100 -u -b 100M -t 30

UDP出力には重要な2つの列が追加される:

[ ID] Interval     Transfer   Bitrate     Jitter    Lost/Total Datagrams
[  5] 0.00-10.00   1.16 GBytes  998 Mbps  0.052 ms  847/885802 (0.096%)
  • Jitter:遅延のばらつき(ms)。LANでは1ms未満、WAN経由では10ms未満が理想
  • Lost/Total:パケットロス率。正常なLANでは0%であるべき。0.1%を超えたらすぐに調査が必要

断続的なパケットロスの診断 — 実体験

私が経験した最も難しいネットワーク問題のデバッグは、断続的なパケットロスがピーク時間帯(午前9〜11時と午後3〜5時)にしか発生しないケースだった。夜にiperf3で確認すると — 完全に正常で、パケットロス0%、940Mbps。翌朝再確認しても — やはり問題なし。

そこで、正確なタイミングを捉えるために継続的に実行してログを記録するスクリプトを書いた:

#!/bin/bash
# iperf3 UDPテストを5分ごとに実行してログに記録
SERVER="192.168.1.100"
LOGFILE="/tmp/iperf3_monitor.log"

for i in $(seq 1 288); do  # 288回 = 24時間
    TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
    RESULT=$(iperf3 -c $SERVER -u -b 1G -t 30 -J 2>/dev/null)
    LOSS=$(echo $RESULT | python3 -c \
        "import sys,json; d=json.load(sys.stdin); print(d['end']['sum']['lost_percent'])" 2>/dev/null)
    echo "$TIMESTAMP packet_loss=$LOSS%" >> $LOGFILE
    sleep 270  # 270秒休止 + 30秒テスト = 300秒(5分)
done

結果:ピーク時間帯にはパケットロスが2.3%まで上昇し、それ以外の時間は0%だった。原因を追跡すると、アップリンクスイッチ上のSFPモジュールが故障していて、トラフィックが増加すると負荷に耐えられなくなっていた。新しいSFPに交換して解決した。

iperf3のためのファイアウォール設定

テストの前に、サーバー側でポート5201を開放することを忘れずに:

# UFW (Ubuntu/Debian)
sudo ufw allow 5201/tcp
sudo ufw allow 5201/udp

# firewalld (CentOS/RHEL/Rocky)
sudo firewall-cmd --permanent --add-port=5201/tcp
sudo firewall-cmd --permanent --add-port=5201/udp
sudo firewall-cmd --reload

カスタムポートを使いたい場合(例:複数インスタンスの実行や競合を避ける場合):

# サーバーがポート9001でリッスン
iperf3 -s -p 9001

# クライアントがポート9001に接続
iperf3 -c 192.168.1.100 -p 9001

ネットワーク問題が疑われる際の素早い確認チェックリスト

  1. 基本的なTCPテストを実行 — 全体的な帯域幅が期待値に達しているか確認
  2. リンク容量の80%の帯域幅でUDPテストを実行 — パケットロスとジッターを確認
  3. -P 4(パラレルストリーム)で実行 — 複数の接続があるときにのみ現れる問題もある
  4. リバースモード-Rで実行 — 非対称ルーティングがある場合、双方向の帯域幅が異なることがある
  5. 断続的な問題の場合は、上記の例のようなスクリプトを使って時系列でモニタリングする

iperf3とss/netstatを組み合わせれば、Linuxのほとんどのネットワーク問題を特定できる。帯域幅のボトルネック、潜在的なパケットロス、非対称ルーティング — それぞれの問題には専用のテスト方法がある。重要なのはすべてのフラグを知ることではなく、実行前に正しい問いを立てることだ。

Share: