Proxmox 2ノードクラスタにqdeviceを追加する
この記事で実現すること
前回の記事では、2台のProxmoxノード(V9.x)でクラスタを構成し、VMマイグレーションとZFSレプリケーションを使える状態にしました。
ただし、2ノードクラスタにはquorumの課題があります。片方のノードが停止した場合、残った1台だけではクラスタとしての判断が難しくなるためです。
そこで今回は、外部投票サーバーとしてqdeviceを追加し、2ノードクラスタのquorumを安定させます。さらに、HA構成を作成し、テストVMを使って障害時のフェイルオーバーを確認します。
今回の構成
| 名称 | pve1 | pve2 | quory |
|---|---|---|---|
| 役割 | メインノード | セカンダリノード | QDevice / automation |
| CPU | AMD Ryzen 9 7900 (12C/24T) | AMD Ryzen 5 5600G (6C/12T) | intel N100 |
| メモリ | 64GB DDR5-4800 | 48GB DDR4-3200 | 16GB DDR4-3200 |
| ストレージ | NVMe 2TB ×2(ZFS mirror) | NVMe 1TB(ZFS single) | NVMe 500MB(Ext4) |
| NIC | Intel X710 10GbE ×4 | Intel X710 10GbE ×4 | Realtek 1GbE |
| OS | Debian 13 + Proxmox VE 9.1.9 | Debian 13 + Proxmox VE 9.1.9 | Ubuntu Server 26.04 |
※名称は私が名付けたホスト名です。特に記載する必要もありませんが文中で引用する時にわかりやすくするためですのでご理解ください。
クラスタ構成では、できればCPUの種類は同じメーカーで揃えておいた方が安全です。完全に同じハードウェア構成にできれば理想ですが、家庭内のホームラボでは必ずしもそうはいきません。
今回の構成でも、pve1はRyzen 9 7900、pve2はRyzen 5 5600Gで、世代も性能も異なります。そのため、VMのCPU設定では互換性を意識する必要があります。
ネットワークについては、VMマイグレーションや将来的なフェイルオーバーを考えると、各ノードで同じ構成にしておくべきです。構成が揃っていれば、VMが別ノードへ移動した場合でも、どのネットワークを利用すべきかが明確になります。
第1部:quorumとqdevice
2ノードクラスタの問題
Proxmoxを2台でクラスタ化すると、VMのマイグレーションや管理の一元化ができるようになります。しかし、2ノードクラスタにはquorumの問題があります。クラスタでは、複数のノードが協調して動作します。そのため、障害やネットワーク分断が発生したときに、「どのノードが正しいクラスタとして動き続けてよいのか」を判断する必要があります。
3台以上のクラスタであれば、多数決によって判断しやすくなります。たとえば3台構成で1台が停止しても、残り2台で多数派を維持できます。一方、2台構成では片方のノードが停止した場合、残ったノードは1台だけになります。この状態では、多数決という意味では過半数を作りにくくなります。
また、単純なノード停止ではなく、ノード間の通信だけが切れた場合には、両方のノードが「相手が停止した」と判断してしまう可能性があります。このような状態で両方のノードが独立して動き続けると、両方のノードが稼働中になり、それぞれのノードはもう一方のノードが停止しているように見えてしまいます。
そのため、2ノードクラスタでは、単に2台をクラスタ化するだけでなく、quorumをどう扱うかを考える必要があります。
quorumとは何か
quorumは、クラスタが安全に動作を継続してよいかを判断するための多数決の考え方です。クラスタ内の各ノードにはvote(投票)があり、クラスタ全体として必要な票数を満たしている場合に、quorate(定足数を満たした)状態になります。
Proxmoxクラスタでは、pvecm statusでquorumの状態を確認できます。
1 | pvecm status |
正常な状態であれば、以下のように表示されます。
1 | Quorate: Yes |
Quorate: Yesの状態であれば、そのクラスタは必要な票数を満たしており、クラスタとして動作を継続できます。
qdeviceとは何か
qdeviceは、クラスタのquorum判定を補助するための外部投票デバイスです。2ノードクラスタの、pve1とpve2の2票にqdeviceを追加します。これによって2台のProxmoxノードに加えて、外部の投票役を持つ構成になります。
今回の構成では、以下のような考え方になります。
1 | pve1 : 1 vote |
qdeviceは、Proxmoxノードそのものではありません。VMやCTを動かす役割もありません。あくまで、クラスタの投票を補助するための外部サーバーです。
quoryの役割
今回の環境では、quoryと名付けたUbuntu Server26.04をqdeviceとして利用します。役割は、corosync-qnetdを動作させ、Proxmoxクラスタのqdeviceとしてquorum判定を補助することです。
qdevice用途であれば、高性能なCPUや大容量メモリは必要ありません。通信量も少なく、1GbEでも十分すぎるくらいです。重要なのは、性能よりも安定して常時稼働できることです。
第2部:qdeviceセットアップ
qdeviceに必要なハードウェア
実際のところ、ホームユーザーが導入するqdeviceとしては以下のようなものが選択されるようです。
- 極めて小型のPC(ラズベリーパイなど)にセットアップ
- NASにVMとしてセットアップ
- 小型PCにセットアップ
私は、3の小型PCを選びました。クラスタ運用やVMの管理のために定期的なジョブ実行(ヘルスチェック、セキュリティパッチ等)と、このQuorumとが兼ねられると考えました。但し過負荷になってはクラスタ通信に影響が出るのでそれは避けたいところです。省電力ならラズベリーパイが一番ですが、電源やパーツの安定稼働については今ひとつ心配なところがありました。Amazonを覗いてみればミニPCはたくさんあります。そのようなデバイスは今一つ欲しいと思いません。これはもう感覚という以外無いです。うまく説明できません。「なんとなく嫌」なのです。そして、自分で組むとなるとケースのサイズもそれなりに大きくなってしまいますし、省電力も中途半端になりそうです。その中でもMSIのミニPCはきちんとしたスペックが開示されており、自分としては珍しくAmazonでPCを購入しました。
今回使ったMSIサーバー
MSI Cubi N ADL S-055BUS
| 項目 | 内容 |
|---|---|
| 用途 | Proxmoxクラスタ用 qdevice / 管理用サーバー |
| CPU | Intel Celeron N100(TDP 6w) |
| メモリ | Crucial 16GB SODIMM PC4-25600(DDR4-3200)CT16G4SFS832A |
| ストレージ | KINGSTON OM8S 500GB NVMe SSD |
| NIC | 1GbE ×2(REALTEK RTL8111H) |
| OS | Ubuntu Server 26.04 |
MSI BUSINESS & PRODUCTIVITY PCS Cubi N ADL
https://storage-asset.msi.com/specSheet/uk/mini-pcs/Cubi%20N%20ADL%20S-055BUS.pdf
ベアボーンなのでSSDとメモリは別途手持ちのものを流用、購入しています。
このハードウェアは見た通り非常に小さいですが、電源としてACアダプタ(65W、PSEマーク付き)が付いてます。
ファンレスで2PortのNICがあるので、色々な目的に使えそうです。何の話でしたっけ?そうでしたProxmoxの話でしたね。
qdevice用途としては完全にオーバースペック
ひたすらPVE1、PVE2との通信が発生するのだろうということで機器選定したものの、完全にオーバースペックです。
ネットワーク
平均300B/s。最大が2KB/sですが、おそらくMaxの値は私がSSHをした時のものです。
CPU/メモリ
8日以上連続稼働した状態でも、load averageは0.00, 0.00, 0.00で、CPU idleは97.7% でした。
メモリについても、16GB搭載に対して実使用量は約790MiB程度でした。qdevice用途としては、今回のIntel Celeron N100 / 16GB RAM / NVMe SSD 500GBという構成は、かなり余裕のある構成です。
1 | yoshi@quory:~$ top -b -n 1 | head -20 |
実際にqdeviceとして動作しているcorosync-qnetdの使用量を確認すると、CPU使用率は0.0%、RSSは13,864 KiB、つまり約13.5MiBでした。
この結果からも、qdevice用途では高性能なCPUや大容量メモリはほとんど必要ないことが分かります。
今回のquoryはIntel Celeron N100、メモリ16GB、NVMe SSD 500GBという構成ですが、qdevice用途としては明らかに余裕がありすぎる構成です。今後は他の使い道を探すことにしましょう。
| 項目 | 値 |
|---|---|
| プロセス | corosync-qnetd |
| CPU使用率 | 0.0% |
| メモリ使用率 | 0.0% |
| RSS | 13,864 KiB(約13.5MiB) |
| VSZ | 16,228 KiB(約15.8MiB) |
ネットワーク構成
今回判明したように、qdevice用途であれば、ネットワークは1GbE 1ポートで十分です。10Mbps半二重だって大丈夫です笑。負荷分散を考え、2Portモデルを選定しましたが、全くの見込み違いでした。
今回の構成では、qdevice通信はProxmoxのマネジメントVLANと同一のネットワークのみを使用します。厳密に言えば、同じセグメントである必要はありませんが、できるだけ通信が妨げられることは防ぐために同一のネットワークに設定されることをお勧めします。
1 | pve1.internal : 192.168.x.11 |
前回の記事では、VMマイグレーションやZFSレプリケーション用の通信をServer VLAN側に分けました。
あとは私の環境の留意事項としては、VM担っているSophos FirewallがDNSとDHCPを提供するので、こういったレイヤではDNSやDHCPは依存しないようにします。昔ながらの固定IPアドレスと/etc/hostsで名前解決を管理します。
なお、corosync-qnetdはTCP 5403を使用します。
そのため、pve1 / pve2 から quoryのTCP 5403へ到達できることが必要です。
事前確認
ここからはUbuntu26.04 Serverを前提に、qdeviceの具体的なセットアップを行っていきます。
2ノードのProxmoxが既にクラスタ化されている事を前提とします。
qdeviceを追加する前に、名前解決、SSH疎通、時刻同期、クラスタ状態を確認します。
qdeviceのセットアップでは、Proxmoxノードからqdeviceへ接続して設定します。そのため、Proxmoxノードからqdeviceへ到達できることが前提になります。
名前解決確認
まず、qdevice上でproxmoxノード、qdevice自身の名前解決を確認します。以下は私の環境ですが、ご自身の環境で、事前に/etc/hostsでホスト名の登録をしてください。
1 | getent hosts pve1.internal |
期待する結果は以下の通りです。
1 | 192.168.x.11 pve1.internal |
次に、Proxmoxノード側からqdeviceの名前解決を確認します。
pve1で実行します。
1 | getent hosts quory.internal |
pve2でも同様に確認します。
1 | getent hosts quory.internal |
どちらも以下のように解決できれば問題ありません。
1 | 192.168.x.14 quory.internal |
qdeviceはクラスタの判断に関わるため、名前解決が不安定な状態で進めるのは避けるべきです。DNSを使う場合でも、/etc/hostsを使う場合でも、pve1 / pve2 / quoryの相互解決が安定していることを確認しておきます。
rootの有効化
pvecm qdevice setup は、Proxmox側からqdeviceへroot SSH接続して初期設定が行われます。そのため、qdevice登録直前のみquory側でroot SSHログインを一時的に許可します。
qdevice上で実行します。一時的なrootパスワードを設定してください。
1 | sudo passwd root |
通常運用ではroot SSHは無効にするのが一般的です。
root SSH 一時許可
qdevice上で実行します。一時的に00-qdevice-root-temp.confファイルを作成します。viまたはnanoで
1 | vi /etc/ssh/sshd_config.d/00-qdevice-root-temp.conf |
そして、以下の内容を登録します。
1 | PermitRootLogin yes |
SSH設定の構文確認です。保険をかけて複数のSSH接続を実施の上で、慎重に実施しましょう。
1 | sudo sshd -t |
SSHを再起動します。
1 | sudo systemctl restart ssh |
SSH疎通確認
proxmox1号機とproxmox2号機からqdeviceへSSH接続できることを確認します。
pve1で実行します。ホスト名はご自身の環境で読み替えてください。
1 | ssh root@quory.internal hostname |
期待する結果は以下です。
1 | quory |
pve2でも同様に確認します。
1 | ssh root@quory.internal hostname |
1 | quory |
qdeviceのセットアップ完了後に、あらためて公開鍵認証へ移行し、パスワード認証を無効化する流れがおすすめです。
時刻同期確認
クラスタ構成では、各ノードの時刻が大きくずれていないことも重要です。
quoryで時刻同期状態を確認します。
1 | timedatectl |
確認するポイントは以下です。
1 | System clock synchronized: yes |
pve1 / pve2についても、通常はNTPまたはchronyで時刻同期されていることを確認しておきます。
クラスタやqdeviceのトラブル調査ではログ時刻を突き合わせることが多いため、時刻同期は地味ですが重要です。
クラスタ状態確認
qdeviceを追加する前に、現在のProxmoxクラスタが正常であることを確認します。
pve1またはpve2で以下を実行します。
1 | pvecm status |
確認するポイントは以下です。
1 | Quorate: Yes |
この時点では、まだqdeviceを追加していないため、2ノードクラスタとして表示されます。
qdevice追加前の状態でクラスタが不安定な場合は、先にその原因を解消してから進めた方が安全です。
quoryにqnetdをインストールする
次に、quory側にcorosync-qnetdをインストールします。qnetdは、qdeviceの投票を受け持つ外部サーバー側のサービスです。
quoryで実行します。
1 | sudo apt update |
インストール後、サービスを有効化して起動します。
1 | sudo systemctl enable --now corosync-qnetd |
状態を確認します。
1 | systemctl status corosync-qnetd --no-pager |
active (running) になっていれば問題ありません。
1 | active (running) |
また、corosync-qnetdはTCP 5403で待ち受けます。quoryで以下を実行します。
1 | ss -lntp | grep 5403 |
以下のようにLISTENしていれば、qnetdが待ち受けています。
1 | LISTEN ... :5403 ... |
pve1 / pve2からquoryのTCP 5403へ到達できる必要があります。
Proxmoxノード側のqdeviceパッケージを確認する
次に、pve1 / pve2側でcorosync-qdeviceがインストールされているか確認します。pve1で実行します。
1 | dpkg -l | grep corosync-qdevice |
pve2でも確認します。
1 | dpkg -l | grep corosync-qdevice |
インストールされていない場合は、それぞれのProxmoxノードでインストールします。
1 | apt update |
インストール後、再度確認します。
1 | dpkg -l | grep corosync-qdevice |
qnetdはquory側、qdeviceはProxmoxノード側で動作する、という役割分担です。
corosync設定をバックアップする
pvecm qdevice setupは、Proxmoxクラスタのcorosync設定を変更します。そのため、実行前に /etc/pve/corosync.confをバックアップしておきます。
今回はpve1で作業します。
1 | mkdir -p /root/backup/corosync |
corosync.confをバックアップします。
1 | cp -a /etc/pve/corosync.conf \ |
現在のクラスタ状態も保存しておきます。
1 | pvecm status > /root/backup/corosync/pvecm-status.$(date +%Y%m%d-%H%M%S).txt |
バックアップが取得できていることを確認します。
1 | ls -l /root/backup/corosync |
クラスタ構成を変更する作業では、作業前の状態を残しておくことが重要です。
通常はpvecm qdevice removeでqdeviceを削除できますが、万が一の切り戻しを考えると、設定変更前のファイルを残しておくと安心です。
pvecm qdevice setupを実行する
準備ができたら、Proxmoxノード側でqdevice setupを実行します。qdevice setupは、pve1またはpve2のどちらか一方でのみ実行します。
今回はpve1で実行します。
1 | pvecm qdevice setup quory.internal |
初回接続時には、SSH fingerprintの確認が表示される場合があります。その場合は内容を確認してyesを入力します。
セットアップ中には、qnetd証明書の設定、corosync設定の更新、qdeviceサービスの起動などが行われます。正常に完了したら、エラーが出ていないことを確認します。エラーが出た場合は、そのまま先へ進まず、以下を確認します。
pve1 / pve2側です。
1 | pvecm status |
quory側です。
1 | systemctl status corosync-qnetd --no-pager |
qdeviceはクラスタ構成に関わるため、エラーが出た状態で作業を続けない方が安全です。
qdevice追加後の状態確認
qdevice setupが完了したら、クラスタ状態を確認します。
pve1またはpve2で実行します。
1 | pvecm status |
確認するポイントは以下です。
1 | Expected votes: 3 |
この状態になっていれば、pve1 / pve2の2ノードに加えて、qdeviceが投票に参加している状態です。
考え方としては以下のようになります。
1 | pve1 : 1 vote |
次に、corosync-qdeviceの状態を確認します。
1 | corosync-qdevice-tool -s |
Membership information、Vote、Stateなどが表示され、qdeviceが正常に認識されていることを確認します。
サービス状態も確認します。
pve1で実行します。
1 | systemctl status corosync-qdevice --no-pager |
pve2でも確認します。
1 | systemctl status corosync-qdevice --no-pager |
どちらもactive (running) であれば問題ありません。quory側では、qnetdの状態を確認します。
1 | systemctl status corosync-qnetd --no-pager |
こちらもactive (running) であることを確認します。最後に、quory側でTCP 5403の待ち受けも確認しておきます。
1 | ss -lntp | grep 5403 |
これで、2ノードProxmoxクラスタにqdeviceが追加され、quorumを安定させる構成になりました。
セットアップ完了後
一時許可ファイル削除
1 | sudo rm -f /etc/ssh/sshd_config.d/00-qdevice-root-temp.conf |
SSH設定構文確認
1 | sudo sshd -t |
問題がなければ(慎重に複数のSSHセッションを張って実行してください)
1 | sudo systemctl restart ssh |
rootパスワードのロック
1 | sudo passwd -l root |
ユーザーがsudo付きのコマンドを叩いたり、sudo -iするときのパスワードには無影響です。
公開鍵認証
普段、公開鍵認証をお使いの方はこのタイミングで公開鍵認証に移行されることをお勧めします。ここでは公開鍵認証の手順については割愛します。
ufwを設定される方は、以下のPortが開いている必要があります※IPv6やFromはお好みで。
1 | sudo ufw status |
第3部:HA構成と検証
さて、いよいよProxmoxサーバー側でのHA対応です。ここまで来れば、VMのマイグレーションもqdeviceがある状態で安全に運用できています。
改めての確認ですが、この記事では、前回記事のProxmoxを2台でクラスタ化する:VMマイグレーションでパッチ適用を楽にするで紹介した通り、共有ストレージは保有せずにZFSレプリケーションで、別ノードにVMディスクのコピーを作っておく方法を前提としています。
高価な共有ストレージが無くて良い代わりに、レプリケーションにはその間隔が開きますから、同期できていない時間の情報はフェイルオーバーすると失われます。最新のメモリ情報も連携されていないので、VMはもう片方のノードでブートから始まります。ここはライブマイグレーションとは大きく異なります。
HAに登録するVMを絞る
前述した通り、そのVMの適正に応じてHA戦略を立てる必要があります。HAに向いているVMは情報更新があまり発生しないものが対象になります。データ損失が致命的であるならばHAには向きません。
| 分類 | 条件 | 例 | 補足 |
|---|---|---|---|
| HA対象にしやすいVM | ZFSレプリケーションなどにより、復旧先ノードにVMディスクのコピーがある | FreeRADIUS、DNS、軽量な認証系、監視補助系 | VMディスクが復旧先に存在しない場合、HAで起動できません |
| HA対象にしやすいVM | 最後のレプリケーション以降の更新が失われても影響が小さい | 設定変更が少ないサービス、読み取り中心のサービス | ZFSレプリケーションは非同期のため、数分〜1時間程度の巻き戻りを許容できる必要があります |
| HA対象にしやすいVM | サービス停止をできるだけ避けたい | 認証、名前解決、ファイアウォール、家庭内ネットワークの基盤サービス | HAで復旧できても、完全な無停止ではありません |
| HA対象にしやすいVM | 障害時に別ノードで自動起動しても問題が少ない | ステートレス寄りのサービス、設定変更頻度が低いVM | 起動後にサービスが自動復旧できることも重要です |
| HAに向かないVM | データ損失が許されない | データベース、会計データ、重要な業務データを持つVM | 非同期レプリケーションでは、最後の同期後の更新が失われる可能性があります |
| HAに向かないVM | 書き込みが頻繁に発生する | ログサーバー、監視DB、時系列DB、頻繁に更新されるアプリケーション | 障害時の巻き戻りによる不整合が問題になりやすいです |
| HAに向かないVM | 障害後に手動確認してから起動した方が安全 | ストレージ系サービス、複雑なDB、状態管理が重いサービス | 自動起動よりも、状態確認後に復旧した方が安全な場合があります |
| HA対象にしなくてもよいVM | 停止しても影響が小さい | 検証用VM、一時的な作業VM、Cloud-Initで再作成できるVM | HA対象を増やしすぎると、障害時の挙動が複雑になります |
| HA対象にしなくてもよいVM | バックアップから戻せば十分 | 開発用VM、テスト環境、利用頻度の低いVM | HAではなく、バックアップと再作成で十分な場合があります |
私の場合は、HAに登録しているのはFirewall、Radiusサーバーの2つです。開発環境(ansibleなど)はレプリケーションを実行していますが、HAにはしていません。ノードがダウンして開発が止まるのは(仕事ではないので)許容できますが、ダウンのタイミングによって依存関係が崩れたりするのは致命的です(そもそものバックアップはGitHubがありますが、Pushしていない開発中の依存関係が崩れるのは避けたいものです)。
Firewallは滅多にルールを更新することはなく、仮にレプリケーションの実行間隔(15分毎)にノードがダウンして15分前の状態に戻ったとしてもほぼ問題はありません。せいぜいルールの1つか2つを登録し直すだけで済みます。それよりもFirewallが止まれば自宅全体のネットが止まるわけですからむしろ細かいことよりもサービス復旧が優先です。
もう1つ家族のために必須のサービスがWi-Fi向けのWPA3 Enterprise認証のFree Radiusサーバーです。これは負荷も極めて低くリソースもほとんど要らないサービスですが、ダウンしていると家族がWi-Fiに接続できなくなります。私が仕事で外出している時にそうなっては困るのでFirewall同様、ダウンタイムが許されないサービスになります。個人で運用しているものなのでユーザー追加は頻度が極めて少ないという事が一般的にも言えますし、この環境ではEAP-TLSでCA証明書によって利用ユーザーが署名されているため、RADIUSに対して新しいユーザー登録、新しいデバイスの登録という必要もなく、Radiusには1つのCA証明書(公開鍵)が置いてあるだけで、ほぼ更新が発生することはありません。
別の言い方をすれば、HA登録するためにできるだけ更新が発生しないようなVMを設計・構築するという考え方もあります。
HAにVMを登録する
まず最初にHA登録されるVMがレプリケーション設定されているかを確認してください。これが大前提となります。
Proxmoxにログインし、データセンターからHAを選択します。
ここでHAを登録することになります。
大事なところはフェイルバックのチェックを外すことです。これがチェックされていると、対象ノードがダウンしていない限りはVMを意図的に別ノードに移動させても、本来稼働しているノードが稼働していれば、当該ノードに戻ってしまうからです。
続いて、HAの中のアフィニティルールを定めます。
通常動作するノードのプライオリティを高くしておきます。
なお、注意点として、シャットダウンやリブートなどユーザーが意図的に実施したアクションに対してはフェイルオーバーは発生しません。VMが稼働しているノードをダウンさせた場合、そのVMを抱えたままノードは停止またはリブートします。
テストVMでフェイルオーバーを確認する
実際の障害シナリオ
pve2の電源障害を想定しました。
HA対象としたVMは、検証用のUbuntu VMであるvm:100です。検証を分かりやすくするため、この時点ではSophos FirewallやRADIUS用VMはHA対象から外し、vm:100のみをHA対象としました。
事前状態は以下の通りです。
1 | HA対象VM: vm:100 |
pve2の電源を強制的に停止させたところ、pve1側ではcorosyncがpve2との通信断を検知し、その後HA managerがpve2を障害ノードとして扱いました。
ログ上の流れは以下の通りです。
1 | 08:19頃 事前ログ・状態確認 |
実際のHAログでも、以下のようにvm:100がpve2からpve1へ復旧されたことを確認できました。
1 | service 'vm:100': state changed from 'fence' to 'recovery' |
その後、ha-manager statusを確認すると、vm:100はpve1上で起動していました。
1 | quorum OK |
また、8:50時点でVM内からuptime -pを確認したところ、以下のように表示されました。
1 | uptime -p |
このことから、VM内のOSとしても8:23頃に起動していたことが確認できます。Proxmox側のログでは8:22:56にVM起動が完了しているため、HAログ、VM状態、ゲストOS内のuptimeが整合する結果となりました。
フェイルオーバー後のレプリケーション
HAフェイルオーバー後、vm:100はpve1上で起動しました。
その後、pve2を起動してクラスタへ復帰させたところ、vm:100はpve1上で稼働したままでした。これは、HA設定でfailback 0としているためです。障害ノードが復帰しても、VMは自動的には元のノードへ戻りません。
一方で、ZFSレプリケーションは現在の稼働ノードに合わせて継続されました。
フェイルオーバー直後、pve2はまだ停止していたため、pve1からpve2へのレプリケーションは一度失敗し、通知が発生しました。しかし、pve2を起動してクラスタへ復帰させると、次回のレプリケーションで正常に同期されました。
8:56時点でpvesr statusを確認すると、vm:100のレプリケーション先はlocal/pve2となっており、8:45の定期同期も正常に完了していました。
1 | JobID Enabled Target LastSync NextSync Duration FailCount State |
通常時、vm:100はpve2で稼働し、pve2からpve1へレプリケーションされていました。
しかし、HAフェイルオーバー後はvm:100がpve1で稼働しているため、レプリケーション方向もpve1からpve2へ切り替わっていました。
この結果から、今回のProxmox VE 9.2環境では、HAフェイルオーバー後もVMの稼働ノードに合わせてZFSレプリケーションが継続されることを確認できました。
なお、このタイミングでProxmoxから通知設定されている宛先に対して自動的に通知が行われていることも確認できました。私はProxmox上でSlackに対してWeb hookを設定していますが、以下の内容がスマホのSlack宛に通知されました。
まとめ
今回は、2ノードProxmoxクラスタにqdeviceを追加し、ZFSレプリケーション環境でHAフェイルオーバーがどのように動作するかを検証しました。
qdeviceを追加することで、2ノード構成でも安定してquorumを維持できるようになりました。さらに、HA対象VMを限定したうえでpve2の電源断を行い、vm:100がpve1上で自動起動することを確認しました。
今回の検証では、pve2の電源断からpve1上でVMが起動するまで、ログ上では約2分程度かかりました。HAフェイルオーバーはライブマイグレーションではないため、メモリ状態は引き継がれず、VMは復旧先ノードで再起動されます。
また、共有ストレージを利用せず、ローカルZFSとレプリケーションで構成している場合、復旧先ノードで起動するVMのディスク状態は、最後にレプリケーションされた時点のものになります。そのため、前回レプリケーションからノード障害発生までの間に更新されたデータは失われる事になります。
一方で、停止すると困るものの、数分程度のデータ巻き戻りを許容できるVMに対しては、今回の構成は十分に有効だと感じました。
なお、すべてのVMをHA対象にすればよいわけではありません。例えば監視系VMのように、障害直前までのログを可能な限り保持したいVMは、あえてHAには登録しない判断もあります。
VMごとに、サービス停止の影響、データ更新頻度、失ってよいデータの範囲を整理したうえで、HA対象にするかどうかを決めることが重要です。