はじめに
前回の記事では、Proxmox VE 8.3 のネステッド仮想化環境上に Harvester v1.7.1 の3ノードクラスタを構築しました。本記事はその続編として、同じ Proxmox ホスト上で稼働する TrueNAS Scale の iSCSI Target から提供される LUN を、Harvester の Longhorn 共有ストレージとして組み込みます。
Harvester のデフォルトでは、各ノードのインストールディスク上に Longhorn のストレージ領域が確保されます。今回は外部ストレージとして TrueNAS の iSCSI LUN を追加し、3ノードにレプリカを分散配置できる共有ストレージを構成します。
前提条件
本記事は以下の環境が構築済みであることを前提とします。
| 項目 | 内容 |
|---|---|
| Proxmox VE | 8.3.0 (kernel 6.8.12-4-pve) |
| Harvester | v1.7.1 (3ノードクラスタ構築済み) |
| harvester01 | 192.168.11.71, VMID 131, 8 vCPU, 16 GB RAM |
| harvester02 | 192.168.11.72, VMID 132, 8 vCPU, 16 GB RAM |
| harvester03 | 192.168.11.73, VMID 133, 8 vCPU, 16 GB RAM |
| Management VIP | 192.168.11.70 |
| TrueNAS Scale | 192.168.11.4, VMID 102, Proxmox 上の VM |
| ネットワーク | vmbr0 (192.168.11.0/24)、VLAN なし |
構成概要
┌─────────────────────────────────────────────────────┐
│ Proxmox VE 8.3 ホスト (192.168.11.45) │
│ │
│ ┌──────────┐ iSCSI ┌────────────────────────┐ │
│ │ TrueNAS │◄──────────►│ Proxmox iSCSI Client │ │
│ │ Scale │ Target: │ │ │
│ │ VM 102 │ harvester │ sdc(lun1) │ │
│ │ │ LUN 0,1,2 │ sdd(lun2) │ │
│ │ │ │ sde(lun3) │ │
│ └──────────┘ └───┬────┬────┬──────────┘ │
│ │ │ │ │
│ scsi1 │ │ │ scsi1 │
│ ┌────────┘ │ └────────┐ │
│ ▼ ▼ ▼ │
│ ┌───────────┐ ┌───────────┐ ┌───────────┐
│ │harvester01│ │harvester02│ │harvester03│
│ │ VM 131 │ │ VM 132 │ │ VM 133 │
│ │ /dev/sdb │ │ /dev/sdb │ │ /dev/sdb │
│ │ iscsi-lun1│ │ iscsi-lun2│ │ iscsi-lun3│
│ └───────────┘ └───────────┘ └───────────┘
│ │ │ │
│ └─────────────┼─────────────┘
│ Longhorn Replica × 3
│ StorageClass: longhorn-iscsi
└─────────────────────────────────────────────────────┘
接続方式について
Harvester VM に外部ストレージの LUN を認識させる方法は2つあります。
方式A: Proxmox 側で iSCSI LUN を接続し、VM に仮想ディスクとしてパススルー — Proxmox ホストが iSCSI Initiator として TrueNAS に接続し、認識した LUN を各 VM の追加 SCSI ディスク(scsi1)として割り当てます。VM 内部からは通常の SCSI ディスク /dev/sdb として見えるため、Harvester 側で特別なパッケージや設定は不要です。
方式B: Harvester VM 内部から iscsiadm で直接 iSCSI 接続 — VM の OS から直接 iSCSI Target に接続します。Harvester (SLE Micro) は immutable OS のため、iscsiadm パッケージの永続化に追加の考慮が必要になります。
本記事では、シンプルで追加パッケージ不要な方式Aを採用しました。
1. TrueNAS iSCSI Target の設定
TrueNAS Scale の Web UI(http://192.168.11.4)から iSCSI Target を設定します。
1.1 Zvol の作成
Storage → Datasets で ZFS pool 配下に Zvol を3つ作成します。今回の環境では zpool/pool 配下に以下の Zvol が作成済みです。
+--------------------------------------------------+
| Dataset Name | 使用済/利用可能 | 暗号化 |
|--------------|-------------------|-------------|
| zpool | 1.19 TiB/224.74 GiB| Unencrypted |
| └ pool | 1.19 TiB/224.74 GiB| Unencrypted |
| ├ lun1 | 101.57 GiB/326.31 GiB| Unencrypted |
| ├ lun2 | 101.57 GiB/326.31 GiB| Unencrypted |
| └ lun3 | 101.57 GiB/326.31 GiB| Unencrypted |
+--------------------------------------------------+
Zvol Details (lun3 の例):
Type: VOLUME
Sync: STANDARD
Compression Level: Inherit (LZ4)
ZFS Deduplication: OFF
Path: zpool/pool/lun3
各 Zvol のサイズは 100 GiB です。
1.2 iSCSI Global Configuration の確認
Shares → iSCSI → Target Global Configuration を確認します。
+-------------------------------+
| 全般の構成 |
|-------------------------------|
| Base Name: iqn.2005-10.org.freenas.ctl |
| iSNS Servers: (空欄) |
| Pool Available Space Threshold: (空欄) |
| iSCSI listen port: 3260 |
+-------------------------------+
Base Name がこの後作成する Target の IQN のプレフィックスになります。
1.3 Extent の作成
Shares → iSCSI → Extents → Add で Zvol と iSCSI Extent を紐づけます。3つ作成してください。
| Extent Name | Extent Type | Device |
|---|---|---|
| harvester-lun1 | Device | zvol/zpool/pool/lun1 |
| harvester-lun2 | Device | zvol/zpool/pool/lun2 |
| harvester-lun3 | Device | zvol/zpool/pool/lun3 |
作成後、Extents タブに以下のように表示されます。
+------------------------------------------------------------+
| Extents |
|------------------------------------------------------------|
| Extent Name | Device/File | Enabled |
|----------------|--------------------|---------|
| harvester-lun1 | zvol/zpool/pool/lun1 | Yes |
| harvester-lun2 | zvol/zpool/pool/lun2 | Yes |
| harvester-lun3 | zvol/zpool/pool/lun3 | Yes |
+------------------------------------------------------------+
1.4 Target の作成
Shares → iSCSI → Targets → Add で Target を1つ作成します。
+-----------------------------------------------+
| Edit iSCSI Target |
|-----------------------------------------------|
| Basic Info: |
| Target Name: harvester |
| Target Alias: (空欄) |
| |
| iSCSI Group: |
| Portal Group ID: 1 (block) ← 既存 Portal |
| Initiator Group ID: 1 (ALL Initiators Allowed) |
| Authentication Method: None |
+-----------------------------------------------+
注意: Portal Group ID の設定を忘れずに行ってください。 今回の作業では、Target 作成時に Portal Group ID を設定し忘れたため、Proxmox 側の iSCSI discovery で Target が表示されませんでした。Portal Group ID に既存の Portal(0.0.0.0:3260 でリッスンしているもの)を必ず紐づけてください。
1.5 Associated Targets の作成
Shares → iSCSI → Associated Targets → Add で Target と Extent を紐づけます。1つの Target に対して LUN ID を変えて3つ登録します。
| Target | LUN ID | Extent |
|---|---|---|
| harvester | 0 | harvester-lun1 |
| harvester | 1 | harvester-lun2 |
| harvester | 2 | harvester-lun3 |
作成後、Associated Targets タブは以下のようになります。
+--------------------------------------------+
| Associated Targets |
|--------------------------------------------|
| Target | LUN ID | Extent |
|-----------|--------|----------------------|
| harvester | 0 | harvester-lun1 |
| harvester | 1 | harvester-lun2 |
| harvester | 2 | harvester-lun3 |
+--------------------------------------------+
1.6 Proxmox からの疎通確認
Proxmox シェルから iSCSI discovery を実行し、Target が見えることを確認します。
root@pve:~# iscsiadm -m discovery -t sendtargets -p 192.168.11.4:3260
192.168.11.4:3260,1 iqn.2005-10.org.freenas.ctl:block
192.168.11.4:3260,1 iqn.2005-10.org.freenas.ctl:block2
192.168.11.4:3260,1 iqn.2005-10.org.freenas.ctl:harvester
iqn.2005-10.org.freenas.ctl:harvester が表示されれば OK です。
トラブルシュート: ここで harvester が表示されない場合は、以下を確認してください。
- TrueNAS の iSCSI Target 設定で Portal Group ID が設定されているか
- TrueNAS の iSCSI サービスを再起動する(System Settings → Services → iSCSI を Stop → Start)
- Proxmox 側の discovery キャッシュを削除して再実行する
iscsiadm -m discovery -p 192.168.11.4:3260 --op delete
iscsiadm -m discovery -t sendtargets -p 192.168.11.4:3260
2. Proxmox から iSCSI LUN を接続し Harvester VM にアタッチ
2.1 iSCSI Target へのログイン
Proxmox シェルで実行します。
root@pve:~# iscsiadm -m node -T iqn.2005-10.org.freenas.ctl:harvester \
-p 192.168.11.4:3260 --login
Logging in to [iface: default, target: iqn.2005-10.org.freenas.ctl:harvester, portal: 192.168.11.4,3260]
Login to [iface: default, target: iqn.2005-10.org.freenas.ctl:harvester, portal: 192.168.11.4,3260] successful.
2.2 LUN の認識確認
root@pve:~# lsblk -d -o NAME,SIZE,MODEL,TRAN | grep -i iscsi
sdc 100G iSCSI Disk iscsi
sdd 100G iSCSI Disk iscsi
sde 100G iSCSI Disk iscsi
3つの 100G iSCSI Disk が認識されています。
2.3 LUN とデバイスの対応確認
TrueNAS の Extent に表示されていたシリアル番号でデバイスと LUN の対応を特定します。
root@pve:~# for dev in sdc sdd sde; do
serial=$(lsblk -nd -o SERIAL /dev/$dev)
echo "$dev: serial=$serial"
done
sdc: serial=e602b7da4af9b8e
sdd: serial=b472a9d64bfd57e
sde: serial=a7dda03e485ad45
TrueNAS の Extents 画面のシリアル列と照合した結果は以下の通りです。
| デバイス | シリアル | TrueNAS Extent | Zvol |
|---|---|---|---|
| sdc | e602b7da4af9b8e | harvester-lun1 | zpool/pool/lun1 |
| sdd | b472a9d64bfd57e | harvester-lun2 | zpool/pool/lun2 |
| sde | a7dda03e485ad45 | harvester-lun3 | zpool/pool/lun3 |
2.4 各 Harvester VM に LUN をアタッチ
各 VM に追加 SCSI ディスク(scsi1)として iSCSI LUN を割り当てます。VM は稼働中のままホットアドできます。
root@pve:~# qm set 131 --scsi1 /dev/sdc
update VM 131: -scsi1 /dev/sdc
root@pve:~# qm set 132 --scsi1 /dev/sdd
update VM 132: -scsi1 /dev/sdd
root@pve:~# qm set 133 --scsi1 /dev/sde
update VM 133: -scsi1 /dev/sde
設定確認:
root@pve:~# qm config 131 | grep scsi1
scsi1: /dev/sdc,size=104857616K
root@pve:~# qm config 132 | grep scsi1
scsi1: /dev/sdd,size=104857616K
root@pve:~# qm config 133 | grep scsi1
scsi1: /dev/sde,size=104857616K
2.5 Harvester VM 内でのディスク認識確認
各 Harvester ノードのコンソール(Ctrl+Alt+F2 → rancher ユーザでログイン → sudo)でディスクが見えることを確認します。
harvester01:/home/rancher # lsblk -d -o NAME,SIZE,MODEL
NAME SIZE MODEL
loop0 3G
sda 400G QEMU HARDDISK
sdb 100G QEMU HARDDISK
sr0 1024M QEMU DVD-ROM
3台とも /dev/sdb (100G) が QEMU HARDDISK として認識されています。Proxmox の仮想ディスクパススルーにより、VM 内部からは通常の SCSI ディスクとして見えます。
3. ディスクのフォーマットとマウント
3.1 ext4 フォーマット
各ノードで /dev/sdb を ext4 でフォーマットします。各 VM に別々の LUN が割り当てられているため、3台それぞれで実行する必要があります。
# harvester01
harvester01:/home/rancher # sudo mkfs.ext4 -F /dev/sdb
mke2fs 1.47.0 (5-Feb-2023)
Discarding device blocks: done
Creating filesystem with 26214400 4k blocks and 6566400 inodes
Filesystem UUID: c53b4373-be9c-4822-a568-dfe5b5626d2c
...
Writing superblocks and filesystem accounting information: done
# harvester02
harvester02:/home/rancher # sudo mkfs.ext4 -F /dev/sdb
...
Filesystem UUID: 86005ce3-59ec-4f5d-8ce1-c7b6d41316d8
...
# harvester03
harvester03:/home/rancher # sudo mkfs.ext4 -F /dev/sdb
...
Filesystem UUID: 882e8bbc-7fb8-4382-a1b4-4d87c8afe959
...
フォーマット確認:
harvester01:/home/rancher # sudo blkid /dev/sdb
/dev/sdb: UUID="c53b4373-be9c-4822-a568-dfe5b5626d2c" BLOCK_SIZE="4096" TYPE="ext4"
3台とも TYPE="ext4" が表示されれば OK です。
3.2 マウント
各ノードにマウントポイントを作成し、マウントします。マウントポイントのディレクトリ名はノードごとに対応する LUN 番号にしています。
# harvester01
harvester01:/home/rancher # sudo mkdir -p /var/lib/harvester/extra-disks/iscsi-lun1
harvester01:/home/rancher # sudo mount /dev/sdb /var/lib/harvester/extra-disks/iscsi-lun1
# harvester02
harvester02:/home/rancher # sudo mkdir -p /var/lib/harvester/extra-disks/iscsi-lun2
harvester02:/home/rancher # sudo mount /dev/sdb /var/lib/harvester/extra-disks/iscsi-lun2
# harvester03
harvester03:/home/rancher # sudo mkdir -p /var/lib/harvester/extra-disks/iscsi-lun3
harvester03:/home/rancher # sudo mount /dev/sdb /var/lib/harvester/extra-disks/iscsi-lun3
マウント確認:
harvester01:/home/rancher # df -h /var/lib/harvester/extra-disks/iscsi-lun1
Filesystem Size Used Avail Use% Mounted on
/dev/sdb 98G 2.1M 93G 1% /var/lib/harvester/extra-disks/iscsi-lun1
3台とも /dev/sdb 98G がマウントされていれば OK です。
4. Longhorn ディスク登録
4.1 なぜ kubectl patch が必要なのか
Harvester Web UI の「Hosts → Edit Config → Storage」画面からディスクを追加するのが通常の方法ですが、Proxmox からパススルーした仮想ディスクは Harvester の NDM (Node Disk Manager) に認識されず、UI の Add Disk に表示されません(GitHub issue #6975 参照)。
そのため、Longhorn が内部で管理しているノード設定(Kubernetes カスタムリソース nodes.longhorn.io)を kubectl patch で直接編集し、マウント済みのディレクトリを filesystem タイプのディスクとして手動登録します。
4.2 既存ディスク名の確認
patch コマンドに既存の default-disk エントリを含めないと、Longhorn がそのディスクを削除してしまいます。必ず事前に既存のディスク名を正確に確認してください。
harvester01:/home/rancher # kubectl -n longhorn-system get nodes.longhorn.io harvester01 -o yaml | grep -A 5 " disks:"
disks:
default-disk-f4fae7db6516d736:
allowScheduling: true
diskDriver: ""
diskType: filesystem
evictionRequested: false
harvester01:/home/rancher # kubectl -n longhorn-system get nodes.longhorn.io harvester02 -o yaml | grep -A 5 " disks:"
disks:
default-disk-8c6696e816277068:
allowScheduling: true
diskDriver: ""
diskType: filesystem
evictionRequested: false
harvester01:/home/rancher # kubectl -n longhorn-system get nodes.longhorn.io harvester03 -o yaml | grep -A 5 " disks:"
disks:
default-disk-b07f36edbd75074:
allowScheduling: true
diskDriver: ""
diskType: filesystem
evictionRequested: false
確認結果:
| ノード | default-disk 名 |
|---|---|
| harvester01 | default-disk-f4fae7db6516d736 |
| harvester02 | default-disk-8c6696e816277068 |
| harvester03 | default-disk-b07f36edbd75074 |
4.3 kubectl patch によるディスク追加
harvester01 のコンソールから3台分を実行します。各 patch コマンドで既存の default-disk を維持しつつ、iSCSI LUN のディスクを追加しています。tags: ["iscsi"] は後で作成する StorageClass から参照するためのタグです。
harvester01:
kubectl -n longhorn-system patch nodes.longhorn.io harvester01 --type merge -p '
{
"spec": {
"disks": {
"default-disk-f4fae7db6516d736": {
"allowScheduling": true,
"diskDriver": "",
"diskType": "filesystem",
"evictionRequested": false,
"path": "/var/lib/harvester/defaultdisk",
"storageReserved": 0,
"tags": []
},
"iscsi-lun1": {
"allowScheduling": true,
"diskDriver": "",
"diskType": "filesystem",
"evictionRequested": false,
"path": "/var/lib/harvester/extra-disks/iscsi-lun1",
"storageReserved": 0,
"tags": ["iscsi"]
}
}
}
}'
harvester02:
kubectl -n longhorn-system patch nodes.longhorn.io harvester02 --type merge -p '
{
"spec": {
"disks": {
"default-disk-8c6696e816277068": {
"allowScheduling": true,
"diskDriver": "",
"diskType": "filesystem",
"evictionRequested": false,
"path": "/var/lib/harvester/defaultdisk",
"storageReserved": 0,
"tags": []
},
"iscsi-lun2": {
"allowScheduling": true,
"diskDriver": "",
"diskType": "filesystem",
"evictionRequested": false,
"path": "/var/lib/harvester/extra-disks/iscsi-lun2",
"storageReserved": 0,
"tags": ["iscsi"]
}
}
}
}'
harvester03:
kubectl -n longhorn-system patch nodes.longhorn.io harvester03 --type merge -p '
{
"spec": {
"disks": {
"default-disk-b07f36edbd75074": {
"allowScheduling": true,
"diskDriver": "",
"diskType": "filesystem",
"evictionRequested": false,
"path": "/var/lib/harvester/defaultdisk",
"storageReserved": 0,
"tags": []
},
"iscsi-lun3": {
"allowScheduling": true,
"diskDriver": "",
"diskType": "filesystem",
"evictionRequested": false,
"path": "/var/lib/harvester/extra-disks/iscsi-lun3",
"storageReserved": 0,
"tags": ["iscsi"]
}
}
}
}'
3台とも node.longhorn.io/harvesterXX patched と表示されれば成功です。
4.4 登録状態の確認
harvester01:/home/rancher # kubectl -n longhorn-system get nodes.longhorn.io harvester01 -o yaml | grep -A 50 "diskStatus"
diskStatus:
default-disk-f4fae7db6516d736:
conditions:
- ...
status: "True"
type: Ready
- ...
status: "True"
type: Schedulable
...
storageAvailable: 238551040000
storageMaximum: 238655954944
storageScheduled: 0
iscsi-lun1:
conditions:
- lastProbeTime: ""
lastTransitionTime: "2026-03-08T14:42:43Z"
message: Disk iscsi-lun1(/var/lib/harvester/extra-disks/iscsi-lun1) on node
harvester01 is ready
reason: ""
status: "True"
type: Ready
- lastProbeTime: ""
lastTransitionTime: "2026-03-08T14:42:43Z"
message: Disk iscsi-lun1(/var/lib/harvester/extra-disks/iscsi-lun1) on node
harvester01 is schedulable
reason: ""
status: "True"
type: Schedulable
diskDriver: ""
diskName: iscsi-lun1
diskPath: /var/lib/harvester/extra-disks/iscsi-lun1
diskType: filesystem
diskUUID: 283f4d78-63a5-42b3-8c94-82c441643ce3
filesystemType: ext2/ext3
3台とも以下の状態であることを確認してください。
| ノード | ディスク名 | Ready | Schedulable |
|---|---|---|---|
| harvester01 | iscsi-lun1 | True | True |
| harvester02 | iscsi-lun2 | True | True |
| harvester03 | iscsi-lun3 | True | True |
5. StorageClass の作成
iSCSI ディスク専用の StorageClass を作成します。diskSelector: "iscsi" により、タグ iscsi が付与されたディスクにのみレプリカを配置します。
harvester01:/home/rancher # kubectl apply -f - << 'EOF'
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: longhorn-iscsi
provisioner: driver.longhorn.io
parameters:
numberOfReplicas: "3"
staleReplicaTimeout: "30"
diskSelector: "iscsi"
reclaimPolicy: Delete
volumeBindingMode: Immediate
allowVolumeExpansion: true
EOF
storageclass.storage.k8s.io/longhorn-iscsi created
各パラメータの意味は以下の通りです。
| パラメータ | 値 | 説明 |
|---|---|---|
| numberOfReplicas | 3 | 3ノードにレプリカを分散配置 |
| diskSelector | iscsi | tag "iscsi" のディスクのみ使用 |
| reclaimPolicy | Delete | PVC 削除時にボリュームも自動削除 |
| volumeBindingMode | Immediate | PVC 作成時に即座にプロビジョニング |
| allowVolumeExpansion | true | PVC のサイズ拡張を許可 |
確認:
harvester01:/home/rancher # kubectl get storageclass longhorn-iscsi
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
longhorn-iscsi driver.longhorn.io Delete Immediate true 5s
6. レプリカ動作テスト
StorageClass が正しく動作し、3ノードにレプリカが分散配置されることを確認します。
6.1 テスト PVC 作成
harvester01:/home/rancher # kubectl apply -f - << 'EOF'
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test-iscsi-pvc
namespace: default
spec:
accessModes:
- ReadWriteMany
storageClassName: longhorn-iscsi
resources:
requests:
storage: 10Gi
EOF
persistentvolumeclaim/test-iscsi-pvc created
6.2 テスト Pod 作成
PVC が Bound になっても、ボリュームは detached 状態の場合があります。Pod をアタッチしてボリュームをアクティブにします。
harvester01:/home/rancher # kubectl apply -f - << 'EOF'
apiVersion: v1
kind: Pod
metadata:
name: test-iscsi-pod
namespace: default
spec:
containers:
- name: test
image: busybox
command: ["sleep", "3600"]
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: test-iscsi-pvc
EOF
pod/test-iscsi-pod created
6.3 確認(60秒後)
# PVC 状態
harvester01:/home/rancher # kubectl get pvc test-iscsi-pvc -n default
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
test-iscsi-pvc Bound pvc-9086eb3a-2a92-47cc-9817-32c2f3edee56 10Gi RWX longhorn-iscsi <unset> 84s
# Pod 状態
harvester01:/home/rancher # kubectl get pod test-iscsi-pod -n default
NAME READY STATUS RESTARTS AGE
test-iscsi-pod 1/1 Running 0 74s
# ボリューム状態
harvester01:/home/rancher # kubectl -n longhorn-system get volumes.longhorn.io \
-o custom-columns=NAME:.metadata.name,STATE:.status.state,ROBUSTNESS:.status.robustness
NAME STATE ROBUSTNESS
pvc-9086eb3a-2a92-47cc-9817-32c2f3edee56 attached healthy
# レプリカ分散確認
harvester01:/home/rancher # VOL=$(kubectl get pvc test-iscsi-pvc -n default -o jsonpath='{.spec.volumeName}')
harvester01:/home/rancher # kubectl -n longhorn-system get replicas.longhorn.io -l longhornvolume=$VOL \
-o custom-columns=NAME:.metadata.name,NODE:.spec.nodeID,STATE:.status.currentState,DISK:.spec.diskID
NAME NODE STATE DISK
pvc-9086eb3a-2a92-47cc-9817-32c2f3edee56-r-70d7d1e2 harvester01 running 283f4d78-63a5-42b3-8c94-82c441643ce3
pvc-9086eb3a-2a92-47cc-9817-32c2f3edee56-r-731de1e0 harvester02 running bc24b5ea-b07d-4aaa-bcf5-62185bedaffd
pvc-9086eb3a-2a92-47cc-9817-32c2f3edee56-r-e3c18b53 harvester03 running ca02807c-0811-4574-a80c-0f77f799d331
3つのレプリカが harvester01/02/03 に1つずつ分散配置され、すべて running であることが確認できました。DISK 列の UUID は各ノードの iSCSI LUN ディスクの UUID と一致しており、diskSelector: "iscsi" による振り分けが正しく機能しています。
6.4 テストリソースクリーンアップ
harvester01:/home/rancher # kubectl delete pod test-iscsi-pod -n default
pod "test-iscsi-pod" deleted
harvester01:/home/rancher # kubectl delete pvc test-iscsi-pvc -n default
persistentvolumeclaim "test-iscsi-pvc" deleted
# 30秒後に確認
harvester01:/home/rancher # kubectl -n longhorn-system get volumes.longhorn.io
No resources found in longhorn-system namespace.
ボリュームが完全に削除されました。reclaimPolicy: Delete が正しく機能しています。
7. 永続化設定
Harvester (SLE Micro) は immutable OS であり、/etc 等への変更は再起動時に消失します。/oem/ ディレクトリは COS_OEM パーティションに直接マウントされており永続的に保持されます。Harvester は起動時に /oem/*.yaml を cloud-init 形式で読み込み実行するため、ここにマウント処理を記述します。
7.1 Harvester VM 内のマウント永続化
各ノードで /oem/91_iscsi-mount.yaml を作成します。
harvester01:
harvester01:/home/rancher # sudo tee /oem/91_iscsi-mount.yaml << 'EOF'
name: iSCSI LUN Mount Configuration
stages:
boot:
- commands:
- mkdir -p /var/lib/harvester/extra-disks/iscsi-lun1
- sleep 5
- mount /dev/sdb /var/lib/harvester/extra-disks/iscsi-lun1 || true
EOF
harvester02:
harvester02:/home/rancher # sudo tee /oem/91_iscsi-mount.yaml << 'EOF'
name: iSCSI LUN Mount Configuration
stages:
boot:
- commands:
- mkdir -p /var/lib/harvester/extra-disks/iscsi-lun2
- sleep 5
- mount /dev/sdb /var/lib/harvester/extra-disks/iscsi-lun2 || true
EOF
harvester03:
harvester03:/home/rancher # sudo tee /oem/91_iscsi-mount.yaml << 'EOF'
name: iSCSI LUN Mount Configuration
stages:
boot:
- commands:
- mkdir -p /var/lib/harvester/extra-disks/iscsi-lun3
- sleep 5
- mount /dev/sdb /var/lib/harvester/extra-disks/iscsi-lun3 || true
EOF
sleep 5 はディスクデバイスの認識を待つためのものです。|| true はマウント失敗時に起動プロセスを止めないためのフェイルセーフです。
7.2 Proxmox 側の永続化設定
Harvester VM 内のマウントだけでなく、Proxmox ホスト側の iSCSI 接続と VM 起動順序も永続化が必要です。
iSCSI セッションの自動接続:
root@pve:~# iscsiadm -m node -T iqn.2005-10.org.freenas.ctl:harvester \
-p 192.168.11.4:3260 --op update -n node.startup -v automatic
root@pve:~# iscsiadm -m node -T iqn.2005-10.org.freenas.ctl:harvester \
-p 192.168.11.4:3260 --op show | grep node.startup
node.startup = automatic
VM 自動起動と起動順序の設定:
TrueNAS が先に起動し iSCSI サービスが利用可能になってから Harvester VM が起動するよう、起動順序を制御します。
# TrueNAS: 最初に起動、120秒待機(iSCSI サービス起動待ち)
root@pve:~# qm set 102 --onboot 1 --startup order=1,up=120
# Harvester VM: TrueNAS の後に起動
root@pve:~# qm set 131 --onboot 1 --startup order=2,up=30
root@pve:~# qm set 132 --onboot 1 --startup order=2,up=30
root@pve:~# qm set 133 --onboot 1 --startup order=2,up=30
確認:
root@pve:~# qm config 102 | grep startup
startup: order=1,up=120
root@pve:~# qm config 131 | grep startup
startup: order=2,up=30
起動の流れは以下のようになります。
- Proxmox ホスト起動
- iSCSI セッション自動接続(
node.startup = automatic)→ sdc/sdd/sde が認識される - TrueNAS VM (order=1) が起動、120秒待機
- Harvester VM 131/132/133 (order=2) が起動
- 各 VM 内で
/oem/91_iscsi-mount.yamlにより/dev/sdbが自動マウント - Longhorn が既に登録済みのディスクを検知し Ready 状態に復帰
7.3 再起動テスト
harvester01 で再起動テストを実施しました。
再起動前:
harvester01:/home/rancher # df -h /var/lib/harvester/extra-disks/iscsi-lun1
Filesystem Size Used Avail Use% Mounted on
/dev/sdb 98G 2.1M 93G 1% /var/lib/harvester/extra-disks/iscsi-lun1
harvester01:/home/rancher # kubectl -n longhorn-system get nodes.longhorn.io harvester01 \
-o yaml | grep -A 15 "iscsi-lun1" | grep -E "status:|type:"
status: "True"
type: Ready
status: "True"
type: Schedulable
再起動実行:
harvester01:/home/rancher # sudo reboot
再起動後:
harvester01:/home/rancher # df -h /var/lib/harvester/extra-disks/iscsi-lun1
Filesystem Size Used Avail Use% Mounted on
/dev/sdb 98G 2.1M 93G 1% /var/lib/harvester/extra-disks/iscsi-lun1
harvester01:/home/rancher # kubectl -n longhorn-system get nodes.longhorn.io harvester01 \
-o yaml | grep -A 15 "iscsi-lun1" | grep -E "status:|type:|message"
message: Disk iscsi-lun1(/var/lib/harvester/extra-disks/iscsi-lun1) on node
harvester01 is ready
status: "True"
type: Ready
message: Disk iscsi-lun1(/var/lib/harvester/extra-disks/iscsi-lun1) on node
harvester01 is schedulable
status: "True"
type: Schedulable
マウントと Longhorn ディスクの両方が自動復旧しました。再起動直後に Node harvester01 is down: manager pod longhorn-manager-XXXXX is not... というメッセージが表示される場合がありますが、longhorn-manager Pod の起動完了待ちによる一時的なものであり、数分で解消されます。
8. トラブルシューティング
8.1 TrueNAS iSCSI Target が discovery で表示されない
症状: Proxmox シェルで iscsiadm -m discovery を実行しても、作成した Target が一覧に表示されない。
原因: TrueNAS の Target 設定で Portal Group ID が未設定のままだった。
対処:
- TrueNAS Web UI → Shares → iSCSI → Targets → 対象 Target の編集画面を開く
- iSCSI Group の Portal Group ID に既存の Portal(0.0.0.0:3260)を設定して保存
- iSCSI サービスを再起動
- Proxmox 側で discovery キャッシュを削除して再実行
8.2 Longhorn ディスクが再起動後 Not Ready (NoDiskInfo) のままになる
症状: ノード再起動後、マウントは復旧しているが Longhorn ディスクが Ready に戻らない。
原因: Longhorn が以前の Disk UUID を記憶しており、マウントし直しただけでは Ready に戻らない場合がある。
対処手順:
Step 1 — ディスクを無効化:
kubectl -n longhorn-system patch nodes.longhorn.io <ノード名> --type merge -p '
{
"spec": {
"disks": {
"<ディスク名>": {
"allowScheduling": false,
"diskDriver": "",
"diskType": "filesystem",
"evictionRequested": false,
"path": "<マウントパス>",
"storageReserved": 0,
"tags": ["iscsi"]
}
}
}
}'
Step 2 — ディスクを削除:
kubectl -n longhorn-system patch nodes.longhorn.io <ノード名> --type merge -p '
{
"spec": {
"disks": {
"<ディスク名>": null
}
}
}'
Step 3 — ディスクを再登録:
kubectl -n longhorn-system patch nodes.longhorn.io <ノード名> --type merge -p '
{
"spec": {
"disks": {
"<ディスク名>": {
"allowScheduling": true,
"diskDriver": "",
"diskType": "filesystem",
"evictionRequested": false,
"path": "<マウントパス>",
"storageReserved": 0,
"tags": ["iscsi"]
}
}
}
}'
Step 2 で Please disable the disk and remove all replicas and backing images first エラーが出る場合は、Step 1 の無効化後にレプリカが退避されるまで待ってから再実行してください。
おわりに
TrueNAS Scale の iSCSI LUN を Proxmox の仮想ディスクパススルー経由で Harvester の Longhorn 共有ストレージとして組み込むことができました。
最終的な構成は以下の通りです。
| 項目 | 内容 |
|---|---|
| ストレージ | TrueNAS Scale (192.168.11.4) iSCSI Target |
| Target IQN | iqn.2005-10.org.freenas.ctl:harvester |
| LUN 数 | 3 (lun1/lun2/lun3, 各 100 GiB) |
| 接続方式 | Proxmox iSCSI → VM 仮想ディスク (scsi1) パススルー |
| Longhorn ディスク | iscsi-lun1/lun2/lun3 (tag: iscsi) |
| StorageClass | longhorn-iscsi (numberOfReplicas=3, diskSelector=iscsi) |
| 永続化 | /oem/91_iscsi-mount.yaml + Proxmox onboot + iSCSI automatic |
| 起動順序 | TrueNAS (order=1, up=120) → Harvester VM (order=2, up=30) |
| レプリカテスト | 3ノード分散配置 (healthy) 確認済み |