ネットワーク帯域上で必要な帯域をあらかじめ確保したり、必要以上のトラフィックを制限することを引っくるめて一般にQoS(Quality of Service)などと言うが、LinuxでIPのトラフィックコントロール(帯域制御)をするには、iprouteとtcを使う。
しかしこの設定は柔軟ではあるものの、直感的ではなく分かりづらい。こういうモノが必要な場合の大半は、アドレス帯毎に制限したいとかポート毎に制限したいとか、比較的目的がはっきりしているため、出来ればザックリと簡単に設定したいものだ。
そこで、CBQ.initというtcのwrapperとして使いやすいscriptがある。CBQというのはClass-Based Queuingと言って、トラフィック(パケット)をクラスとして定義し、それぞれに帯域上限値を設定しておく事で、上限値を超えたパケットを破棄するという方式だ。単純なqueueの優先順位付けの帯域制限方式と異なり、いつまで経ってもパケットがスケジューリングされず、事実上の通信断になってしまう事態を防ぐ事が出来る。
このCBQ.initをCentOS4で試してみた(たぶんCentOS5でもredhatでも同じでしょう)。必要なモジュールは最小構成でも用意されていたので、単純にscriptを設置するだけで良い。
まずはscriptをダウンロードし、適当はdirectoryに置いておく。redhat系のchkconfig形式のscriptのため、/etc/init.d/に置くなりlinkするなりしておくと、サービスとして管理することができる。分かりやすくするため、/etc/init.d/cbqというファイル名で設置してみた。
# chkconfig --add cbq # chkconfig --list | grep cbq cbq 0:off 1:off 2:off 3:off 4:off 5:off 6:off
こんな感じで見えれば正常。
あとは、script中のコメントに従って設定ファイルを用意する。設定ファイルもredhat系のdistributionならばおなじみの形式だ。設定ファイルの置き場はデフォルトでは/etc/sysconfig/cbq/なので、特に問題無ければここにすると良い。当然CentOSの標準構成には無いので作っておく。
# mkdir /etc/sysconfig/cbq/
設定ファイルは帯域制御したいクラス毎に、このdirectoryにファイルを置く。ファイル名の命名規則は以下のとおり。
cbq-lt;clsidgt;.lt;namegt;
- clsidは帯域制御のクラスIDで、他のクラス(要は他の設定ファイル名)と重複してはいけない。0002からFFFFまでの値を指定する。
- nameは任意の文字列。分かりやすい名前にでもしておく。
たとえば/etc/sysconfig/cbq/cbq-5963.for_httpsなどというファイルを作る。内容の例はこんな感じ。
DEVICE=eth0,1000Mbit,100Mbit RATE=5Mbit WEIGHT=500kbit RULE=:443,
- DEVICEには対象とするinterface名と、対応する物理NICのリンク速度、ウェイト(通常はリンク速度の1/10)を指定する。
- RATEにはこのクラスへの割り当て帯域を指定する。
- WEIGHTはウェイトを指定する。通常はRATEの1/10。
- RULEは、[[saddr[/prefix]][:port[/mask]],][daddr[/prefix]][:port[/mask]]この形式で指定する。カンマ区切りで前半がソースアドレスとポート、後半がディスティネーションだ。特に指定しない(anyを指定する)場合は省略可能。
これがもっとも基本的で単純な使い方だ。上記の例だと、1Gbpsのインターフェイスeth0を通るパケットに対し、ソースポートが443であれば何れのソースアドレスでも、何れのディスティネーションでも5Mbpsの帯域とする、と言う意味。Webサーバなどに設定して、httpsの下り帯域を制限しているわけだ。
単なるwrapperとはいえ、設定出来る内容は多岐にわたり、かなりきめ細かい設定も出来る。scriptのコメントがとてもよく纏まっているので、いろいろ試してみると良い(CBQ.initという名前だけど、CBQ以外の制御もできる)。
chkconfigでサービスに登録してあれば、動作させるには
# service cbq start
だけで良い。動作状況の確認は以下のコマンドでできる。
# service cbq stats(帯域制御の状況を表示する) # service cbq list(制御対象のリストを表示する) # tc -s class ls dev eth0(tcで見る場合にはこんな感じ watchコマンドの引数にすると便利)
動作に問題が無ければ、chkconfigコマンドでonにしておけば、毎回OSのboot時に設定される。chkconfigを使わない場合は、そのままscriptの実行し、引数にstart,stop,stats,list等を指定すれば同じ結果になる。