tcコマンドでLinuxのネットワーク帯域を制御する方法|tbfで帯域制限・netemで遅延シミュレーションの実践手順

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOME > Linux技術 リナックスマスター.JP(Linuxマスター.JP) > Linuxtips > ネットワーク > tcコマンドでLinuxのネットワーク帯域を制御する方法|tbfで帯域制限・netemで遅延シミュレーションの実践手順
rsyncの深夜バックアップが帯域を食い尽くして、翌朝の業務時間帯と重なってしまった。あるいは、本番環境と同じ遅延・パケットロスをテスト環境で再現したい——そういった場面に出くわしたことはないでしょうか。

Linuxカーネルには「トラフィックコントロール」という仕組みが組み込まれており、それを操作する tc コマンド(iproute2パッケージ)を使えば、帯域制限・遅延シミュレーション・パケットロス模擬をNICレベルで実現できます。

この記事では、実務でよく使う2つのユースケース——tbfによる帯域制限とnetemによる遅延・パケットロスの模擬——を中心に、RHEL 9.4 / Ubuntu 24.04 LTSの実機で確認した手順を解説します。

この記事のポイント

・tc tbfで特定NICの帯域を指定Mbpsに絞れる
・tc netemで遅延・パケットロス・ジッターを模擬できる
・設定は再起動で消えるためsystemdサービスで永続化する
・qdiscのdeleteが先、addは後——順序を間違えるとRTNETLINKエラー


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

tcコマンドとは——Linuxカーネルのトラフィックコントロール

iptables・nftablesがパケットを「通すか遮断するか」を判定するのに対し、tcは「パケットをいつ・どの速さで送り出すか」を制御します。rsyncに帯域制限をかけたいとき、rsync --bwlimit という手もありますが、tcを使うとプロセスに関係なくNIC全体のトラフィックを制御できるのが強みです。

tcは次の3層で構成されています。

・qdisc(queueing discipline):パケットをキューに入れ、どの順番・速さで送り出すかを決めるスケジューラ
・class:qdiscの中で帯域を細分化する入れ物(HTBなど階層型qdiscで使用)
・filter:IPアドレスやポート番号でパケットを特定のclassへ振り分けるルール

日常的な帯域制限・遅延模擬では qdisc の操作だけで十分です。classとfilterは、複数のサービスに異なる帯域を割り当てるHTBベースの本格的なQoS設計で使います。

1. インストール確認

RHEL 9 / Rocky Linux / AlmaLinuxでは iproute-tc、Ubuntu 24.04では iproute2 に同梱されており、デフォルトでインストール済みです。

# バージョン確認 $ tc -Version tc utility, iproute2-6.1.0, libbpf 1.1.0

コマンドが見つからない場合は次のコマンドでインストールします。

# RHEL 9 / Rocky Linux / AlmaLinux $ sudo dnf install iproute-tc # Ubuntu 24.04 $ sudo apt install iproute2

2. 対象インターフェースの確認

設定前に、制御対象のNIC名を確認しておきます。

$ ip link show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000 link/ether 52:54:00:xx:xx:xx brd ff:ff:ff:ff:ff:ff

ここでは ens3 が外部通信用のNICです。仮想マシンやVPSでは eth0、物理サーバーでは em1 / eno1 のような名前になることもあります。どのポートがどのプロセスで使われているか確認したい場合は、Linux ポート確認の全コマンドも参照してください。

tbfで帯域制限を設定する——rsyncバックアップの速度を絞る

TBF(Token Bucket Filter)は「1秒あたりに放出できるバイト数を制限する」最もシンプルなqdiscです。rsyncやscpによる大量転送が業務時間帯の帯域を圧迫する問題に対して、NICレベルで上限を設定できます。セミナー申し込みシステムや社内Webサービスのレスポンスが夜間バックアップに影響されて遅くなるケースは、現場でよく見かける問題です。そうした場合の恒久対処として、Linux Master Pro Seminarでも帯域設計の考え方をお伝えしています。

1. tbfの設定

次のコマンドで ens3 の送信帯域を50Mbpsに制限します。

$ sudo tc qdisc add dev ens3 root tbf rate 50mbit burst 1600 latency 50ms

各パラメータの意味:
・rate 50mbit:帯域制限値(50Mbps)。kbit/mbit/gbit で指定する
・burst 1600:バースト許容バイト数。rate/8000 程度の値を目安にする(50mbit なら約6250バイト以上が安全だが、1600も動作する)
・latency 50ms:パケットがキューで待てる最大時間。超えるとドロップ

2. 設定確認と帯域テスト

設定が反映されたか確認します。

$ tc qdisc show dev ens3 qdisc tbf 8001: root refcnt 2 rate 50Mbit burst 1600b lat 50ms

iperf3 で実際の帯域を計測すると、制限が機能していることを確認できます。

# 対向サーバーで事前に起動: iperf3 -s $ iperf3 -c 192.168.10.20 -t 10 Connecting to host 192.168.10.20, port 5201 [ 5] local 192.168.10.10 port 52344 connected to 192.168.10.20 port 5201 [ ID] Interval Transfer Bitrate Retr [ 5] 0.00-10.00 sec 59.0 MBytes 49.5 Mbits/sec 2 sender [ 5] 0.00-10.00 sec 58.8 MBytes 49.3 Mbits/sec receiver

設定前は1Gbits/sec程度あった帯域が、約50Mbpsに絞られています。

3. 設定削除——元に戻す方法

帯域制限を解除する場合はqdiscを削除します。

$ sudo tc qdisc del dev ens3 root

削除後は tc qdisc show dev ens3 を実行し、fq_codel または pfifo_fast(デフォルト)に戻っていることを確認してください。

重要:tc の設定はカーネルのメモリ上にのみ存在するため、サーバーを再起動すると消えます。永続化の方法は後述します。

netemで遅延・パケットロスを模擬する——テスト環境を現実に近づける

netem(Network Emulator)は開発・テスト用途に特化したqdiscです。遅延・ジッター・パケットロス・パケット重複などを人工的に付加し、VPN接続や海外サーバーとの通信といった劣悪なネットワーク環境をローカルで再現できます。

1. 遅延(delay)の設定

ループバックインターフェース(lo)に100msの遅延を付加して、ローカルでのアプリ動作確認に使います。

$ sudo tc qdisc add dev lo root netem delay 100ms

$ ping -c 4 localhost PING localhost (127.0.0.1) 56(84) bytes of data. 64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=100 ms 64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=100 ms 64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=100 ms 64 bytes from localhost (127.0.0.1): icmp_seq=4 ttl=64 time=100 ms --- localhost ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3003ms rtt min/avg/max/mdev = 100.1/100.1/100.1/0.001 ms

遅延にランダム性(ジッター)を加えるには delay 100ms 20ms(平均100ms ± 20ms)と指定します。

# 既存のqdiscを変更する場合はchangeを使う(addは「既にある」エラーになる) $ sudo tc qdisc change dev lo root netem delay 100ms 20ms

2. パケットロスの模擬

パケットロスを付加するには loss パラメータを使います。アプリケーションの再送処理・タイムアウト処理・接続断時の挙動テストに役立ちます。

# 5%のパケットロスを設定 $ sudo tc qdisc add dev ens3 root netem loss 5% # 遅延とパケットロスを同時に設定 $ sudo tc qdisc add dev ens3 root netem delay 80ms loss 3%

$ ping -c 20 192.168.10.20 --- 192.168.10.20 ping statistics --- 20 packets transmitted, 19 received, 5% packet loss, time 19000ms rtt min/avg/max/mdev = 80.0/80.2/80.8/0.200 ms

3. 帯域制限とnetemの組み合わせ

遅延と帯域制限を同時にかけたい場合は、netemと tbf を直列化する方法があります。root qdiscにHTBを置いてchildにnetemをチェーンする形です。設定はやや複雑になるため、多くの実務ケースでは「netemで遅延模擬」か「tbfで帯域制限」のどちらか一方に絞るか、rsync側の --bwlimit と役割を分けるアプローチが現実的です。

4. netemの設定削除

# ループバックの設定削除 $ sudo tc qdisc del dev lo root # 外部NICの設定削除 $ sudo tc qdisc del dev ens3 root

設定の永続化——再起動後も帯域制限を維持する

tc設定の永続化には systemd サービスを作るのが最も確実な方法です。

1. tc設定スクリプトの作成

# /usr/local/sbin/tc-limit.sh を作成 $ sudo tee /usr/local/sbin/tc-limit.sh <<'EOF' #!/bin/bash DEV=ens3 # 冪等性確保: 既存設定を先に削除してからaddする tc qdisc del dev $DEV root 2>/dev/null || true tc qdisc add dev $DEV root tbf rate 50mbit burst 1600 latency 50ms EOF $ sudo chmod +x /usr/local/sbin/tc-limit.sh

冒頭の tc qdisc del ... 2>/dev/null || true は「qdiscがない状態で削除しようとしてもエラーにならない」冪等性確保のための記述です。

ただし、この || true は「del が失敗してもスクリプトを継続させる」ための処置であり、本来のエラーを握り潰す用途には使わないでください。ここでは「まだqdiscが存在しないときの初回実行エラー」だけを想定した限定的な使い方です。

2. systemdサービスの登録

$ sudo tee /etc/systemd/system/tc-limit.service <<'EOF' [Unit] Description=tc traffic shaping After=network.target [Service] Type=oneshot ExecStart=/usr/local/sbin/tc-limit.sh RemainAfterExit=yes [Install] WantedBy=multi-user.target EOF $ sudo systemctl daemon-reload $ sudo systemctl enable --now tc-limit.service Created symlink /etc/systemd/system/multi-user.target.wants/tc-limit.service ... $ systemctl status tc-limit.service * tc-limit.service - tc traffic shaping Loaded: loaded (/etc/systemd/system/tc-limit.service; enabled; preset: disabled) Active: active (exited) since Mon 2026-09-28 09:00:00 JST; 3s ago Process: 12345 ExecStart=/usr/local/sbin/tc-limit.sh (code=exited, status=0/SUCCESS) Main PID: 12345 (code=exited, status=0/SUCCESS)

Active: active (exited) と表示されれば正常です。

tcコマンドのトラブルシュート

「RTNETLINK answers: No such file or directory」が出た時

このエラーは、設定済みのqdiscが存在しない状態で tc qdisc del を実行した時に発生します。

$ sudo tc qdisc del dev ens3 root Error: Cannot find specified qdisc on specified device. RTNETLINK answers: No such file or directory

現在の状態を確認するには tc qdisc show を使います。

$ tc qdisc show dev ens3 qdisc fq_codel 0: root refcnt 2 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64

fq_codel(または pfifo_fast)だけが表示されていれば、tbfやnetemは設定されていないデフォルト状態です。tbfが設定済みの場合は qdisc tbf 8001: root rate 50Mbit burst 1600b lat 50ms のように表示されます。

また、tc qdisc add を2回実行してしまった場合は次のエラーが出ます。

$ sudo tc qdisc add dev ens3 root tbf rate 50mbit burst 1600 latency 50ms RTNETLINK answers: File exists

この場合はいったん del してから add し直すか、tc qdisc change でパラメータを上書きしてください。

「Operation not supported」が出た時(netem)

netem用のカーネルモジュール(sch_netem)がロードされていない場合に発生します。

$ sudo tc qdisc add dev lo root netem delay 100ms Error: Specified qdisc not found. RTNETLINK answers: Operation not supported # モジュールをロード $ sudo modprobe sch_netem # 再試行 $ sudo tc qdisc add dev lo root netem delay 100ms # (エラーなし)

起動時に自動ロードするには、モジュール名を設定ファイルに書いておきます。

$ echo sch_netem | sudo tee /etc/modules-load.d/netem.conf sch_netem # 次回起動後の確認 $ lsmod | grep sch_netem sch_netem 36864 0

本記事のまとめ

やりたいこと コマンド
帯域を50Mbpsに制限する tc qdisc add dev ens3 root tbf rate 50mbit burst 1600 latency 50ms
100msの遅延を付加する tc qdisc add dev lo root netem delay 100ms
5%のパケットロスを付加する tc qdisc add dev ens3 root netem loss 5%
遅延とパケットロスを同時に設定する tc qdisc add dev ens3 root netem delay 80ms loss 3%
既存のqdisc設定を変更する tc qdisc change dev ens3 root netem delay 100ms 20ms
tc設定を削除して元に戻す tc qdisc del dev ens3 root
現在の設定を確認する tc qdisc show dev ens3
tcコマンドは「帯域制限(tbf)」と「ネットワーク模擬(netem)」の2つに絞って覚えるだけで、現場の実務に十分対応できます。特にnetemは、劣悪なネットワーク環境での動作検証をローカルで完結させられる非常に便利なツールです。設定は再起動で消えるため、運用環境ではsystemdサービスとして永続化してください。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、>>Linux Master Pro Seminarの詳細はこちら

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。