2016年12月20日火曜日

LIO Cluster [LIO, DRBD, Pacemaker による冗長化 iSCSI Target] (その16)障害テスト計画


障害テストを実施するにあたり、その計画を立てようという話です。関連する運用設計についても触れてみたいと思います。

今回のような HA クラスタの場合、フェイルオーバが発生し、障害原因が取り除かれた後、スイッチバックさせるべきかどうか、という問題があります。
できるだけサービスを停止させたくない、ということであればスイッチバックさせたくない、という方向に話が進みます。
運用が楽な方がいいということであれば、1号機が常に Active 機であるという運用設計を採用し、スイッチバックさせておくべきであるということに落ち着きやすいです。分かりやすい(常に1号機でサービスが稼働している)ことが大切で、未然に事故を防ぐことにつながります。テスト工数も単純に半分で済みます。
どちらがいい、悪いではなく、どちらに決めるか、という問題です。
スイッチバックさせるためには、スイッチバック中のサービス停止が問題となります。
今回の構成では、2秒ほどでスイッチバックできるので、サービス利用が一番少ない時間帯にスイッチバックさせれば影響はほとんどない、ということでいいと思います。
2秒ほどのサービス停止に関する調整が簡単に許されないのであれば、もっともっと、ずーと高価なストレージを採用すべきです。コントローラのスイッチオーバが2秒で完了するストレージがあればいいですが、よく知りません。

今回は、1号機が常に Active 機である、という運用設計を採用したとして話を進めます。
2号機でサービスが提供されている状態は、仮復旧しているだけで障害が継続している状態ということになります。
構築編では特に話を出しませんでしたが、1号機(iscsitgt01a)で優先的にリソースが起動される設定を入れてあります。

1号機(iscsitgt01a)の障害が回復した場合に自動フェイルバックする設定を入れるべきかどうかについては、入れないこととします。
障害の原因が分からないままに、正しい対応ができている確信がないままに自動復旧させるのは危険だからです。状態によってはデータを失ってしまいます。
ボンディングの設定については、プライマリスレーブが有効なときはいつでもアクティブなスレーブとなる設定となっています。Red Hat 社のマニュアルにあるとおりの設定です。何度もフェイルオーバが発生する状況(いわゆる往復ビンタ状態)に陥った場合、サービス遅延やサービス停止にはなってもデータロストにはならないという判断が働いているのだと思います。テストで問題が発生しない限りは、Red Hat 社の判断を尊重し、ボンディングについては自動フェイルバックする設定のままとします。
自動復旧は期待しない、という運用に決めたので、OS 起動時に pacemaker.service を自動起動させる設定も入れないこととします。
クラスタの起動は、オペレータが明示的にサービス起動させる運用とします。
自動復旧させないということは、障害が発生して以降は必ず冗長性が失われているということになりますので、障害発生時には直ちに駆けつけて復旧を急ぐ必要があります。
運用ポリシーとしては、4時間以内に駆けつけなのか、翌営業日対応なのか、というあたりが選択肢となるのだと思われます。

運用設計として、定期点検を実施するかどうか、という話があります。
スタンバイ機が故障していることに気づかないまま運用を続けていると危険です。
スタンバイ機が故障していないことをどのように確認するかですが、スイッチオーバさせてみるのが手っ取り早く、確実な方法です。
スイッチオーバ中のサービス停止が問題となるのは障害復旧時と同じです。
スイッチオーバさせてしまったがゆえに障害が発生してしまった、という事態も想定されます。
コントロールされている時間帯に発生させてしまった方がマシだと考えるべきか、寝ている子は起こすべきでないと考えるべきか、難しい問題です。
スイッチオーバさせないで点検する方法があるかどうかですが、どこまでやれて、どこまで妥協するのか、という話になるものと思います。
定期点検はしないケースの方が多いと思われるので、一旦この問題は保留します。

運用設計として、パッチ適用をどうするのか、という問題もあります。
こちらは、ストレージという点から考えると、閉じたネットワーク空間内に配置されるということもあり、問題が発生しない限り適用しない、ということになると思われます。

データのバックアップについては、今回は上位層で考えるということで割り切りたいと思います。もう1セット LIO Cluster を構築し、バックアップ領域とするなどの対応を考えていただければと思います。仮想環境であれば、Active 機の仮想マシンを丸ごとバックアップすればいいです。
LIO Cluster を3セット用意して Oracle RAC の ASM 用ストレージとするというのはよい考えだと思います。それを更に2セット用意して一方をデータベース用、もう一方をバックアップ用という構成も素敵です。本当に大切なデータについては十二重化くらいまでは考えておくべきです。今回構築した LIO Cluster は非常にシンプルな機能しか実装しておらず、スナップショット機能やバックアップ機能などはあえて実装していません。これらの実装を始めると、汎用性が無くなっていくこともありますが、フェイルオーバ時間が2秒に収まらなくなっていく方が問題と捉えています。高級ストレージは当然これらの機能を有していますが、それらに依存するとベンダーロックインな実装になってしまう点も考慮しておく必要があります。バックアップ対象がある程度の大きさを超えた場合、ストレージの機能を利用しないとバックアップが一定時間内に終了しない、といったことになりますが、そうでない限りは、できるだけストレージの機能に依存する実装は避けるべきだと考えております。
クラウド時代を見越した実装を考えると、ストレージについては、今までの常識にとらわれない考え方をしなければならないケースが増えると思います。スケールアップ型のストレージは高機能ですが、半端なく高価です。スケールアウト型は、安い機材を多数組み合わせることで信頼性と性能を向上させます。レイテンシの向上は最初から諦めたスループット重視のスケールアウト型 (AWS の S3 等) の方が普及していますが、これらは高価なストレージの代替にはなりえない点が残念です。今回紹介する構成が、レイテンシの向上も見越したスケールアウト型ストレージの土台となれば幸いです。iSCSI イニシエータ側で LVM を使って束ねて使う、というのがもう1つのおすすめ構成となります。

OS 部分のバックアップについては、取得しておくことにします。バックアップが使えることの確認、リストア・リカバリ手順を整えておく必要があります。バックアップの有効期限についても考慮する必要があり、バックアップ後の設定変更に対応できるのかどうかも問題となります。
お奨めはできませんが、今回の構成程度であれば再構築でも十分短時間でできる、という判断もありだと思います。初期構築とスタンバイ機のみの復旧構築では手順が異なる部分も存在するので、事前に確認しておく必要があります。


どのような障害試験を行うかですが、全ての障害ケースをテストするのは実質的に不可能です。そこで、ある程度の絞り込みを行う必要があります。

一つ目の原則として、二重障害は考慮しない、というものがあります。
二重障害、三重障害等を考え始めると、テストケースが爆発的に増えていきます。
今回は HA 構成ということで2ノードしか存在しておらず、2ノードとも障害が発生してしまえば無力ですので、この原則は比較的お客様の了解を得やすいものと思われます。

ハードウェアを破壊してしまう可能性のあるテストは実施しない、という原則もお客様の了解を得やすい部類だと思います。わざと壊したらサポートを受けられないのでコストに響きます。

ソフト的に破壊してしまう可能性のあるテストは実施しない、という原則はどうでしょうか。バックアップ、リカバリ試験を兼ねて、実施すべきと考える場合と、テスト工数削減のために実施しないケースがあると思います。
実施すべきだと思います。

全損からの復旧試験は必ず実施し、部分破損からの復旧試験はある程度妥協する、という考え方があります。
障害対応として一番困惑するのは、部分的に壊れているケースです。一部が壊れた場合であっても、全部が壊れたものとみなして対応する、というのは整理としては非常に分かりやすいです。Stonith などは、下手に壊れた状態で放置するよりも積極的に壊れた側を強制停止させてしまおうという発送の下で考えだされた技術です。
LIO のリソースエージェントを改修しました(2016/12/10) が、LIO はカーネルモジュールとして実装されている関係で LIO のサービスを kill するといった対応ができないため、制御不能に陥って kill したい場合には、カーネルを停止させる処理を追加しました。OS 丸ごと停止させるのは乱暴な処置ですので、/etc/ha.d/noreboot というファイルが存在している場合には、単にエラーとなるようにしています。今回の運用であれば、2号機側に /etc/ha.d/noreboot ファイルを作成しておきます。

障害の原因として考えられるのは、ハードウェア故障、操作ミス、ソフトウェア・バグ、誤作動などが挙げられます。
ソフトウェアのバグや誤作動をソフトウェアでカバーするのは非常に難しいですが、カーネルパニックが発生した場合や、ビジーループによりひどい処理遅延が発生した場合にフェイルオーバさせることで対処できる場合もあります。
今回の構成では、ソフトウェア watchdog を仕込んでいるので、運が良ければ自動的にフェイルオーバします。運悪くフェイルオーバしない場合でも、別途監視していて障害を検知できた場合は、手動でフェイルオーバさせることで仮復旧できることもあります。これらの事象をわざと発生させることや再現させることは非常に難しいのでテスト範囲から除外します。
ハードウェア故障については、ハードウェア固有の検知機構が必要です。ハードウェア故障により、後述する障害ケースが引き起こされる場合についてのみテストすることとします。
操作ミスについては、やりがちなミスはテストしておくべきだと思いますが、「rm /」等を実行してしまった、というケースまでやるのはやりすぎだと思います。全損からの復旧試験に含まれているという整理でいいと思います。
全損からの復旧が必要とならないケースについて、クラスタ操作時にやりがちなミスをテストしておけば十分と考えます。

※ うっかり「rm /」を実行してしまうことがあるのか、という問いに対し、「ある」と答えておきます。過去に実施した数千行の手順の中からできるだけ単純化して説明すると、VAR1VAR2 がうっかり未定義の状態で「rm $VAR1/$VAR2」を貼り付けて実行してしまうということをやったことがあります。手順書を作ってその確認をしているときでしたが、開発機で、かつ、バックアップが存在したので最悪の事態に発展するところまではいきませんでした。お客様からは「次からは気を付けてね」と言われるレベルで済みました。今考えても背筋が凍りつく思いがします。この日以来、「su」コマンドは使わずに、できるだけ「sudo」コマンドを使うようになりました。スクリプト内でrm $VAR1/$VAR2」という表現になりそうなときはrm $VAR1$VAR2」に変更し、VAR1 の定義で末尾に「/」を含ませるように心がけています。


具体的な障害ケースは以下の分類で考えることにします。Active 機側で発生する場合、Stand-by 機側で発生する場合、等の分類は省略しています。

◆ノード障害
・シャットダウン
・カーネルパニック
・電源断
・DRBD 特有のスプリットブレイン障害

◆プロセス障害
・Corosync プロセス障害
・Pacemaker プロセス障害
・DRBD プロセス障害 (カーネルモジュールなので難しい)
・LIO プロセス障害 (カーネルモジュールなので難しい)
・Corosync 誤操作
・Pacemaker 誤操作
・LVM 誤操作
・DRBD 誤操作
・LIO 誤操作
・Corosync ポート閉塞
・DRBD ポート閉塞
・LIO ポート閉塞

◆ネットワーク障害
・スイッチ障害
・ポート障害
・インターコネクト障害

◆ストレージ障害
・ローカルハードディスク障害

※ ローカルストレージの RAID 障害は試験範囲外とします。ハードウェアに適した方法で実行しておいた方が良いですが、サポートとの関係で難しい場合もあるかと思われます。

※ ストレージ障害については、共有ディスクに対するパス障害などもありますが、今回の構成では共有ストレージが存在しません。ローカルストレージを読み書きしている DRBD が疑似的な共有ストレージとなっています。

0 件のコメント:

コメントを投稿