HA機能
HA機能の利用方法
High Availability機能は、物理ホストに障害があった際、自動的に正常な他のホストで「仮想マシンを再起動」(これをフェイルオーバーと呼びます)する機能です。仮想マシンのゲストOS内で、再起動時に自動的にシステム復旧するように、事前に整えておく必要があります。
HAを利用するための条件とは?
HRPC KVM版でHAを利用するには、「共有ストレージ」に仮想マシンの仮想ディスクが設置されている必要があります。次の条件を満たしている必要があります。
- HCIでは3台以上、3Tierでは2台以上の完全な同一構成のノードで組まれた仮想データセンターであること。
- HCIタイプ(cephpool)か、3Tierタイプ(ESF)であること。仮想マシンイメージがこのストレージにデプロイされていること。
- ホスト機器(hrpc-node)に十分なリソース余剰(特にメモリ)があること。少なくても、ノード1台分のメモリは全体で空いていることが重要です。
※たとえば、3台のノードで組まれた仮想データセンターの場合、合計で2台分のメモリしか利用してはいけません。これをアドミッションコントロールと呼びます。 - 仮想マシンのバックアップが確実に取られていること
Backup Storageなどの契約をし、仮想マシンの定期バックアップを設定することを強く推奨します。
Proxmox VEのHAの概要
Proxmox VEのHAの概要は、下記の通りです。
- 物理ホストをHA Groupを作成する。HA時のふるまいはHA Groupで決める。
- 仮想マシンをそのHA Groupに参加させる。
クラスター(仮想データセンター)全体でHAが作られ、その中で作られた仮想マシンが、自動的にHA管理される設計思想ではありません。
また、HRPCは、標準でHAは設定されていません。
HA Groupを作成する(機能を有効化)
HA機能を有効にしたい場合、まず左側のペインでデータセンターを選択、中のペインでHAを開きグループをクリックします。右のペインで作成ボタンを押し、HAグループのIDを作成、HAに関係するホストをチェックします。
HA Groupは複数作る事ができますし、HA Groupに物理ホストをいれないこともできるので、4台のマシン契約時に3台でHA Groupをつくり、1台はHA範囲外にすることも可能です。HAグループのrestrictedがチェックされていると、そのHAグループに属している仮想マシンは、HA Groupから外されたホストで起動できません。
nofailbackをチェックしている場合、フェイル(故障)した物理ノードがリブートして戻ってきた際に、仮想マシンを元に戻さず、退避先で動作させ続けます。nofailbackをチェックしていない場合は、元のノードにライブマイグレーションで戻すため、ノードホストと仮想マシンの配置を厳密に管理する事ができます。
物理ノードが不安定になり再起動を繰り返すケースの場合は、またHAが稼働し仮想マシンが再起動を繰り返すことになります。そのため、nofailbackにはチェックを入れることを推奨しています。
また、仮想マシンのライブマイグレーションは実績のある熟れた技術ですが、Proxmox VEを含め、全てのライブマイグレーションは内部的には一瞬の停止があり、その停止中に載せ替えを行います。そこで、リアルタイム性が極めて重要なソフトウェアでは、問題がおきる可能性もあります。
仮想マシンをHAの対象にするには?
ProxmoxのHAは仮想マシンをHA管理下に置かない限りHAの対象にはなりません。
仮想マシンをHA管理下に置く場合は、当該の仮想マシンを選択し、右上の「More▼」プルダウンメニューから「HAの管理」を選びます。
上記で設定したHAグループのIDをグループから選択し、要求状態をstartedにした上で、追加ボタンを設定します。
これでこの仮想マシンはHAの管理下に入ります。
メンテナンス再起動と仮想マシンの関係
HAグループに入ったノードをメンテナンスなどで再起動させる時(不意の障害などではなく)、仮想マシンのふるまいは、HAの管理下にあるかどうかで異なります。
HA管理下の仮想マシン | 別のマシンへライブマイグレーションする |
---|---|
HA管理外の仮想マシン | 自動的にシャットダウンし、再起動後もシャットダウンしたまま |
HAのメカニズム
HAスタックは次のような仕組みで動いています。
レイヤ | コンポーネント | 役割 |
---|---|---|
クラスタ通信 | Corosync | ノード間のハートビート、設定の同期 |
HA マネージャ | pve-ha-crmd (CRM) | HA サービスのデプロイを実行 |
クラスタリソーススケジューラ | CRS – basic mode | 仮想マシン数を基準に、最少ノードを選択 |
リソースエージェント | pve-ha-lrm | 各ノード上で仮想マシンの起動・停止を実行 |
HA の基本動作
HRPCのHAモードは、デフォルトでBASICモードが使われています。
フェイルオーバー対象の仮想マシンを、障害時点で「稼働中HA サービス数が最も少ないノード」に起動します。CPU・メモリ量などの重み付けは行わず、シンプルかつ高速に分散を行います。
フェイルオーバーのアルゴリズム
- 候補ノード集合の決定
- 仮想マシンが属するHAグループ内ノードが選ばれ、無ければクラスタ内のonlineかつstandbyでない全ノードが次善として選択されます。
- プライオリティのクラス分け
- ノードごとに設定された優先度(1-100)。未設定の場合は全ノード同じクラス。
- 最少サービスノードの選定
- 候補ノードの「稼働中HAサービス数」を比較し、最少のノードを採用。
- 同点時の決定
- ノード名昇順で決定。実装上は安定ソートのため結果は予測可能。
障害発生時の処理フロー
フェーズ動作管理者が確認できる箇所
- 障害検知
- ダウンしたノードがCorosync投票から除外され、ha-managerがnot-reachable判定を行います。これはデフォルトで120秒で設定されています。
- サービスの回収
- CRMが該当ノード上の HAサービスをstopped 状態とし、その該当ノード上で動いていた仮想マシンの回収処理を開始します。
- ノード選定
- CRSが残存ノードの中で、最少動かしているVMが少ないノード(最小サービス決定)を決定します。
- (再)起動
- 選定ノードで仮想マシンを起動します。GUIでは「HA → Resources」にて started へ遷移していることからわかります。
- 注:この再起動とは結果としての再起動であり、オペレーションとしての再起動ではありません。落ちた仮想マシンを、再度起動することだと考えてください。
- 監視完了
- ゲスト OS 起動を確認し running へ。以降は通常稼働。
※nofailback がデフォルトの場合、停止していたノードが復帰しても、VM/CT は自動リターンしません。必要に応じて手動 Live Migration を実行してください。
メンテナンス時のワークフロー
HAを用いたメンテナンスは下記の様に行います。
- 対象ノードを空にする
- Web GUI→ Node (select) → More… → Maintenance をクリックすると、HA サービスが、仮想マシンを自動的に他ノードへ Live Migrationします。
- ステータス確認処理
- 該当ノードから仮想サーバが完全になくなるまで待ちます。
- 保守作業
- アップデートを実施します。
- クラスタ復帰
- ノード起動後に Leave Maintenance を実行。再度 Corosync 合流後、通常運用へ。
よくある質問 (FAQ)
元ノードが復帰したら仮想マシンも自動で戻りますか?
デフォルト (nofailback) では戻りません。負荷再分散が必要なら手動 Live Migration を行ってください。
Proxmox VEのCRSをstaticモードへの切り替えはできますか?
InfiniCloud サポート窓口までご依頼ください。ただし2025年1月時点では、この機能はTechnical Previewであり、設定変更後も、全HAノードでCRMの再起動が必要になります。
HA で保護していない仮想マシンはどうなりますか?
対象外の仮想マシンは障害ノード復帰まで停止したままです。自動復旧しないので、重要な仮想マシンは必ずHAを有効にしてください。
HA機能の限界
HA機能には限界があり、HAを利用することで発生する障害があります。
- 仮想マシンの不慮の再起動
- 仮想マシンのデータの破壊
HAは、ノードに障害が起きた時に、別のノードから仮想マシンを起動する機能です。しかしこれは、人の眼で見た視点での動作であって、実際のソフトウェアロジックは全く異なる実装となります。
まず、3つのノード全体(ノードA、ノードB、ノードCがあるとき)の中で、固有のノードに「障害が起きた」ということを定義することは厳密にはできません。
HAはそれぞれのノードが互いに協調しあって動作しています。
ノードA視点でノードBに対する疎通が取れなくなったとき、ノードBに障害が起きたのか、ノードAとノードBの疎通が取れなくなっただけなのかがわかりません。仮にノードA視点でノードCと疎通があれば、ノードBに障害が起きたであろう可能性が「想像」できます。
そこで、この想像にしたがって、ノードAとCはノードBが収容している仮想マシンを、自分達(AとCのどちらか)が再起動しようとします。
問題は、これが「想像」であり、ノードBは障害なのか孤立なのかが、この段階では判断できないことです。
ノードBの仮想マシンのデータは、共有ストレージ上で更新され続けているはずです。そこでノードAとCはノードBの動きを観測できるので、ノードBが最後にストレージを更新したのが何秒前かをみて判断します。
逆に言えば、ノードB自身が孤立したと判断した場合、ノードAとCが仮想マシンを再起動する可能性に備え、直ちに収容している仮想マシンをシャットダウンさせます。これが上記の「不慮の再起動」です。
一方、ノードBのシャットダウンが間に合ってない場合は、どうなるのでしょうか?
同じ仮想マシンがノードBと他のノードの2箇所で動くことになり、仮想マシンの仮想ディスクはたちまち破損してしまいます。これが上記の仮想マシンのデータの破壊に繋がります。
つまり再起動か、データの破壊かの二者択一となってしまいます。
≫ 参考 テクニカルノート/CAP定理を時間と空間に拡張する「落ちず、速く、信頼できるサービスをどう作るのか?」
実際にはデータ破壊だけは起きてはいけないため、ノードBはただちに孤立と同時に自分のマシンをシャットダウンさせます。このシャットダウンは正常終了ではシャットダウンが間に合わない可能性があるので、一般に強制電源OFFです。
ノードAやCからの判断はインターバルを持って行い、Proxmoxでは2分単位に行っています。2分応答しなければ「ホストに障害が起きた」と判断し、直ちに再起動処理がます。そのため最短でも2分間+仮想マシンがブートする時間は、ダウンタイムに繋がります(実際はもっとかかります)。
しかし、ノードBの速度が遅くなっていたり、メモリがスワップアウトしたり、Ballooningドライバによるメモリ回収で一時的に重くなったり、また、ストレージの書き込みが遅くなったりすることが発生すると、2分という時間はすぐに過ぎてしまい、シャットダウンが間に合わない可能性もあります。
守らなくてはならないのはデータであるため、システムは自動的にWatchDog Timer等を利用し、ホストのカーネル応答がなくなっても、カーネルを自動的に再起動できるようにしています。
またHRPCでは、このようなカーネル処理により大幅な遅延が起きないように、なるべく、無駄に処理時間の長いアルゴリズムは採用していないようにしています。