CloudStack4.2環境の運用を開始し、徐々にインスタンスへのアクセスが増えてきたある日のこと。
 とあるWebアプリに「アクセスできない」というトラブルが発生。拡張ネットワーク構成の、仮想ルータでロードバランスも行なっている構成。ロードバランサ経由の他、各サーバ単体の静的IPでもアクセスできない。ついでに管理用のSSHもつながらないことからおそらくTCP周りは全滅している模様。
 ただCloudStackのコンソール経由で見てみるとサーバ自体は動作しておりアクセスも操作もできる。またロードバランサ環境=複数サーバ構成なわけだが、その複数のサーバ間の通信は行える。どうも仮想ルータと内部ネットワーク間のアクセスができなくなっている模様。
 ところで仮想ルータは、ネットワーク構成によってはかなりのアクセスが集中する構成にも関わらず、初期状態ではTCPのコネクション数やら何やらのチューニングが行われていない。いや/etc/sysctl.confには一部設定されてるっぽいのだがなぜだか起動直後は反映されていない。また、ソフトウェアロードバランサであるところのhaproxy。これの初期設定もワリと抑えめにされており拡張の余地が残されている。
 その辺のパラメータを超えちゃったのかなーとか思いつつ設定を調整し仮想ルータ再起動。通信復旧。やれやれこれで様子見。

 ………その約一週間後。ほぼ同様の通信障害が発生orz とりあえず仮想ルータ再起動で復旧するところまで同じ。
 しかしTCPパラメータ等の調整をした後の二度目となると別の原因の可能性が高くなる。というか最初の段階でTCPの限界系のログが一切出ておらず、というかその他の通信系の不具合もまったく予兆すらない。雰囲気wとしては「あるタイミングでふっとTCPパケットが消失しはじめる」かのような感じと言えばよいか。弾いたり拒否したりするのではなく、消失。あるいは行方不明。しかも仮想ルータ全体にではなくいずれかの仮想NICに依存する形で。

 それでもまあTCP周りの原因を推定して詰めていくしかなかったので、CloudStack以前にハイパーバイザ側で何か対応すべき点はないか、今回の場合「KVM」で何かしらTCPをチューニングする余地がないかとあれやこれや調べてたところ、某tHatの仮想化チューニング話・「ネットワーク調整のヒント」というページで

  arp_filter を使用して ARP 変動を防ぎます。 ARP 変動はホスト、 ゲストいずれでも発生する可能性のある望ましくない状況で、 マシンが ARP 要求に対して複数のネットワークインターフェースから応答してしまう原因となります。 この設定を永続的にするため、 echo 1 > /proc/sys/net/ipv4/conf/all/arp_filter を行なうか、 /etc/sysctl.conf の編集をしてください。

 なる記述を目にする。
 ARP変動?初めて聞く言葉。調べると世間的には「ARP Flux」と呼ばれる現象であるらしい。1台のマシンに同一セグメントのIPが振られている複数のNICがあると、ARP取得用のブロードキャストの応答が変になってARPテーブルのMACアドレスがおかしくなる現象、らしい。仮想マシンを構成する場合1物理サーバ内に同一セグメントの仮想NICが(仮想ブリッジ含めて)複数生成されることもあるため、表面化する可能性が高まるっぽい。

 …怪しい。
 ARPテーブルがおかしくなるとゆーことは、すなわち通信対象となるMACアドレスが変な方に向いているとゆーこと。仮に発生すればそりゃTCPパケットが行方不明ぽくなっても不思議ではない。ARPテーブルはNIC毎に保持されるので障害発生時に特定のNIC側に発生するのも説明できる。こんな現象であればより頻発してても不思議ではないが、ARPテーブルならば定期的にクリアされるだろうしおかしければ再要求もされるだろうから状況によっては自動復旧されてたのだろうと推察。

 対処としては「arp_filter」を有効にすること。ARP要求に対してより厳密に確認するためのパラメータぽい。一度検証機で試した後、仮想ルータ並びにその配下のインスタンス、更にCloudStack管理外の各物理サーバに設定(デフォルトに対して設定する「net.ipv4.conf.default.arp_filter =1」を/etc/sysctl.confに記述)。更に念の為にcronで1分毎にARPテーブルをログ保存するよう仕掛ける。

 …設定した約十分後、早速障害が発生orz
 しかしこれはむしろ「設定が生きたから」ではないかと推察。むしろこれまでが変な状態だったのだろうと。それがARPテーブルの更新のタイミングでより厳密に処理されるようになった結果、エラーとして顕在化したのではないかと。
 とりあえず三度仮想ルータを再起動→通信復旧した後、前述のARPログを見てみると、ちょうど障害が発生したタイミングでいくつかの通信対象が「Incomplete」となっており、復旧していない事を確認。「Incomplete」はarpコマンドで強制的にテーブルから削除した場合に瞬間的に発生しうる状態だが、普通はその後(接続時に)再要求が行われてすぐ復旧する。数分に渡ってIncompleteの状態になるのはさすがに異常。元々の障害時も似たような状態だったのだろうと推察。

 その後数十日間上記の状態で稼働を続けたが、通信周りの障害発生なし。念のためARPテーブルも確認し続けているがIncompleteは発生していない。
 これで多分収束したものと思われる。

 まー仮想ルータやら仮想ブリッジやら半自動でゴテゴテ作るCloudStackなので、いずれこーゆー「1物理サーバ(というか物理NIC)に割り当てられた複数の仮想NIC」的なところで問題が発生しても不思議じゃないかなぁとぼんやりと推察していたところもある。が、今回はまだしも「ARP Flux」という特定問題のヒントがあったのである程度絞れたが、ホントに1物理サーバ内で論理ネットワークを無視した変な通信し始められたら正直お手上げだよなぁ、とか漠然とオモタ。もちろんCloudStack、KVMに限らずあらゆる仮想基盤で言えることだと思うが。

追記:
 残念ながらその後もarp消失に伴う事例が発生中。ただし頻度は落ちてる。また上記arp_filterを設定しきれてない物理NICもあるので(※でも運用中なのでヘタに設定できない)とりあえずarp_filterの設定に一定の効果はあるものと思う。
 また最近CloudStackのシステムVMのバージョンが2014.06頃に上がった事を確認。取り急ぎ検証環境でシステムVMの入れ替え→仮想ルータの初期化を実行。数日経過したけどとりあえず目に見えた異常はなし。見たとこサービスのアップデートはそれほど顕著ではないが、ベースとなるOSが32bitの他64bitも選択できるようになった。前回までは32bit一択だった気がするので例えばメモリ的な処理限界に起因するものだとしたらこれでだいぶ改善される可能性もある。

関連タグ:CloudStackTCP/IP
2014-04-16 [技術]