ProxmoxでZFSのプール作り直し（RAIDZ2からRAID1）

## 概要
かれこれ10年前くらい前、HP Microserver N54LにFreeNASを入れて4台のHDDでRAIDZ2を組んで、仮想基盤のデータストアとしてNFSマウントしたり、CIFSでファイル置き場として使っていました。FreeNASはその後ESXi上に移行し、4台のHDDは入れ替えつつ使っていましたが、4台のHDDが不要になったため、RAIDZ2からRAID1に変更します。
RAIDZ2のデータは全て別ストレージに移行しました。

## ZFS Poolの削除

### 現状確認
現在、Proxmox上でRAIDZ2を使用したZFSプールが構成されていますが、このプールはDEGRADED状態にあります。データの移行は不要で、既存のディスクを再利用してRAID1プールを新たに作成する必要があります。また、/dev/sdd2は既に取り外されており、/dev/sdcは作業中に取り外します。

```bash
root@pve:~# zpool status
  pool: zpool
 state: DEGRADED
status: One or more devices has been taken offline by the administrator.
        Sufficient replicas exist for the pool to continue functioning in a
        degraded state.
action: Online the device using 'zpool online' or replace the device with
        'zpool replace'.
  scan: scrub repaired 0B in 08:24:09 with 0 errors on Sun Jun  9 08:48:11 2024
config:

        NAME        STATE     READ WRITE CKSUM
        zpool       DEGRADED     0     0     0
          raidz2-0  DEGRADED     0     0     0
            sda     ONLINE       0     0     0
            sdc     ONLINE       0     0     0
            sdd2    OFFLINE      0     0     0
            sdb     ONLINE       0     0     0

errors: No known data errors
```

### Proxmox VEの管理画面から削除
既存のzpoolを選択して削除します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789581/97f7bfae-387a-d7be-4a9a-fd5df25970f4.png)

### 現在のRAIDZ2プールの破棄

1. **RAIDZ2プールの削除**
    ```bash
    zpool destroy zpool
    ```

```bash
root@pve:~# zpool destroy zpool
root@pve:~# zpool destroy status
cannot open 'status': no such pool
```

    - **注意点**: この操作により、`zpool`プール内のすべてのデータが完全に削除されます。重要なデータがないことを確認した上で実施します。

#### 既存のパーティションを削除 (fdisk使用)

1. **fdiskを使用してパーティションを削除**
    - `/dev/sda`のパーティション削除:
      ```bash
      fdisk /dev/sda
      ```
        - コマンドプロンプトで以下を入力:
        - `p` (パーティションテーブルを表示)
        - `d` (パーティションを削除)
        - パーティション番号を入力 (削除するパーティションを選択)
        - すべてのパーティションが削除されるまで `d` を繰り返し実行
        - `w` (変更をディスクに書き込み)

    - `/dev/sdb`のパーティション削除:
      ```bash
      fdisk /dev/sdb
      ```
      - コマンドプロンプトで以下を入力:
        - `p` (パーティションテーブルを表示)
        - `d` (パーティションを削除)
        - パーティション番号を入力 (削除するパーティションを選択)
        - すべてのパーティションが削除されるまで `d` を繰り返し実行
        - `w` (変更をディスクに書き込み)

    - `/dev/sdc`のパーティション削除:
      ```bash
      fdisk /dev/sdc
      ```
      - コマンドプロンプトで以下を入力:
        - `p` (パーティションテーブルを表示)
        - `d` (パーティションを削除)
        - パーティション番号を入力 (削除するパーティションを選択)
        - すべてのパーティションが削除されるまで `d` を繰り返し実行
        - `w` (変更をディスクに書き込み)

```bash
root@pve:~# fdisk /dev/sda

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


Command (m for help): p
Disk /dev/sda: 3.64 TiB, 4000787030016 bytes, 7814037168 sectors
Disk model: WDC WD40EZRZ-00G
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: A9443FEE-2D19-11EA-AC88-9CB654A9DA62

Device       Start        End    Sectors  Size Type
/dev/sda1      128    4194431    4194304    2G FreeBSD swap
/dev/sda2  4194432 7814037119 7809842688  3.6T FreeBSD ZFS
Command (m for help): d
Partition number (1,2, default 2):

Partition 2 has been deleted.

Command (m for help): d
Selected partition 1
Partition 1 has been deleted.

Command (m for help): p
Disk /dev/sda: 3.64 TiB, 4000787030016 bytes, 7814037168 sectors
Disk model: WDC WD40EZRZ-00G
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: A9443FEE-2D19-11EA-AC88-9CB654A9DA62

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

root@pve:~# fdisk /dev/sdb

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


Command (m for help): p
Disk /dev/sdb: 3.64 TiB, 4000787030016 bytes, 7814037168 sectors
Disk model: WDC WD40EZRZ-00G
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: 43C695A7-CEBF-11E8-9959-9CB654A9DA62

Device       Start        End    Sectors  Size Type
/dev/sdb1      128    4194431    4194304    2G FreeBSD swap
/dev/sdb2  4194432 5860533127 5856338696  2.7T FreeBSD ZFS

Command (m for help): d
Partition number (1,2, default 2):

Partition 2 has been deleted.

Command (m for help): d
Selected partition 1
Partition 1 has been deleted.

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

root@pve:~# fdisk /dev/sdc

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


Command (m for help): p
Disk /dev/sdc: 2.73 TiB, 3000592982016 bytes, 5860533168 sectors
Disk model: WDC WD30EZRX-00D
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: C8C168B2-CB2A-11E4-B0A4-9CB654A9DA62

Device       Start        End    Sectors  Size Type
/dev/sdc1      128    4194431    4194304    2G FreeBSD swap
/dev/sdc2  4194432 5860533127 5856338696  2.7T FreeBSD ZFS

Command (m for help): d
Partition number (1,2, default 2):

Partition 2 has been deleted.

Command (m for help): d
Selected partition 1
Partition 1 has been deleted.

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

:::note warn
以下手順を実行したところ、**failed to clear label**となりましたので、fdiskによる方式としました。
    
```bash
zpool labelclear -f /dev/sda
zpool labelclear -f /dev/sdb
zpool labelclear -f /dev/sdc
```
:::

## ディスク交換

1. **システムのシャットダウン**
    ```bash
    shutdown now
    ```
    - **注意点**: 物理的なディスクの取り外しを行うために、システムをシャットダウンします。

2. **/dev/sdcの物理的取り外し**
    - **注意点**: ディスクを取り外す際には静電気防止対策を行い、慎重に作業を進めます。

3. **システムの再起動**
    - 電源を入れてシステムを再起動します。

4. **ディスクの認識確認**
    - ディスクが認識していることを確認します。

```bash
root@pve:~# dmesg | grep sd[abcd]
[    1.506702] sd 0:0:0:0: [sda] 7814037168 512-byte logical blocks: (4.00 TB/3.64 TiB)
[    1.506705] sd 0:0:0:0: [sda] 4096-byte physical blocks
[    1.506715] sd 0:0:0:0: [sda] Write Protect is off
[    1.506718] sd 0:0:0:0: [sda] Mode Sense: 00 3a 00 00
[    1.506731] sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[    1.506749] sd 0:0:0:0: [sda] Preferred minimum I/O size 4096 bytes
[    1.938490]  sda:
[    1.938519] sd 0:0:0:0: [sda] Attached SCSI disk
[    2.578565] sd 3:0:0:0: [sdb] 7814037168 512-byte logical blocks: (4.00 TB/3.64 TiB)
[    2.578568] sd 3:0:0:0: [sdb] 4096-byte physical blocks
[    2.578577] sd 3:0:0:0: [sdb] Write Protect is off
[    2.578580] sd 3:0:0:0: [sdb] Mode Sense: 00 3a 00 00
[    2.578596] sd 3:0:0:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[    2.578612] sd 3:0:0:0: [sdb] Preferred minimum I/O size 4096 bytes
[    3.012684]  sdb:
[    3.012710] sd 3:0:0:0: [sdb] Attached SCSI disk
```
## ZFS Poolの追加

1. **新しいRAID1プールの作成**
    ```bash
    zpool create mirrorpool mirror /dev/sda /dev/sdb
    ```
    - **注意点**: 現在使用可能なディスクを利用してRAID1プールを作成します。

```bash
root@pve:~# zpool create zpool mirror /dev/sda /dev/sdb
```

2. **プールの状態確認**
    ```bash
    zpool status
    zfs list
    ```

```
root@pve:~# zpool status
  pool: zpool
 state: ONLINE
config:

        NAME        STATE     READ WRITE CKSUM
        zpool       ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            sda     ONLINE       0     0     0
            sdb     ONLINE       0     0     0

errors: No known data errors
root@pve:~# zfs list
NAME    USED  AVAIL  REFER  MOUNTPOINT
zpool   420K  3.51T    96K  /zpool
```

3. **ボリュームの作成**

    プールが作成されたら、「Share」と「Private」というボリュームを作成します。これには `zfs create` コマンドを使用します。

    ```bash
    zfs create zpool/Share
    zfs create zpool/Private
    ```

```bash
root@pve:~# zfs create zpool/Share
root@pve:~# zfs create zpool/Private
```

    作成したプールとボリュームを確認するために、以下のコマンドを使用します。

    ```sh
    zfs list
    ```

```bash
root@pve:~# zfs list
NAME            USED  AVAIL  REFER  MOUNTPOINT
zpool           728K  3.51T   104K  /zpool
zpool/Private    96K  3.51T    96K  /zpool/Private
zpool/Share      96K  3.51T    96K  /zpool/Share
```

4. **Proxmox VEの管理画面から追加**
新規のzpoolを選択して追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789581/b7d546ac-a6bb-8de0-319b-b017f35a9a27.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789581/38aa9ed9-e142-44b2-4aae-3e846e14afc2.png)

## 補足

ZFS Poolを作り直した際に、マウントポイントが以前と異なったため、lxcで起動していたSambaサーバが起動しなくなりました。

```
safe_mount: 1425 No such file or directory - Failed to mount "/mnt/zpool/Private" onto "/usr/lib/x86_64-linux-gnu/lxc/rootfs/mnt/Private"
mount_entry: 2213 No such file or directory - Failed to mount "/mnt/zpool/Private" on "/usr/lib/x86_64-linux-gnu/lxc/rootfs/mnt/Private"
lxc_setup: 3915 Failed to setup mount entries
do_start: 1273 Failed to setup container "100"
sync_wait: 34 An error occurred in another process (expected sequence number 3)
__lxc_start: 2114 Failed to spawn container "100"
TASK ERROR: startup for container '100' failed
```

このため、lxcの設定ファイルを修正し、正しいマウントポイントに変更することで起動するようになりました。

```bash
root@pve:/etc/pve/lxc# pwd
/etc/pve/lxc
root@pve:/etc/pve/lxc# diff -ruN 100.conf.BAK 100.conf
--- 100.conf.BAK        2024-06-30 12:40:57.000000000 +0900
+++ 100.conf    2024-06-30 12:46:49.000000000 +0900
@@ -10,8 +10,8 @@
 rootfs: local-lvm:vm-100-disk-0,size=8G
 swap: 1024
 unprivileged: 1
-lxc.mount.entry: /mnt/zpool/Private mnt/Private none bind,create=dir 0 0
-lxc.mount.entry: /mnt/zpool/Share mnt/Share none bind,create=dir 0 0
+lxc.mount.entry: /zpool/Private Private none bind,create=dir 0 0
+lxc.mount.entry: /zpool/Share Share none bind,create=dir 0 0
 lxc.idmap: u 0 100000 1000
 lxc.idmap: u 1000 65534 1
 lxc.idmap: u 1001 101001 64534
```