之前在Proxmox上面跑VM,扩展磁盘空间就是在 UI 上面 Resize disk 然后 VM 里面 growpart + resize2fs 就好了。结果这次给 TrueNAS Scale 上面的 VM 做同样的事情时遇到一点点小麻烦,有一些也是 zvol 相关的。在此记录一下。
此番在TrueNAS上面的VM,没有再像之前那样,整个 VM 就用一个 disk,一个挂载在根目录上面的的 Partition,而是把系统和数据放在不同的虚拟磁盘上面。在 TrueNAS 上面可以给这两个磁盘分别用不同的 data pool,应对系统和数据,在速度/容量/可靠性方面上的不同需求。
Add New Disk Device
首先创建VM以及添加设备的时候,会让选择 device mode,这里我是用的 virtio。没有试过 AHCI,不过据说AHCI可能性能会差一些。
小建议,随VM创建时添加的 Device,Order上面都是1xxx。后来添加的Disk Device (服务数据),建议采用2xxx,开头,用来跟系统盘区分。上图中用1001就很容易混淆。这个数字后期可以随时更改,并不需要过度担心。
Partition and Format
- 在 VM 里面,不知道为何,bulk device 是以 vd 开头的 (i.e.
ls -lhsta /dev/vd
可以看到所有磁盘,而不是一般常见的/dev/sd
。这个可能还是和 TrueNAS 对 QEMU 的使用方式有关。 lsblk -f
是更可靠的获得 dev 下面磁盘设备(块设备)的方式- 格式化的时候,要特别注意分区。一定要给一个partition number,即有一个分区,而不是把整个磁盘不经过 partition 直接格式化。也就是说,要用
mkfs -t ext4 /dev/sdb1
或者mkfs -t ext4 /dev/vdb1
而不是mkfs -t ext4 /dev/vdb
. - 对分区进行格式化的前提自然是要有分区:
fdisk /dev/vdb
,然后按照提示创建分区。 mkfs -t ext4
之后我们就该挂载了。这里自然要用 partition 的 UUID。通过lsblk -f
或者ls -lhst /dev/disk/by-uuid/*
找到刚刚格式化的分区。在fstab
里面进行修改即可。修改之后 使用sudo mount -a
, 现在的 Ubuntu 可能会要求用户更新 systemd 的配置sudo systemctl daemon-reload
(印象中最近的 Ubuntu,挂载方面都是走的 Systemd,可能不仅是 Ubuntu, Debian 应该也是)。
In fstab, add:
# Data disk mount
/dev/disk/by-uuid/xxxx06e6-xxxx-xxxx-xxxx-yyyy683cxxxx /data ext4 defaults 0 1
Extend Disk Size
-
在 TrueNAS 上面可以对 ZVol 的大小进行修改。目前我只试过改大。直接改小可能会有问题(或者不支持?通过 ZFS send/recv 其实可能可以做到,而且应该也是需要在VM里面的文件系统上把准备工作 fdisk 的一系列操作做好,但是无论怎样 inplace 直接改估计都有风险)。
-
Zvol改大了之后,需要到 VM Devices 里面稍微尝试修改一下 Disk Device 的 zvol。并不需要真的修改zvol,只需要调整一下,然后再调整回来,save。这样似乎才能让zvol的大小修改反映到QEMU上面,并在VM里面反映出来。
-
VM 重启后,应该可以在
fdisk /dev/vdb
看到这个变化。如果之前直接格式化了整个磁盘,而不是先分区,再格式化,就可能看不到磁盘大小的变化,导致没法扩容。 -
确认磁盘变大之后,在 VM 里面用
growpart /dev/vdb 1
然后再resize2fs /dev/vdb1
即可直接扩充 EXT4 文件系统的容量。
Move Zvol Around
(Technically, 这个不属于 resize 的一部分了。但是有时候resize很可能伴随着换存储池)
- 如果要迁移这个 zvol 的话,只需要在 TrueNAS 的 Shell 里面 (首先要获得 root 权限:sudo -i )运行:
zfs send apool/services-data | zfs recv -v bpool/services-data
即可完成数据的转移。但是这时我们会看到 recv 端zvol 大小和原始分配的大小不同。接收端的 zvol 实际上是 sparse provision 的,而原本的 ZVol 很可能是 Thick Provision 的。这里ZFS应该是在 send/recv 的时候这么做以节省需要传输的数据。相同的情况,网上例子还有很多: https://www.truenas.com/community/threads/moved-zvol-different-size-afterwards.107761/- 暂时我的解决方案就是
sudo zfs set refreservation=auto MyPoolA/Virtual_Disks/services-data
- 这是 Allocation Size 应该就对了。但是这个会随着 services-data 里面数据的增多,自动增长 services-data 分配的空间大小。甚至有时 reservation 本身跟 data 达到接近 1:1 的程度,占用大量 TrueNAS 层面 services-data parent dataset 的空间。需要特别注意。我采取的方法是,修改 recv 端 services-data 这个 ZVol 的大小(只应该是改大,因为 recv 的时候的大小一定是小于等于 send 端的 zvol 分配的大小的),然后再把 refreservation 设定为 none。目前看这依旧不是最佳方法,因为 recv 端的 provision type 还是显示为 sparse。不过使用中目前没有遇到什么问题。
- 关于 Sparse vs Thick 以及 refreservation 属性,可以参考:https://serverfault.com/a/894060。大概就是,如果 refreservation 有一个设定的数值大小,那么就是 thick 的。
- 暂时我的解决方案就是
- 迁移了之后,自然要到 VM 那边对相应的 disk device 的 zvol指向进行修改。建议还是 VM 先关机,然后再进行修改。