Proxmox 2ノード構成でHAクラスタを組めない
「なんだよ!Proxmox HAは2ノードじゃ組めないんじゃないかよ。
こっちはポン酢が蒸発して忙しいんだ!」
と気付いてしまったそこの奥さあん。ちょっと待ってくださいよぉ~。お~!
(富士地震火山研究所byえいしゅう博士)
という事で、
Proxmoxは2物理ノードだけではHAを組めない事になっています。
誤解しないでくださいね。2物理ノードでクラスタは組むことはできてもHA(High-Availability)、つまりVMの自動フェイルオーバーが働かない状態となります。なので"HA"クラスタは組めません。という事です。
2ノードでHAクラスタを組めない理由
理由を簡単に説明すると、「PVEはクラスタ制御部分にcorosyncを使用しており、このcorosyncによる投票(Vote)でMaster(主ノード)を決定しているから。」です。
LLMによると
理由を簡単に説明すると、Proxmoxはクラスタ通信にCorosyncを利用しており、Votequorumの投票によって「現在のノード集合がクラスタの過半数を持つ正統な側か」を判断しているためです。
過半数を持つ側だけが、クラスタ設定の変更やHAリソースの復旧を安全に進められます。
が正しい言い方だそうです。
Proxmoxクラスタ制御の雑な説明
もう少しクラスタ制御について優しく解説すると、HAクラスタのノードA,Bがあったとします。
AとBはお互いに数秒~数十秒おきに通信をしながら、お互いを死活監視しあってます。
「生きてるか~!」「生きてるよ~」という感じですね。
ハートビートチェックとも言います。つまり、お互いの心音を聞いてるわけです。
1. A --生きてる?--> B
2. A <---生きてる--- B
BからAにも同様のことをやっていると考えてください
LLMチェック!:技術的に正確な説明
「数秒~数十秒おき」がお嫌いなようですw
AとBはクラスタネットワークを通じて継続的に通信し、お互いの状態を確認しています。
が、より正しいとのこと。
スプリットブレインと第三票の必要性
語弊がある説明かもしれませんが、判りやすいと思います。
ここでノードAとノードBの間のLANケーブルが切れたとしましょう。ノードA,Bは生きているのにお互い通信出来ず、お互いに相手ノードが死んだ?と勘違いするような事が起きるわけです。
1. A --生きてる?--❌ B
2. A -------❌------ B(沈黙)
みたいな。逆もしかりです。
そして、勘違いして、「死んだノード上のVMを起動しなきゃ!Masterになるぞ!」 というのが両A,Bノードで誤って発生することをスプリットブレインと言います。
クラスタ制御ではスプリットブレインを起こさないための仕組みが組み込まれています。
それが第三者QDeviceによる投票なのです。
「今回はマジでBが死んだ(ように見える)からAに投票しよう」とか
「いや、両方生きてるから投票棄権しよう」
などの動きにより、A,Bノードがそれぞれ安心してMasterノードに昇格するかなどを見極めているという事です。
はい。ここもLLMチェック入りました。正しくは
QDeviceは、AとBのどちらのクラスタ区画が正統な側かを外部から判断し、その側へ第三票を与えます。
これにより、片方のノードだけが残った場合でも、
- 生存ノードの1票
- QDeviceの1票
で過半数を確保でき、HA処理を継続できます。
だそうです。
解決案
では、どのようにすればProxmox HAを2ノードで作るかについて説明していきたいと思います。
大きく、以下のパターンに分けて解決していく事になると思います。
1. Proxmoxノードをもう1台追加する
一番正攻法です。つまり3ノードHAにしなさいという話。
でも、もはやタイトルと矛盾を起こしてますね。なので、ここでは解決策とはしません。
2. 外部QDeviceを設ける
既存の2ノードを維持しつつ、第三票だけ外部へ置く方法です。
Corosyncの投票だけを行う機能を別物理マシンで用意する方法です。既設2ノード上のVMではダメです。
2.1 常設できるPCがある場合
- 常時稼働している
- そのPCにDebianやUbuntuを入れてcorosync-qnetdを入れれば良いです
- 既存サーバーやNASへ相乗りできる可能性がある
これは例えるなら、TrueNASが別物理筐体で存在するような場合です。そこにQDevice(corosync-qnetd)を起動すれば良いことになります。
2.2 OpenWrtルーターを持っている
- 常時稼働している
- PCよりは消費電力が小さい
- PVEとは別用途・別筐体
- 別電源系統に置きやすい
- OpenWrt向けパッケージ準備(つまりOpenWrtで動作しているルーター)が必要
やり方の記事はこちら
2.3 Raspberry Piを持っている
- Debian系OSを使える
- 情報が多い
- QDevice用途として十分
ただし、今から買うと意外に高いので、他の用途でも使ってみたい人向け
2.4 Lichee Piを買う
Lichee Piはこんなのです!
殆ど電源用のUSB-C端子と、RJ-45のポート、micro-sd差込口しかないやつ。
- 執筆時点で3千円位(Amazon)。アリエクだともっと安いのあるかも。
- 小型、省電力
- Debian系が動けばQNetd候補
- 少し検証色が強い
これもDebian系が載るらしい。しかもこれをQDeviceにしているという強者記事が無いので、人柱よろしく。
youtubeで(QDeviceとしてではなく)取り上げている人が居るのでみてみて
3. 人間QDevice、または条件付きAuto Quorum
常設QDeviceを置けない場合の代替策です。
3.1 人間QDevice
障害時に人間が状況を確認し、Masterになるべきノードに対して以下のコマンドを手動投入します。
pvecm expected 1
- 投入するかの判定は、人間。つまりノードA,Bのうち片方が完全に停止していることを確認して投入するのがベストです。
- ただし人間が不在だと何も起きない
- 夜中や外出中に弱い
- もはやHAというより「復旧操作」
3.2 条件付きAuto Quorum
スクリプト方式で、上記pvecm expected 1を自動で投入します。
- 既にQuorateなら何もしない
- ゲートウェイ不通なら何もしない
- 相手ノードへpingが通るなら何もしない
- ゲートウェイ生存、相手ノード不通の場合だけexpected 1を投入してくれる。
これは、以下のようなちょっと特殊な環境で利用するのに向いています。
- 2ノードHAを組んでいる(ほぼライブマイグレーション目的でのHA構成など)
- でも電気代勿体ないので必要な時のみノードBを起動
- 普段はノードAだけ常時起動
- ノードB使用後、停止したときに、ノードAでVMが起動できなくなるので、自動的にBが死んだらAにexpected 1を投入するスクリプト
いつか記事にしようかと思うが、必要だったらコメントでもください。
意外と簡単にできちゃうし便利です。
4. 比較表
| 方法 | 費用 | 安全性 | 常時稼働機器 | 難易度 | 向いている人 |
|---|---|---|---|---|---|
| 3台目のPVEノード | 高 | 高 | 必要 | 低〜中 | 正攻法で組みたい |
| PCへQDevice | 低〜中 | 高 | 必要 | 低 | 常設PCが余っている |
| OpenWrtルーター | 低 | 高 | 既存流用 | 中〜高 | 対応ルーターを持っている |
| Raspberry Pi | 中 | 高 | 必要 | 中 | Piを持っている |
| Lichee Pi | 低 | 高 | 必要 | 高 | 小型・低価格で遊びたい |
| 人間QDevice | 0 | 中 | 不要 | 低 | 手動復旧でよい |
| Auto Quorum | 0 | 条件付き | 不要 | 中 | 制約を理解して運用できる |
5.結局どれを選ぶか
常時稼働できる3台目のProxmoxノードがあるなら、3ノード構成が最も分かりやすい選択です。cephクラスタも組めるし良いですよね。でも今回は「Proxmox HAを2ノードで」が目的なので違います。
3台目のProxmoxノードは用意できないものの、常時稼働する別機器がある場合は、QDeviceを置く方法が候補になります。PC、Raspberry Pi、OpenWrtルーターなど、corosync-qnetdを動かせる機器であれば第三票として利用できます。
常時稼働機器を用意できない場合は、人間が状況を確認してpvecm expected 1を実行する方法や、限定条件付きで自動実行する方法もあります。ただし、これらはQDeviceと同じ安全性を提供するものではありません。
我が家では、
- 最初は人間QDevice
- 次はスクリプトで回避でした
- 現状は、Wi-Fiが届きにくい場所を補うため常時稼働していたGL.iNet AXT1800をQDevice化しました。普段のWi-Fiアクセスポイント用途を維持したまま、Proxmoxクラスタの第三票も担当しています。
おまけ:Proxmoxで開発環境をまとめて構築したい場合
この記事では既存のProxmox 2ノードクラスタをHAにする方法をまとめてみました。
Proxmoxクラスタでの開発環境構築については、以下の記事にまとめています。
