Proxmoxの２ノードクラスタからオフラインのノードを削除する

# 背景
Proxmoxで、２ノードクラスタを構成していた。  
ノードID1(node1)のWEB画面にアクセスができなくなり、`journalctl`を確認すると`e1000e 0000:00:1f.6 enp0s31f6: Reset adapter unexpectedly`が発生していた。ネットワークに接続できていない模様。  
[フォーラム](https://forum.proxmox.com/threads/e1000e-reset-adapter-unexpectedly.87769/)を参考に軽く復旧を試みるもうまくいかない。  
クラスタから削除したいが、`pvecm delnode node1`コマンドを実行すると、`cluster not ready - no quorum?`と表示されて削除されない。  

# 結論
```
# quorumの票数を1に変更する
pvecm expected 1
# node1をクラスタから削除
pvecm delnode node1
# 不要な設定ファイルを削除
rm -r /etc/pve/nodes/node1
# 不要なSSHキーを削除
vi /etc/pve/priv/authorized_keys
```

# 構成
|ホスト名|ID|IP|pveversion|
|---|---|---|---|
|node1|1|192.168.100.1|pve-manager/8.1.5/60e01c6ac2325b3f<br>(running kernel: 6.5.13-3-pve)|
|node2|2|192.168.100.2|pve-manager/8.1.3/b46aac3b42da5d15<br>(running kernel: 6.5.11-4-pve)|

# 状況
``` text:root@node2 # pvecm status
Cluster information
-------------------
Name:             Pon2gFactory
Config Version:   2
Transport:        knet
Secure auth:      on

Quorum information
------------------
Date:             Thu Apr 18 08:20:33 2024
Quorum provider:  corosync_votequorum
Nodes:            1
Node ID:          0x00000002
Ring ID:          2.3b
Quorate:          No

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

Membership information
----------------------
    Nodeid      Votes Name
0x00000002          1 192.168.100.2 (local)
```
``` text:root@node2 # cat /etc/pve/corosync.conf
logging {
  debug: off
  to_syslog: yes
}

nodelist {
  node {
    name: node1
    nodeid: 1
    quorum_votes: 1
    ring0_addr: 192.168.100.1
  }
  node {
    name: node2
    nodeid: 2
    quorum_votes: 1
    ring0_addr: 192.168.100.2
  }
}

quorum {
  provider: corosync_votequorum
}

totem {
  cluster_name: Pon2gFactory
  config_version: 2
  interface {
    linknumber: 0
  }
  ip_version: ipv4-6
  link_mode: passive
  secauth: on
  version: 2
}
```

`Quorate: No`になっているので、冒頭の`pvecm delnode`コマンドが利かなかった。  

# 手順
```
# quorumの票数を1に変更する
pvecm expected 1
# node1をクラスタから削除
pvecm delnode node1
```

加えて、以下により不要な設定を削除しておく
```
# 不要な設定ファイルを削除
rm -r /etc/pve/nodes/node1
# 不要なSSHキーを削除
vi /etc/pve/priv/authorized_keys
```

# 実行後の結果
上記手順を実行後の状況は次のようになった。（unified形式のdiffで表示）  
無事、`Quorate: Yes`になっていて、node1が削除されている。  

``` diff_text:root@node2 # pvecm status
 Cluster information
 -------------------
 Name:             Pon2gFactory
-Config Version:   2
+Config Version:   3
 Transport:        knet
 Secure auth:      on

 Quorum information
 ------------------
-Date:             Thu Apr 18 08:20:33 2024
+Date:             Thu Apr 18 15:11:58 2024
 Quorum provider:  corosync_votequorum
 Nodes:            1
 Node ID:          0x00000002
-Ring ID:          2.3b
-Quorate:          No
+Ring ID:          2.40
+Quorate:          Yes

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

 Membership information
 ----------------------
     Nodeid      Votes Name
 0x00000002          1 192.168.100.2 (local)
```
``` diff_text:root@node2 # cat /etc/pve/corosync.conf
 logging {
   debug: off
   to_syslog: yes
 }

 nodelist {
-  node {
-    name: node1
-    nodeid: 1
-    quorum_votes: 1
-    ring0_addr: 192.168.100.1
-  }
   node {
     name: node2
     nodeid: 2
     quorum_votes: 1
     ring0_addr: 192.168.100.2
   }
 }

 quorum {
   provider: corosync_votequorum
 }

 totem {
   cluster_name: Pon2gFactory
-  config_version: 2
+  config_version: 3
   interface {
     linknumber: 0
   }
   ip_version: ipv4-6
   link_mode: passive
   secauth: on
   version: 2
 }
```

# その他の方法
今回はquorateにできたので普通に削除できたが、どうしてもうまくいかない場合の方法も ドキュメントに記載されている。  
https://pve.proxmox.com/pve-docs/pve-admin-guide.html#_remove_a_cluster_node

> 5.5.1 Separate a Node Without Reinstalling
> This is not the recommended method, proceed with caution. Use the previous method if you're unsure.

アクティブなノードをこの方法でクラスタから削除する場合、注意が必要。共有ストレージを設定している場合、事前に分離しておかないと、クラスタから削除後も共有ストレージにアクセスができちゃうので競合が発生してしまうとのこと。詳細は公式ドキュメントを参照。  

``` クラスタに残す側での作業
# サービスを停止する
systemctl stop pve-cluster
systemctl stop corosync
# ファイルシステムをローカルモードで再起動する
pmxcfs -l
# corosyncの設定ファイルを削除する
rm /etc/pve/corosync.conf
rm -r /etc/corosync/*
# ファイルシステムを起動する
killall pmxcfs
systemctl start pve-cluster
# ノードを削除する
pvecm delnode <oldnode>
# quorumを満たしていなくて削除コマンドが失敗した場合は、
# `pvecm expected 1`を実施してから再度実施
# （今回やった手順と同じ）

# 不要な設定ファイルを削除
rm -r /etc/pve/nodes/<oldnode>
# 不要なSSHキーを削除
vi /etc/pve/priv/authorized_keys
```

``` クラスタから削除する側での作業
# 再度クラスタに追加されてしまわないよう、
# クラスタファイルを削除する
rm /var/lib/corosync/*
```

# 感想
quorumの状況が理解できればなんてことはなかった。  
quorateな状態にして、不要なノードを削除するというだけ。  

# 余談
quorumって、文章中でどう使えばいいの？  
日本語訳すると「定足数」らしいけど、クラスタのクォーラム？クラスタの**何の**クォーラム？  
quorateは「定足数に足りている状態」を表す形容詞なので、クラスタのクォーラムがquorateってのもおかしい。難しい。  

# 余談２
クラスタを組む目的として、可用性目的なら２台でのクラスタってのはきっと無意味。  
あと、２ノードクラスタの場合、quorumの設定を次のようにしておくのが正しい方法らしい。  
``` diff_text:/etc/pve/corosync.conf
quorum {
  provider: corosync_votequorum
+ two_node: 1
}
```

拡張性のためにクラスタを組んでいたので、詳しくは知らない。