Proxmox VE 6.2と他のZFSプールを1ストレージに同居させる

Proxmox VE 7あたりでインストーラでパーティションを切ってZFSルート構成が作れるようになった。したがって本記事のような面倒な手段を取る必要はなくなった。

また、/etc/kernel/pve-efiboot-uuids/etc/kernel/proxmox-boot-uuidsに変わったようだ。

Proxmox VEをZFSルートシステムでインストールすると、EFIシステムパーティションなどを除いたディスクの全領域が、Proxmox VE用のプールrpoolとなってしまう。

諸々の事情により、うちの環境ではパーティションを切ってrpoolと他のZFSプールを1つのストレージ上に共存させたい。UEFIとZFSの組み合わせとなれば、臆するなかれ、FreeBSDで培ったスキルを活かしてPVEの全領域プールからパーティションプールへの移行ができるんじゃね?と考え試してみた記録。

好きな構成でDebianインストールしてからProxmox VEの環境入れればいいだって?うっせー、俺はLinuxわかんねーんだよ!

  • Proxmox VE 6.2-4
  • Intel DC S3700 400GB
    • PVEをインストールしたストレージ(sda)。便宜上、占有ストレージと呼ぶ。
  • Samsung PM963 1.92TB
    • PVEと他のZFSプールを同居させるストレージ(nvme0)。便宜上、共存ストレージと呼ぶ。

共存ストレージ作成にあたり、まずは占有ストレージのパーティションを確認する。

# fdisk -l /dev/sda
Disk /dev/sdh: 357.6 GiB, 384000000000 bytes, 750000000 sectors
Disk model: INTEL SSDSC2BA40
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: FDCAC366-6C27-4210-8305-0C33EE989D55

Device       Start       End   Sectors   Size Type
/dev/sda1       34      2047      2014  1007K BIOS boot
/dev/sda2     2048   1050623   1048576   512M EFI System
/dev/sda3  1050624 749999966 748949343 357.1G Solaris /usr & Apple ZFS

Partition 1 does not start on physical sector boundary.
# zfs list rpool
NAME    USED  AVAIL     REFER  MOUNTPOINT
rpool  12.1G   333G      104K  /rpool

4kセクタガン無視してパーティション切られててファッキューリーナスと思うが、それはさておき。

うちの環境ではBIOSブートはもう使わないので、BIOS bootは要らない。VMの仮想ディスクは専用プール(zimg)に確保するつもりなので、PVEのシステムプール(rpool)も最小限の容量とする。他に当方環境の諸々の事情を考慮し、共存ストレージは以下のパーティション構成とした。とりあえず、ESPとrpool用のパーティションがあればOK。

種類 容量 用途
FAT32 512MiB EFIシステムパーティション
ZFS 100GiB FreeBSDシステム (zroot)
ZFS 1434GiB VM用データ置き場 (zimg)
ZFS 50GiB PVEシステム (rpool)
- 250GiB 予備領域

共存ストレージにパーティションを作成する。

GPTを作る

# fdisk /dev/nvme2n1

Welcome to fdisk (util-linux 2.33.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0x5133f831.

Command (m for help): g
Created a new GPT disklabel (GUID: CEAAD3D1-5B58-524F-8E0D-26F1F3B2A24A).

nコマンドでパーティションを切って…

Command (m for help): n
Partition number (1-128, default 1): 
First sector (256-468843600, default 256): 
Last sector, +/-sectors or +/-size{K,M,G,T,P} (256-468843600, default 468843600): +512M

Created a new partition 1 of type 'Linux filesystem' and of size 512 MiB.

tコマンドでパーティションの種類を変える

Command (m for help): t
Partition number (1-4, default 4): 1
Partition type (type L to list all types): 1

Changed type of partition 'Linux filesystem' to 'EFI System'.

最終的に以下のようになる。ZFSを使う上でパーティションタイプは重要ではないが、後から見てもわかるように設定しておくのが無難。

Command (m for help): p
Disk /dev/nvme2n1: 1.8 TiB, 1920383410176 bytes, 468843606 sectors
Disk model: SAMSUNG MZQLW1T9HMJP-00003              
Units: sectors of 1 * 4096 = 4096 bytes
Sector size (logical/physical): 4096 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: CEAAD3D1-5B58-524F-8E0D-26F1F3B2A24A

Device             Start       End   Sectors  Size Type
/dev/nvme0n1p1       256    131327    131072  512M EFI System
/dev/nvme0n1p2    131328  26345727  26214400  100G FreeBSD ZFS
/dev/nvme0n1p3  26345728 402260223 375914496  1.4T Solaris /usr & Apple ZFS
/dev/nvme0n1p4 402260224 415367423  13107200   50G Solaris /usr & Apple ZFS

最後にwで書き込む。

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

作成したESPをFAT32でフォーマットする。

# mkdosfs -F 32 -S 4096 -s 1 -v -n EFI /dev/nvme1n1p1
mkfs.fat 4.1 (2017-01-24)
/dev/nvme2n1p1 has 64 heads and 32 sectors per track,
hidden sectors 0x0800;
logical sector size is 4096,
using 0xf8 media descriptor, with 131072 sectors;
drive number 0x80;
filesystem has 2 32-bit FATs and 1 sector per cluster.
FAT size is 128 sectors, and provides 130784 clusters.
There are 32 reserved sectors.
Volume ID is 517202a5, volume label EFI

既存ESPと新規ESPをマウントし、中身をコピーする。

# mkdir /mnt/esp /mnt/newesp
# mount /dev/sda2 /mnt/esp
# mount /dev/nvme1n1p1 /mnt/newesp
# cp -Rpv /mnt/esp/. /mnt/newesp/

今回はパーティションサイズが完全に一緒だったので、ddで丸コピーでもよかったかもしれない。

忘れずにアンマウント。

# umount /mnt/esp
# umount /mnt/newesp

PVEのシステムデータのコピー方法は、ZFSのミラーリングを使う方法、send/recvを使う方法の2種類がある。

方法1:ミラープールを経由する

ZFSのミラーリングを使う方法。

現在のrpoolに共存ストレージのnvme0n1p4をミラーとして追加し、同期完了後に占有ストレージのパーティションをミラーから切り離す。

簡単かつ安全な方法だが、今回は移行先のパーティションの方が小さいので使えない。残念。参考までに実行するコマンドは以下のようになる。なお、デバイス追加時にaddを使うとストライピングとして追加され、取り外し出来なくなるので注意!!

■ミラーの追加
# zpool attach rpool ata-INTEL_SSDSC2BA400G3_xxx-part3 nvme-SAMSUNG_MZQLW1T9HMJP-00003_yyyy-part4

■ミラーの取り外し
# zpool detach rpool ata-INTEL_SSDSC2BA400G3_xxx-part3

方法2:zfs send/recvを使う

ZFSのデータバックアップ・復元機能であるzfs send/recvを使う方法。正攻法と言えば正攻法。

使用中のデータ分のやり取りしか行わないので、小さなプールへのデータ移行が可能である。

移行元プールのプロパティ確認

移行にあたって、移行元プールのプロパティを確認しておく。

SOURCEがlocalとなっているプロパティが、そのプールとデータセットで独自に設定されたものなので、それらも移行先に移植する必要がある。

# zpool get all rpool | grep local
rpool  bootfs                         rpool/ROOT/pve-1               local
rpool  ashift                         12                             local
(feature flagsは無視してOK)

# zfs get all rpool | grep local
rpool  compression           on                     local
rpool  atime                 off                    local
rpool  sync                  standard               local
移行先プールの準備

上記のプロパティを踏まえて共存ストレージに移行先プールrpool2を作る。

# zpool create -o ashift=12 rpool2 /dev/disk/by-id/nvme-SAMSUNG_MZQLW1T9HMJP-00003_yyy-part4
専用ストレージから共存ストレージにデータを移動

ここからはProxmox VEのインストーラのシェルで作業する。インストーラをDebug Modeで起動し、1度目のシェルはそのままexitし、2度目のシェルに入る。

移行元と移行先プールのマウントポイントを作り、それぞれマウントする。-RでZFSの代替ルート指定を忘れずに行うこと。

# mkdir /run/rpool /run/rpool2
# zpool import -fR /run/rpool rpool
# zpool import -fR /run/rpool2 rpool2

移行元にスナップショットを作成。

# zfs snapshot -r rpool@backup

zfs send/recvでデータのコピーを行うが、まずはrecvに-nオプションを付けて、意図通りの場所に復元できるか確認する。-Fで上書き指定するので、間違うと結構悲惨なんだぜ。

# zfs send -RLce rpool@backup | zfs recv -Fduvn rpool2

問題なさそうなら、-nを外して本番実行。

# zfs send -RLce rpool@backup | zfs recv -Fduv rpool2

念のため移行先のrpool2の中身を見てみる。

# zfs list -r rpool2

移行先プールの名前変更

共存ストレージのrpool2を新生rpoolに名称変更する。

その前に、専用ストレージのrpoolが残ったままなので、こちらはrpool_origとでもしておく。

まずは両プールを一旦アンマウント。 </code> # zpool export rpool # zpool export rpool2 </code>

rpoolをrpool_origに名前を変えてマウント。

# zpool -R /mnt/rpool rpool rpool_orig

同じく、rpool2をrpoolに名前を変えてマウント。 </code> # zpool -R /mnt/rpool2 rpool2 rpool </code>

新生rpoolのbootfsの設定

共存ストレージのrpoolのbootfsが空のままなので、以前のrpoolの値を移植する。

# zpool set bootfs=rpool/ROOT/pve-1 rpool

最後に両プールをアンマウントする。

# zpool export rpool_orig
# zpool export rpool

あとはマシンを再起動し、ブートドライブとして共存ストレージの方を選べば、以前の環境はそのままに新しいrpoolの方からProxmox VEが起動するハズ。

シェルでzfs listすると、新しいrpoolになっていることが分かる。

# zfs list -r rpool
NAME               USED  AVAIL     REFER  MOUNTPOINT
rpool             15.3G  32.7G      104K  /rpool
rpool/ROOT        15.3G  32.7G       96K  /rpool/ROOT
rpool/ROOT/pve-1  15.3G  32.7G     15.3G  /
rpool/data          96K  32.7G       96K  /rpool/data

zfs send/recvの時に作ったスナップショットrpool@backupも新生rpoolにできているので、忘れずに消す。

# zfs destroy -r rpool@backup

PVEがESPの同期の時に使うUUIDの設定を変更する。変えなくてもPVE自体は動くが、update-initramfsなどをした時にESPが更新されなくなる。

blkidコマンドでパーティションのUUIDを表示する。

# blkid
/dev/nvme0n1p1: LABEL_FATBOOT="EFI" LABEL="EFI" UUID="5172-02A5" TYPE="vfat" PARTUUID="381a481f-926d-834a-b607-ab8c7f30d141"
/dev/nvme0n1p2: LABEL="zroot" UUID="14384939844916901067" UUID_SUB="4240071790088313073" TYPE="zfs_member" PARTUUID="618094f1-c1c8-0b4e-b685-06d67f86a449"
(略)
/dev/nvme0n1: PTUUID="9248b857-8f10-ca4b-a0c0-3ea559112855" PTTYPE="gpt"
/dev/nvme1n1: PTUUID="fe718aa7-f8d0-c149-88db-55afb4dbe75a" PTTYPE="gpt"
/dev/mapper/fbsd_disk0: PTTYPE="PMBR"
/dev/mapper/fbsd_disk1: PTTYPE="PMBR"

こんな感じでずらずらと表示される。

必要なのは、対象のESPのパーティションのUUIDである。うちの環境ではnvme0n1p1なので 5172-02A5 となる。

/etc/kernel/pve-efiboot-uuidsに入っている以前のUUIDを、この値で置き換える。

  • virtualization/proxmox_ve_6_2_share_disk_with_other_zpools.txt
  • 最終更新: 2023-02-09 22:51
  • by Decomo