CoDelを有効にする方法

RTTが安定しない相手に合わせてNICのキューをつかってタイミングを最適化するAQMなCoDelを有効にする方法。
公式のwikiがわかりにくかったのでメモ。

3.5系のカーネルに入れ替えたらコマンド一発で有効になります。

sudo tc qdisc add dev eth0 root fq_codel

以下のコマンドで確認できます。(Unknownとか言われてますが)

/sbin/tc -s qdisc show dev eth0
qdisc fq_codel 8003: root refcnt 2 [Unknown qdisc, optlen=48]
 Sent 32181 bytes 2193 pkt (dropped 0, overlimits 0 requeues 0)
 backlog 0b 0p requeues 0

自社のゲートウェイとして使っているvyattaで利用したいのですが、カーネルが古い。うーむ・・・。

Ubuntuでmacvlan

Ubuntuでmacvlanを使うのはとても簡単。

sudo aptitude install uml-utilities
sudo ip link add dev mvleth0 link eth0 type macvlan
sudo ip link set mveth0 up
sudo ifconfig mveth0 10.1.100.1 netmask 255.255.0.0

だけです。そうするとこのようにインターフェイスが生えます。

eth0 Link encap:Ethernet HWaddr 52:54:00:6d:b1:a5 
 inet addr:10.1.3.65 Bcast:10.1.255.255 Mask:255.255.0.0
 inet6 addr: fe80::5054:ff:fe6d:b1a5/64 Scope:Link
 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
 RX packets:11285 errors:0 dropped:187 overruns:0 frame:0
 TX packets:694 errors:0 dropped:0 overruns:0 carrier:0
 collisions:0 txqueuelen:1000 
 RX bytes:859612 (859.6 KB) TX bytes:118257 (118.2 KB)
 Interrupt:11 Base address:0x6000
mveth0 Link encap:Ethernet HWaddr 82:80:0b:36:24:c4 
 inet addr:10.1.100.10 Bcast:10.1.255.255 Mask:255.255.0.0
 inet6 addr: fe80::8080:bff:fe36:24c4/64 Scope:Link
 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
 RX packets:7659 errors:0 dropped:181 overruns:0 frame:0
 TX packets:9 errors:0 dropped:0 overruns:0 carrier:0
 collisions:0 txqueuelen:0 
 RX bytes:665866 (665.8 KB) TX bytes:726 (726.0 B)

ただしvyattaと違って他からみたMACアドレスは実デバイスになってしまいます。なにかカーネルパラメータが不足しているかもしれません。

? (10.1.100.10) at 52:54:00:6d:b1:a5 [ether] on br0

仮想MACのフェイルオーバーについて考えてみる

UC●M問題に端を発した仮想MACですが、あれこれ調べてるうちにひとつの疑問にいたりました。

仮想MACが移動したところで、ぶら下がってるL2スイッチのMACアドレステーブルが更新されないとだめじゃない?
うは、ベンダー様の専売特許とかですかwww
もしかしてリンクdown→upとかダサいことしちゃったりしてる?ぶぴぴwww

とか思いつつ調べてみたんですが、どうにもARPテーブルと情報がまざってしまい、ほしい資料がなかなか得られませんでしたが、やっと見つけました。

どうやら、GARPによってL2スイッチはMACアドレステーブルを更新する動きをするようですね。

ですが実際目で見るまで納得できないので、以下のような実験をしてみました。

  1. 同じMACアドレスとIPアドレスをもった物理ホストを2台用意する。
  2. IPアドレスに対してLAN内の別のホストからPINGを打ち続ける。
  3. PINGのリクエストが着てない側でGARP(arping -U [IPアドレス]を送信)
  4. スイッチングが切り替わるかtcpdumpとスイッチでshow macで確認

物理ホストはvyattaの仮想デバイスを使って用意しました。
LiveCDなvyattaはちょっとした検証のときに便利です。

set interfaces pseudo-ethernet peth0 link eth0
set interfaces pseudo-ethernet peth0 mac aa:aa:aa:aa:aa:aa
set interfaces pseudo-ethernet peth0 address 192.168.100.100/24

 

結果は想像通りで、GARPと同時に切り替わりました。
またL2スイッチは同じMACアドレスがあった場合、同時に二つMACアドレステーブルにのらない、でいいのかな。通信が複製されて大変なことになってしまいますね。

仮想MACのフェイルオーバーの流れはこんな感じでしょうか。

  1. フェイルオーバー発生
  2. 仮想MACとVIPを上げる
  3. L2スイッチのMACアドレステーブルを更新するためにGARP送信

NWがでかくなったり、UC●Mのように不届きな機器がいると、NWすべてのホストにブロードキャストして、ARPテーブルの更新を促すといった手法だと、確実に切り替わりが担保できないのも想像できます。

それに比べて仮想MACだと、直近のスイッチのMACアドレステーブルだけ切り替われば問題ないということですね。

なるほど、知れば納得です。

GARPを無視するスイッチ

去年の暮れの話ですが、メンテナンスの祭にkeepalivedでフェイルオーバーがうまく機能せずに一部の自社のサービスが死に掛けるという自体に陥りました。

いくつかあるVIPをひとつのインスタンスで管理していたんですが、
その中でも特定のIPだけフェイルオーバーに失敗して疎通しなくなるといった症状でした。
ip addr show の結果ではちゃんとVIPは渡されています。

すべてのVIPがだめというわけではなく、一部だけというのもくせものでした。

新拠点にサービスを部分的に投入していく段階であったり、ケチるために思いつきでアクティブ/アクティブ構成だったり、
新しく引いた回線、試験導入して日が浅いハードウェア、少し前にスイッチ故障があり、そのせいでインターナルのサーバのARPテーブルが混乱していたりと、かなり複雑な状況でした。

長ったらしい検証を語るのもめんどくさいので結論を言うと、上位UC●Mのスイッチがkeepalivedがフェイルオーバー時にARPテーブルを更新させるために送信しているGARPを無視して、フェイルオーバーする前のmacアドレスを保持したままという現象でした。

上位スイッチはARPテーブルが変わらないので、フェイルオーバー前のmacアドレス宛に通信を試みようとしますが、
実サーバは送られてきたmacアドレスはあっていても、もうすでにVIPを持っていないのでパケットを破棄してしまいます。

そして年越しもありましたが、一ヶ月ちかく放置されているので、Linuxで無理やり仮想macを実装する方向にむかいます。

pvcreateで “device-mapper: ioctl: error adding target to table

例によって中古ディスクの使いまわしで発生した問題です。
既存のパーティションを削除した後、新たにlvmパーティションを作成し、pvcreateでエラーがでました。

パーティション作り直しでもディスクのメタ情報は消えないようです。

# /sbin/dmsetup  status

pdc_bgbaijhjgc: 0 3906898080 linear ←これ
VolGroup00-LogVol00: 0 972357632 linear
# /sbin/dmsetup info pdc_bgbaijhjgc
Name:              pdc_bgbaijhjgc
State:             ACTIVE
Read Ahead:        256
Tables present:    LIVE
Open count:        0
Event number:      0
Major, minor:      253, 2
Number of targets: 1
UUID: DMRAID-pdc_bgbaijhjgc

Google先生仰せのままに解決しました。

# /sbin/dmsetup remove_all

# /sbin/dmsetup  status
VolGroup00-LogVol01: 0 4194304 linear 
VolGroup00-LogVol00: 0 972357632 linear 

# /usr/sbin/pvcreate /dev/sdc1 
Physical volume "/dev/sdc1" successfully created