[難あり] ProxmoxクラスタでFC-SANのLUNをLVMとして利用する（with lvmlockd, sanlock）

## はじめに

クラスタ構成のProxmox環境で、FC-SANのLUNに直接LVMを作成すると問題が発生しました。

この問題の解消方法について調査したところ、RedHat社のドキュメント
[8.4. 複数のマシン間で SAN ディスクを共有するための LVM の設定](https://docs.redhat.com/ja/documentation/red_hat_enterprise_linux/8/html/configuring_and_managing_logical_volumes/configuring-lvm-on-san-multiple_configuring-lvm-on-shared-storage)
に、lvmlockdとsanlockを利用する方法が記載されていましたので、試してみました。

## 構成概要

本記事では、2台の Proxmox ホストをクラスタ構成で運用していることを前提としています。

- **ターゲット側 (SAN ストレージ)**
  - Fedora Server 41 を使用
  - 2ポートの QLogic 2662 HBA を実装
  - 2台の Proxmox ノードが同じ LUN にアクセス
  - FC ターゲットの設定は別記事で説明（本記事では省略）

- **Proxmox クラスタ側**
  - 2台の Proxmox ノード (Proxmox VE 8)
  - 1ポートの Emulex LPe12000 HBA を装備し、FC ターゲットに接続
  - 共有 LUN を LVM バックエンドとして使用

## 1. ProxmoxノードでFC LUNを確認

まず、FC経由でターゲットLUNが認識されているか確認します。

### HBAのWWPNを確認

```bash
cat /sys/class/fc_host/host*/port_name
```

```
root@d-1697:~# cat /sys/class/fc_host/host*/port_name
0x10000090fad99630
root@d-1698:~# cat /sys/class/fc_host/host*/port_name
0x10000090fad995fe
```

FCリンクアップ状態確認:

```bash
cat /sys/class/fc_host/host*/port_state
```

```
root@d-1697:~# cat /sys/class/fc_host/host*/port_state
Online
root@d-1698:~# cat /sys/class/fc_host/host*/port_state
Online
```

LUNが検出されているか確認:

```bash
lsblk | grep sdb
```

```
root@d-1697:~# lsblk | grep sdb
sdb                  8:16   0   200G  0 disk
root@d-1698:~# lsblk | grep sdb
sdb                  8:16   0   200G  0 disk
```

`sdb` として 200GB のLUNが見えていることを確認。

## 2. LVM の設定

### 物理ボリュームの作成
```bash
pvcreate /dev/sdb
```

```bash
root@d-1698:~# pvcreate /dev/sdb
  Physical volume "/dev/sdb" successfully created.
```


### lvmlockd, sanlock のインストール

全てのノードで、インストールを行います。

```bash
apt install lvm2-lockd
apt install sanlock
```

### 設定

#### /etc/lvm/lvm.conf

両ホストで、以下の通り編集します。

```bash
root@d-1698:/etc/lvm# diff -ruN lvm.conf.ORG lvm.conf
--- lvm.conf.ORG        2025-02-24 05:14:37.736314976 +0900
+++ lvm.conf    2025-02-28 16:50:12.664163129 +0900
@@ -1170,7 +1170,7 @@
        # case there is also lvmlockd(8) man page available for more
        # information.
        # This configuration option has an automatic default value.
-       # use_lvmlockd = 0
+       use_lvmlockd = 1
 
        # Configuration option global/lvmlockd_lock_retries.
        # Retry lvmlockd lock requests this many times.
```

#### /etc/lvm/lvmlocal.conf

両ホストで、以下の通り編集します。固有の host_id を設定します。

```bash
root@d-1698:/etc/lvm# diff -ruN lvmlocal.conf.ORG lvmlocal.conf
--- lvmlocal.conf.ORG   2022-10-20 04:37:31.000000000 +0900
+++ lvmlocal.conf       2025-02-28 16:57:33.971896408 +0900
@@ -53,5 +53,5 @@
        # This must be unique among all hosts, and must be between 1 and 2000.
        # Applicable only if LVM is compiled with lockd support
        # This configuration option has an automatic default value.
-       # host_id = 0
+       host_id = 98
}
root@d-1697:/etc/lvm# diff -ruN lvmlocal.conf.ORG lvmlocal.conf
--- lvmlocal.conf.ORG   2022-10-20 04:37:31.000000000 +0900
+++ lvmlocal.conf       2025-02-28 16:56:48.348338471 +0900
@@ -53,5 +53,5 @@
        # This must be unique among all hosts, and must be between 1 and 2000.
        # Applicable only if LVM is compiled with lockd support
        # This configuration option has an automatic default value.
-       # host_id = 0
+       host_id = 97
}
```

#### /etc/lvm/lvmlockd.hostid

両ホストで、以下の通り編集します。固有の host_id を設定します。

```bash
root@d-1698:/etc/lvm# cat lvmlockd.hostid
98
root@d-1697:/etc/lvm# cat lvmlockd.hostid
97
```

#### lvmlockd, sanlockの起動

両ノードで lvmlockd, sanlock を起動します。

```bash
root@d-1697:/etc/lvm# systemctl start lvmlockd
root@d-1697:/etc/lvm# systemctl status lvmlockd
● lvmlockd.service - LVM lock daemon
     Loaded: loaded (/lib/systemd/system/lvmlockd.service; enabled; preset: enabled)
     Active: active (running) since Fri 2025-02-28 17:09:38 JST; 2s ago
       Docs: man:lvmlockd(8)
   Main PID: 5710 (lvmlockd)
      Tasks: 3 (limit: 9241)
     Memory: 600.0K
        CPU: 2ms
     CGroup: /system.slice/lvmlockd.service
             mq5710 /sbin/lvmlockd --foreground

Feb 28 17:09:38 d-1697 systemd[1]: Starting lvmlockd.service - LVM lock daemon...
Feb 28 17:09:38 d-1697 lvmlockd[5710]: [D] creating /run/lvm/lvmlockd.socket
Feb 28 17:09:38 d-1697 lvmlockd[5710]: 1740730178 lvmlockd started
Feb 28 17:09:38 d-1697 systemd[1]: Started lvmlockd.service - LVM lock daemon.
root@d-1697:/etc/lvm# systemctl restart sanlock
root@d-1697:/etc/lvm# systemctl status sanlock
● sanlock.service - Shared Storage Lease Manager
     Loaded: loaded (/lib/systemd/system/sanlock.service; disabled; preset: enabled)
     Active: active (running) since Fri 2025-02-28 16:58:04 JST; 4s ago
       Docs: man:sanlock(8)
    Process: 3811 ExecStart=/usr/sbin/sanlock daemon $sanlock_opts (code=exited, status=0/SUCCESS)
   Main PID: 3812 (sanlock)
      Tasks: 6 (limit: 9241)
     Memory: 13.5M
        CPU: 6ms
     CGroup: /system.slice/sanlock.service
             tq3812 /usr/sbin/sanlock daemon -w 0
             mq3813 /usr/sbin/sanlock daemon -w 0

Feb 28 16:58:04 d-1697 systemd[1]: Stopped sanlock.service - Shared Storage Lease Manager.
Feb 28 16:58:04 d-1697 systemd[1]: Starting sanlock.service - Shared Storage Lease Manager...
Feb 28 16:58:04 d-1697 systemd[1]: Started sanlock.service - Shared Storage Lease Manager.
```

```bsah
root@d-1698:~# systemctl start lvmlockd
root@d-1698:~# systemctl status lvmlockd
● lvmlockd.service - LVM lock daemon
     Loaded: loaded (/lib/systemd/system/lvmlockd.service; enabled; preset: enable>
     Active: active (running) since Fri 2025-02-28 16:51:11 JST; 1s ago
       Docs: man:lvmlockd(8)
   Main PID: 2964 (lvmlockd)
      Tasks: 3 (limit: 9241)
     Memory: 640.0K
        CPU: 3ms
     CGroup: /system.slice/lvmlockd.service
             mq2964 /sbin/lvmlockd --foreground

Feb 28 16:51:11 d-1698 systemd[1]: Starting lvmlockd.service - LVM lock daemon...
Feb 28 16:51:11 d-1698 lvmlockd[2964]: [D] creating /run/lvm/lvmlockd.socket
Feb 28 16:51:11 d-1698 lvmlockd[2964]: 1740729071 lvmlockd started
Feb 28 16:51:11 d-1698 systemd[1]: Started lvmlockd.service - LVM lock daemon.
lines 1-15/15 (END)
root@d-1698:~# systemctl start sanlock
root@d-1698:~# systemctl status sanlock
● sanlock.service - Shared Storage Lease Manager
     Loaded: loaded (/lib/systemd/system/sanlock.service; enabled; preset: enabled)
     Active: active (running) since Fri 2025-02-28 16:51:38 JST; 17s ago
       Docs: man:sanlock(8)
    Process: 3224 ExecStart=/usr/sbin/sanlock daemon $sanlock_opts (code=exited, s>
   Main PID: 3226 (sanlock)
      Tasks: 6 (limit: 9241)
     Memory: 13.5M
        CPU: 7ms
     CGroup: /system.slice/sanlock.service
             tq3226 /usr/sbin/sanlock daemon -w 0
             mq3227 /usr/sbin/sanlock daemon -w 0

Feb 28 16:51:38 d-1698 systemd[1]: Starting sanlock.service - Shared Storage Lease>
Feb 28 16:51:38 d-1698 systemd[1]: Started sanlock.service - Shared Storage Lease >
lines 1-15/15 (END)
```

### ボリュームグループの作成

クラスタ対応のボリュームグループを作成します。

```bash
vgscreate --shared fc_vg /dev/sdb
```

```bash
root@d-1697:~# vgscreate --shared fc_vg /dev/sdb

  Enabling sanlock global lock
  Logical volume "lvmlock" created.
  Volume group "fc_vg" successfully created
```

### ボリュームグループを反映

両ノードで、ボリュームグループを反映します。
sanlock と表示されていれば問題ありません。

```bash
root@d-1698:/etc/lvm# vgchange --lock-start fc_vg
  Skipping global lock: lockspace not found or started
  VG fc_vg starting sanlock lockspace
  Starting locking.  Waiting for sanlock may take 20 sec to 3 min...
root@d-1698:/etc/lvm# vgs -o +lock_type
  VG    #PV #LV #SN Attr   VSize    VFree    LockType
  fc_vg   1   0   0 wz--ns <200.00g <199.00g sanlock
  pve     1   3   0 wz--n- <464.76g   16.00g
root@d-1697:/etc/lvm# vgchange --lock-start fc_vg
  Skipping global lock: lockspace not found or started
  VG fc_vg starting sanlock lockspace
  Starting locking.  Waiting for sanlock may take 20 sec to 3 min...
root@d-1697:/etc/lvm#  vgs -o +lock_type
  VG    #PV #LV #SN Attr   VSize    VFree    LockType
  fc_vg   1   0   0 wz--ns <200.00g <199.00g sanlock
  pve     1   3   0 wz--n- <464.76g   16.00g
```

## 3. Proxmox にLVMを登録

ProxmoxのWeb UIから、

1. **Datacenter** → **Storage**
2. **Add** → **LVM** を選択
3. 以下の設定を入力:
   - **ID**: fc_lvm
   - **ボリュームグループ**: `fc_vg`
   - **共有済み**: チェックを入れる
   - **ベースストレージ**: デフォルトのまま

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789581/1f66ea8d-1746-46e5-9739-f3b7cf702f57.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789581/aa445254-befc-4b5a-bb30-8cb79ad4f48e.png)

上記対応の結果として、Web UI の fc_san ストレージの ? は消えました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789581/82d54b62-bce8-4231-b2e3-efb6ebea794a.png)

## 4. OS インストール

fc_lvm に OS をインストールします。

## 5. マイグレーション

fc_lvm にインストールした VM をマイグレーションしてみます。

### Web UI からマイグレーション

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789581/fb10574e-ce67-464a-8a11-195d85112416.png)

マイグレートすると、以下の通り失敗します。

```bash
Task viewer: VM 100 - マイグレート (d-1697 ---> d-1698)
 
2025-02-28 18:20:26 starting migration of VM 100 to node 'd-1698' (192.168.11.98)
2025-02-28 18:20:26 starting VM 100 on remote node 'd-1698'
2025-02-28 18:20:28 [d-1698] can't activate LV '/dev/fc_vg/vm-100-disk-0':   Failed to lock logical volume fc_vg/vm-100-disk-0.
2025-02-28 18:20:28 ERROR: online migrate failure - remote command failed with exit code 255
2025-02-28 18:20:28 aborting phase 2 - cleanup resources
2025-02-28 18:20:28 migrate_cancel
2025-02-28 18:20:29 ERROR: migration finished with problems (duration 00:00:03)
TASK ERROR: migration problems
```

### 対処

調査を行ったところ、sanlock が LV をロックしているため、オンラインでのマイグレーションは行えないようです。このため、手動で以下のようにマイグレーション出来ることを確認しました。

#### 移行元ホスト d-1697 で VM をシャットダウン
```bash
qm shutdown 100
```

#### 移行元ホスト d-1697 で LVM を inactive にする
```bash
root@d-1697:/etc/lvm# lvchange -an /dev/fc_vg/vm-100-disk-0
```

#### 移行元ホスト d-1697 で sanlock のロックを解除
```bash
root@d-1697:/etc/lvm# sanlock client release -s lvm_fc_vg:98:/dev/mapper/fc_vg-lvmlock:0
release pid -1
release done -16
```

#### 移行先ホスト d-1698 で LVM をアクティブ化
```bash
root@d-1698:/etc/lvm# lvchange -ay /dev/fc_vg/vm-100-disk-0
```

#### 移行元ホスト d-1697 からマイグレーション
```bash
root@d-1697:/etc/lvm# qm migrate 100 d-1698 --online
VM isn't running. Doing offline migration instead.
2025-02-28 19:02:29 starting migration of VM 100 to node 'd-1698' (192.168.11.98)
2025-02-28 19:02:30 migration finished successfully (duration 00:00:01)
```

結果として、以下の通り WebUI から見ても移動されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789581/512f1d4e-a7c6-4874-937e-7e216e057536.png)

## まとめ

Proxmox において lvmlockd, sanlock を利用した場合、オンラインのマイグレーションが行えず、オフラインで手動でのマイグレーションが必要であることが分かりました。

手動によるマイグレーションは人手によるオペレーションは現実的ではありませんが、Proxmox にこだわらなければ、以下ドキュメントにあるように、Pacemaker のようなリソース管理ソフトと併用すれば実用に耐えるのかもしれません。

[24 Cluster logical volume manager (Cluster LVM)](https://documentation.suse.com/sle-ha/15-SP6/html/SLE-HA-all/cha-ha-clvm.html)

### 参考情報
lvmlockd, sanlock 用のリソース定義ファイルは以下の通りです。

[resource-agents/heartbeat/lvmlockd](https://github.com/ClusterLabs/resource-agents/blob/main/heartbeat/lvmlockd)

関連の Proxmox Forum のスレッドです。

[PVE 7.x Cluster Setup of shared LVM/LV with MSA2040 SAS (partial howto)](https://forum.proxmox.com/threads/pve-7-x-cluster-setup-of-shared-lvm-lv-with-msa2040-sas-partial-howto.57536/)