CentOSとiptablesでper-packet loadbalance with coreemu
Posted on 2013/01/26(Sat) 02:20 in technical
Linuxでパケット単位のロードバランスをしながら、coreemuの宣伝をします。
今回のキーワードは、 CentOS, coreemu, iptables, fwmark, loadbalance, per-packet loadbalance 辺りでしょうか。
Install coreemu for CentOS 6.3
さっくりインストールするので、いくつか現時点のハマりどころを書いておく。
基本的には、2.2.2. Installing from Packages on Fedora/CentOSを読みながら進みましょう。
- tkimgとlibevを先にインストールしておく必要があります。(EPEL使う場合は勝手に入るのでOK)
- SELINUXを無効にするか適切に設定しないとzebra(およびルーティングデーモン)が動きません
- ホスト側でiptablesを無効にするか空っぽにしておかないと、仮想リンク間のパケットが全部叩き落とされます。 iptables -F; /etc/init.d/iptables save とかで良いですかね。
- yumで入るtkのバージョンが古いので、仮想リンクの遅延等を設定しようとすると Error: Invalid command name "ttk::spinbox" が出るので、tcl/tk8.5をソースからコンパイルして上書きしましょう。また、この時 tk のconfigure中に X11 のライブラリリンクを要求されるので、 libX11-devel をインストールしておきましょう。(以下参考画像)
Let's topology making
さて、トポロジを作りましょう。とりあえずこんな感じですかね。(各ノードはデフォルト設定のまま放り込んでいます)
そして、OSPFのコンバージェンス後、n1のルーティングテーブルは以下のようになります。
[root@n1 n1.conf]# ip route 10.0.4.0/24 dev eth2 proto kernel scope link src 10.0.4.1 10.0.5.0/24 proto zebra metric 30 nexthop via 10.0.0.2 dev eth0 weight 1 nexthop via 10.0.1.2 dev eth1 weight 1 10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.1 10.0.1.0/24 dev eth1 proto kernel scope link src 10.0.1.1 10.0.2.0/24 via 10.0.0.2 dev eth0 proto zebra metric 20 10.0.3.0/24 via 10.0.1.2 dev eth1 proto zebra metric 20
通常時のロードバランス(ECMP)
n1~n4のルータではOSPFが動作しており、特に設定をしていないので、必然的にECMP(Equal-cost multi-path)になります。
LinuxにおけるECMPの動作は、通常宛先IPベースで別々の次ホップに割り当てていくので、トラフィックが流れっぱなしになっていると、キャッシュが消えるまで常に同じ経路を通ることになります。
その動きをしているのが下の図。
左側のノードから右側のノードに向けて、 ping 10.0.5.20 -i 0.1 -l 1400 のようにしてpingを投げています。
n1とn2の間は遅延5[ms]、n1とn3の間は遅延10[ms]に設定しているので、行きも帰りもn2を経由していることになります。
ここで、n1でキャッシュを確認後、消してみると、RTTが15[ms]となり、行きの経路が下を通るようになります。
OSPF等で宛先が複数あっても、パケット毎にロードバランスが行われないことは、まぁ、普通ですよね。
iptablesを用いたper-packet loadbalance
そこでiptablesを用いて、パケット毎に別々の経路を通るように設定してみます。
コンフィグはこんな感じ。
ip route add 10.0.5.0/24 via 10.0.0.2 table 101 ip route add 10.0.5.0/24 via 10.0.1.2 table 102 ip rule add fwmark 1 table 101 ip rule add fwmark 2 table 102 iptables -t mangle -A PREROUTING -j MARK --set-mark 1 iptables -t mangle -A PREROUTING -m statistic --mode nth --every 4 --packet 0 -j MARK --set-mark 2
遅延が15[ms]と20[ms]で切り替わっているので、n5→n6のパケットがn1でパケット毎のロードバランスが行われていることになります。応答パケットとなるn6→n5については、常にn3を通る経路を(n4が)選択しています。
直感からすると、 --every 4 は2じゃないのか、って思うんですけど、これ僕がmanを読み違えてるのか、バグなのか分かんないんですよねぇ。
ちなみに、これは確率を使うこともできるので、その場合はこうなります。
ip route add 10.0.5.0/24 via 10.0.0.2 table 101 ip route add 10.0.5.0/24 via 10.0.1.2 table 102 ip rule add fwmark 1 table 101 ip rule add fwmark 2 table 102 iptables -t mangle -A PREROUTING -j MARK --set-mark 1 iptables -t mangle -A PREROUTING -m statistic --mode random --probability 0.5 -j MARK --set-mark 2
iptables -t mangle -F で一旦消して、再投入します。
ま、大体50%、ということで。
終わる
というわけで、Linuxのロードバランス動作とかiptablesの設定を確認するのに、coreemuは中々使える子だよ、ってのをまた宣伝するための記事でした。