MENU

tc qdisc HTB で本番帯域制御を実装する|設定・計測・輻輳時の切り戻しフロー

目次

帯域制御が求められる運用背景

物理回線を複数のサービス・テナント・バッチ処理が共有する環境では、特定トラフィックが帯域を占有し、低レイテンシが求められる業務通信を圧迫するケースが起きます。夜間バックアップや CI/CD の大規模ビルドが日中の API レスポンスを悪化させた、という障害報告は現場で珍しくありません。

Linux カーネルのトラフィック制御機能(tc)に含まれる HTB(Hierarchical Token Bucket) は、クラス階層で帯域を割り当て・貸し借りできる qdisc です。古くから使われてきた CBQ は実装が複雑で Linux 5.x 以降は非推奨扱いが続いており、2026年時点の現場標準は HTB か HFSC(高精度が必要な場合)の二択と見てよいでしょう。本記事では HTB を選択し、ゼロから本番適用するまでの一連のフローを解説します。

HTB の三層構造を整理する――qdisc・クラス・フィルタ

HTB の設定は三つの要素で構成されます。

  • qdisc(キューイング規則):インタフェースに紐付き、パケットの処理順序を決める最上位の仕組みです。HTB を使う場合、root qdisc として HTB を登録します。
  • クラス:帯域の「仕切り」です。親クラスは回線全体の上限を持ち、子クラスがその帯域を分割します。各クラスには rate(保証帯域)と ceil(最大帯域)を設定します。親クラスに余裕があれば子クラスは ceil まで借用でき、借用先がなければ rate に絞られます。
  • フィルタ:届いたパケットをどのクラスへ振り分けるかを判定します。宛先 IP・ポート・DSCP マーク・cgroup ID など多様な条件を記述できます。

クラス ID は メジャー番号:マイナー番号 で表し、root は 1:0、親クラスは慣習的に 1:1、子クラスは 1:10 や 1:20 と付けることが多いです。ID 体系はあらかじめ運用ルールとして決めておくと変更コストが下がります。

実装手順:ルートから子クラスまでを順に積み上げる

以下の例では、合計帯域 1 Gbps の環境において「通常トラフィック(700 Mbps 保証)」「バックアップ(200 Mbps 保証・余剰借用可)」「ベストエフォート(100 Mbps 保証)」の三クラス構成を作ります。インタフェース名は eth0 とします。

1. root qdisc を追加する

sudo tc qdisc add dev eth0 root handle 1: htb default 30

default 30 は、どのフィルタにもマッチしないパケットを自動的にクラス 1:30(後述のベストエフォートクラス)へ送ることを意味します。

2. 親クラスと子クラスを追加する

# 親クラス(回線全体の上限を定義)
sudo tc class add dev eth0 parent 1:0 classid 1:1 htb rate 1gbit ceil 1gbit burst 15k

# 通常トラフィック用(保証 700 Mbps、ceil 1 Gbps)
sudo tc class add dev eth0 parent 1:1 classid 1:10 htb rate 700mbit ceil 1gbit burst 15k prio 1

# バックアップ用(保証 200 Mbps、ceil 800 Mbps)
sudo tc class add dev eth0 parent 1:1 classid 1:20 htb rate 200mbit ceil 800mbit burst 15k prio 2

# ベストエフォート(保証 100 Mbps、ceil 500 Mbps)
sudo tc class add dev eth0 parent 1:1 classid 1:30 htb rate 100mbit ceil 500mbit burst 15k prio 3

prio の値が小さいクラスほど帯域借用の優先度が上がります。バックアップは保証帯域を確保しつつも通常トラフィックに遠慮させたい場合は prio を高く(数値を大きく)設定します。

3. フィルタを設定する

# バックアップ用 IP(例:192.168.100.0/24)を 1:20 へ振り分け
sudo tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
  match ip dst 192.168.100.0/24 flowid 1:20

# ベストエフォート用ポート(例:dst 8080)を 1:30 へ
sudo tc filter add dev eth0 protocol ip parent 1:0 prio 2 u32 \
  match ip dport 8080 0xffff flowid 1:30

マッチしない残りのパケットは default 30 の指定どおり 1:30 へ流れます。フィルタの評価は prio の昇順で行われるため、より狭いマッチ条件を先に置くと意図した分類が実現できます。

4. 再起動後も有効にする

上記コマンドは OS 再起動で消えます。systemd-networkd を使う環境では /etc/systemd/network/10-eth0.network に [TrafficControlQDisc] セクションを追加する方法が標準的です。ただし HTB の全オプションがネイティブに記述できるわけではないため、複雑な構成は ExecStartPost で tc コマンドを呼ぶスクリプトをサービスに組み込む運用が現場では多く採用されています。NetworkManager 環境では dispatcher スクリプト(/etc/NetworkManager/dispatcher.d/)が対応します。

帯域計測と動作検証のフロー

設定後は必ず計測で意図どおりの動作を確認します。

クラス統計を確認する

tc -s class show dev eth0

出力の Sent bytes・drops・overlimits を確認します。overlimits の増加はそのクラスが上限に達してパケットを遅延させていることを示しており、設定値の見直し指標になります。

iperf3 でスループットを測定する

# サーバ側
iperf3 -s

# クライアント側(バックアップ帯域を想定した宛先 IP を指定)
iperf3 -c 192.168.100.10 -t 30 -P 4

30 秒・4 並列ストリームで計測し、平均スループットが設定した ceil を大きく超えていないかを確認します。通常トラフィックが並走していると保証帯域付近に落ち着くはずです。

ss -i でソケット情報を補完する

ss -tin dst 192.168.100.10

cwnd(輻輳ウィンドウ)や retrans(再送数)をあわせて見ることで、HTB が正しく絞っているのか TCP 輻輳制御が働いているのかを切り分けられます。HTB による意図的な帯域制限であれば cwnd は比較的安定しており、ネットワーク経路の問題であれば retrans が顕著に増加する傾向があります。

輻輳発生時の切り戻しフロー

本番環境で帯域制御が原因のパフォーマンス低下を疑った場合、まず設定の全削除で症状が改善するかを最優先で確認します。

最速の一時解除

sudo tc qdisc del dev eth0 root

root qdisc を削除すると紐付くクラスとフィルタもすべて消えます。インタフェースは pfifo_fast(カーネルデフォルト)に戻り、制限なく帯域を使える状態になります。症状が解消すれば HTB 設定が原因と判断できます。

段階的な切り戻し手順

原因クラスを特定できている場合は、そのクラスの rate・ceil を変更するだけで済みます。

# バックアップクラスの帯域を緊急縮小(200 Mbps → 50 Mbps)
sudo tc class change dev eth0 parent 1:1 classid 1:20 htb rate 50mbit ceil 200mbit burst 10k prio 2

tc class change はクラスをその場で書き換えるため、フィルタや他クラスへの影響なく即時反映されます。変更後すぐに tc -s class show で overlimits が減少しているかを確認します。切り戻し後は再発防止として、変更前後のクラス統計・iperf3 結果・アプリケーションのレイテンシをセットで記録し、変更管理ドキュメントに残すことが重要です。

2026年時点の現行環境差分と注意点

u32 フィルタから tc flower・eBPF への移行

従来の u32 フィルタはルール数が増えると線形スキャンとなり CPU 負荷が上がります。カーネル 4.13 以降で安定した tc flower フィルタはハッシュテーブルによる分類を行い、大規模ルールセットで有利です。さらに eBPF を用いた tc-bpf は分類ロジックをカーネル内で実行でき、VXLAN・トンネル環境や conntrack 状態との組み合わせが求められる 2026年の典型的なマルチテナント構成に適合します。新規設計であれば u32 より tc flower から始めることを検討する価値があります。

nftables との共存と ingress 制御

nftables の meta priority を使うと、nft ルール内から HTB クラス ID(1:10 形式)に直接マーキングを行えます。フィルタと nftables の二重管理を避けたい現場での採用が進んでいます。また、HTB 自体は egress 専用であるため、ingress 方向の帯域制限は IFB(Intermediate Functional Block)デバイスを経由するアーキテクチャが標準です。スマート NIC や SR-IOV を使う環境では tc qdisc add dev eth0 ingress と mirred アクションを組み合わせて IFB へリダイレクトし、IFB 側で HTB を適用します。

カーネル 6.x と iproute2 のバージョン一致

Linux 6.1 以降では HTB の内部ロック改善によりマルチコア環境での競合が軽減されています。Ubuntu 24.04 LTS(カーネル 6.8)・RHEL 9.x(カーネル 5.14)を使う環境ではこの恩恵を受けられます。一方、古い iproute2(2.6 系)では新しいカーネルの HTB オプションを認識しない場合があるため、tc -V でバージョンを確認し、ディストリのパッケージと一致させることが前提です。Ubuntu/Debian では iproute2 パッケージ、RHEL 系では iproute パッケージがそれぞれ管理しており、カーネル更新と同時にアップデートする運用フローを整備しておくと予期しない非互換を防げます。

HTB はシンプルな API と豊富な実績を持ちながら、フィルタ層を eBPF に置き換えることで最新の複雑な要件にも対応できる柔軟性があります。設定の永続化・計測・切り戻しまでをセットで運用設計に組み込むことで、帯域起因のインシデントを最小化できます。

「コマンドは打てる。次は”現場で通用する型”を最短で身につけたい」——そんなあなたへ。

ネットの断片的なTipsをコピペするだけでは、体系的な運用スキルはなかなか積み上がりません。リナックスマスター.JPの無料メルマガ「リナマガ」では、現場で実際に使うLinuxサーバー運用の考え方を、順を追って実務目線でお届けしています。いま登録された方には、安全なサーバー構築の「型」をまとめた『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼント中です。

>> 図解60P『Linux入門マニュアル』を無料で受け取る
(メルマガ登録は10秒・いつでも解除OK)

※ 「独学の時間がもったいない」「プロから現場の技術を最短で学びたい」という本気の方には、2日で実務レベルが身につく初心者向けハンズオンセミナーもご用意しています。

PR・広告

新しいLinuxの教科書 第2版(Amazon)

コマンド操作から基本運用までを手を動かして学べる定番書。記事で触れた技術の土台固めに。

Amazonで見る

※ Amazonのアソシエイトとして、当サイトは適格販売により収入を得ています。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

目次