PVEの2ノードクラスターは冗長性がない話とその対策

:::note info
作成日：2024/5/3
PVE 8.2.2
:::

## TL;DL

- PVEの2ノードクラスターは構築可能だが、冗長性はありません。
  - 障害などにより Quorum を満たせなくなると、PVEノードは再起動します。
  - 再起動後、VM/CTの利用などできなくなります。
  - Quorum を満たせるようになると、クラスタ復旧し、利用が可能です。
- どれくらい冗長性がないかを、障害テストを起こして確認
- 対策など

## 概要
たまに２ノードクラスターを作りました！みたいな話をSNSやブログで見かけますが、それって冗長性なくない？と思ったの実際に障害テストをしてみました。


## 用語
- Quorum
  - 定足数。分散システムで操作を実行できるようにするために分散トランザクションが取得する必要がある最小投票数。
  - PVEでは**2ノードなら2**、3ノードなら2。
- Vote
  - 投票数。
  - デフォルトで1ノード1の投票権。
- スプリットブレイン
  - クラスタで各ノード間障害などにより各ノードでサービスが起動してしまうなどの状況
  - PVEではサービス（VM/CTの利用・設定変更など）の停止を行う


https://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%97%E3%83%AA%E3%83%83%E3%83%88%E3%83%96%E3%83%AC%E3%82%A4%E3%83%B3%E3%82%B7%E3%83%B3%E3%83%89%E3%83%AD%E3%83%BC%E3%83%A0


## 構成概要

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2459468/938df147-a2da-2231-effd-95ca16208de9.png)



概要図です。
172.16.0.0/24をクラスタ用ネットワークとして構成しています。
障害ポイントは以下。
※NW障害をPVEのFWを使って障害発生させているのは、各ノードをPonPで構築しているための制約です。


1. PVEノード障害（ノード起動・停止）
3. corosync経路間（PVE2のFWで遮断）
4. サービス・管理側経路間（PVE2のFWで遮断）

各ノードでCTを一つずつ構築し、HA設定も行っています。
※ですが、2ノードクラスターの場合は障害発生時に機能しません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2459468/494e120a-2d2e-bc87-7928-b09af86e6bc0.png)





## 障害テスト
### 1.PVEノード障害

PVE2の電源を停止・起動します。

`pvecm status`でクラスターの状態を確認します。

```
root@pve1:~# pvecm status 

 （中略）

Votequorum information
----------------------
Expected votes:   2
Highest expected: 2
Total votes:      1
Quorum:           2 Activity blocked
Flags:            

Membership information
----------------------
    Nodeid      Votes Name
0x00000001          1 172.16.0.1 (local)
root@pve1:~# 
```

Total votes が Quorum に達していないため、Activity blockedとなり、またFlags:のQuorateもなくっています。
一定時間すると、PVE1は一度再起動します。

再起動後、クラスター・PVE1の設定変更やVM/CTの起動などの操作は行えません。
そのため、PVE2上で動作しているCTがマイグレーションはされませんし、PVE1上のCTも停止します。

CTの起動や設定変更を実行しようとしても、以下の画像のようにエラーとなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2459468/30b8b632-b916-7b35-5165-c36d831c0604.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2459468/8b603b91-b7be-32d9-edfc-60b2282881a3.png)

PVE2の起動後、クラスタが正常な状態に戻れば復旧します。

**つまり、2ノードクラスター構成では1ノードで障害発生すると、障害発生ノード復旧までサービス停止となります。**



### 2.corosync経路間
172.16.0.0/24のcorosync（UDP 5405:5412 ）・SSH（TCP 22）をPVE2のファイアウォール機能（iptabels）で遮断します。
PVE1、2それぞれでノード障害時のPVE1と同様の状態となっています。
そのため、サービス停止はしているがデータ書き込みの競合などは発生しないようになっています。
もちろん、どちらのノードも利用はできないのでサービス停止状態です。

ちなみに、今回はPVE2のファイルウォール機能で通信を遮断しましたが、前述の通りPVEノードの設定変更はできなくなったため、リストアしました。

### 3.サービス・管理側経路間
同様に、172.16.0.0/24のcorosync（UDP 5405:5412 ）・SSH（TCP 22）をPVE2のファイアウォール機能（iptabels）で遮断します。
こちら側ネットワークはcorosyncに使われていないため、クラスタの状態には影響ありません。

## 対策案
予算などの都合で2ノードクラスターにした前提で、対策を検討しました。

### ３ノードクラスターにする
推奨されている構成のとおり、１ノード追加する方法です。
元々の２ノードと同じHWである必要はないし、オンラインマイグレーションをしないのであればCPUファミリーも合わせる必要はなさそうです。


> Online migration of virtual machines is only supported when nodes have CPUs from the same vendor. It might work otherwise, but this is never guaranteed.

VM/CTを動かさない（≒Qデバイス）のであれば、PVEさえインストールできれば何でもいいと思うので、余剰HWを探してみてください。
通常時は元々の２ノードで動かし、障害発生時にのみ一部VM・CTをマイグレーションする、などといった応用も可能そうです。


### Q（Quorum）デバイスを追加する
投票だけをするデバイスを追加する方法です。
corosync-qnetd パッケージが利用可能なら何でもよいので、既存環境を流用することも可能です。
新規で作成するのであれば別途CLIでの操作も発生するので、VM/CTを動かさないPVEノードを追加したほうが楽かもしれません。

https://pve.proxmox.com/pve-docs/chapter-pvecm.html#_qdevice_technical_overview

### フェイルオーバーリンクを追加する
ノード追加が出来ないが、NW障害だけでも対策した苦肉の策です。
※というか、2ノードクラスターにかかわらず、NW障害対策として検討するべき要素です。

NW構成に依存しますが、複数のネットワークをフェイルオーバーリンクとして設定することも可能です。
ただし、クラスタ設定変更のため、クラスタ再作成が必要です。

https://pve.proxmox.com/pve-docs/chapter-pvecm.html#pvecm_redundancy

### クラスタをやめる
冗長性のない2ノードクラスターを構築するぐらいなら、いっそクラスタ構成をやめるのも選択肢です。
※PVE1ノードにして、余ったHWをPBSとして構築し、バックアップを頻繁に取得してそこから復旧するなど。




## 参考


https://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%97%E3%83%AA%E3%83%83%E3%83%88%E3%83%96%E3%83%AC%E3%82%A4%E3%83%B3%E3%82%B7%E3%83%B3%E3%83%89%E3%83%AD%E3%83%BC%E3%83%A0


https://pve.proxmox.com/pve-docs/chapter-pvecm.html#chapter_pvecm