akam1oの日記

クラウドを作るお仕事をしています

Proxmox VE で VM に virtiofs で ZFS を見せたい

1. 概要

Proxmox VE で VM に virtiofs で ZFSディレクトリを見せる方法についてまとめていきます。

PVE 8.X で virtiofs も対応予定なので、今すぐ使いたいとかでなければ待ったほうが丸いです。

2. 背景

Proxmox VE を便利に使っていて、Proxmox で作った ZFS をどうやって VM に見せるかを悩んでいました。

いくつか思いついたものについて下記に示します。

  • 仮想ディスクを ZFS 上に作成する
    • 他の VM からのアクセスができない
    • 仮想ディスクの破損時の対応が面倒
  • HDD を直接 host passthrough して VM に見せる/VMZFS を再構成
    • 他の VM からのアクセスができない
    • VMZFS が一蓮托生
      • そんなに頻繁に ZFS 動かさんし…
  • virtiofs で仮想ホストのディレクトリを共有
    • 他の VM からもアクセスさせることができる
    • 用途によって見せるディレクトリを分けたり管理が楽そう

以上の理由と、上モノの VM は頻繁に作り直したいというのもあり virtiofs で見せることにしました。

3. virtiofs について

virtiofs は仮想ホストのファイルシステムVM に見せることのできる技術。

KVM Forum 2019 の Stefan Hajnoczi 氏の発表がまとまっていてわかりやすい。

一言で言うと 9p が遅いので、今っぽく作り直したもの。

4. 構築

4.1 virtiofs install

Proxmox の repo に virtiofsd があったのでそちらを使っていきます。

# apt install virtiofsd

build 必要ないのは助かりました。

4.2 virtiofs デバイスをアタッチするよう qemu の args に直接書く

今後 PVE 側のアップデートで書きやすくなると思いますが、現状は args の追記として定義になります。

/etc/pve/qemu-server/YOUR_VMID.conf に args を書き足します。

args: -chardev socket,id=virtfs0,path=/run/$YOUR_VM_NAME.sock -device vhost-user-fs-pci,queue-size=1024,chardev=virtfs0,tag=$YOUR_VM_NAME_TAG -object memory-backend-file,id=mem,size=$YOUR_VM_MEMORY_SIZE,mem-path=/dev/shm,share=on -numa node,memdev=mem

下記は私の環境の例です。

# diff /etc/pve/qemu-server/100.conf.bak /etc/pve/qemu-server/100.conf
20a21
> args: -chardev socket,id=virtfs0,path=/run/nextcloud.sock -device vhost-user-fs-pci,queue-size=1024,chardev=virtfs0,tag=nextcloud_tag -object memory-backend-file,id=mem,size=4096M,mem-path=/dev/shm,share=on -numa node,memdev=mem

// qm config コマンドで何が渡されるか確認できる
# qm config 100
args: -chardev socket,id=virtfs0,path=/run/nextcloud.sock -device vhost-user-fs-pci,queue-size=1024,chardev=virtfs0,tag=nextcloud_tag -object memory-backend-file,id=mem,size=4096M,mem-path=/dev/shm,share=on -numa node,memdev=mem
~

4.3 virtiofsd を起動

今回は nohup でプロセスを起動します。

フックスクリプトを書いてもいいのですが、どこかのタイミングで PVE で対応されるのでとりあえず動けばいいで構築進めます。

nohup /usr/libexec/virtiofsd --syslog --socket-path /run/YOUR_VM_NAME.sock --shared-dir /YOUR/ZFS/PATH --announce-submounts --inode-file-handles=mandatory &

systemd の service で管理するなら下記のような感じだろうか。

[Unit]
Description=virtiofs YOUR_VM_NAME_TAG Service

[Service]
Type=simple
ExecStart=/usr/libexec/virtiofsd --syslog --socket-path /run/YOUR_VM_NAME.sock --shared-dir /YOUR/ZFS/PATH --announce-submounts --inode-file-handles=mandatory
ExecStop=/usr/bin/kill $MAINPID
Restart=always

[Install]
WantedBy=multi-user.target

4.4 VM で virtiofs を mount

virtiofs は virtiofs のタグVM 内のマウント先の dir で mount できます。

※ もし上記までの手順で VM プロセスを再起動していない場合は再起動しておいてください。

下記はマウントコマンドの例です。

// マウント先作成
mkdir /mnt/nextcloud

// マウント
mount -t virtiofs nextcloud_tag /mnt/nextcloud

// df で確認するとしっかりと生えている
$ df
Filesystem       1K-blocks    Used   Available Use% Mounted on
tmpfs               400592     980      399612   1% /run
/dev/sda1         22371960 2606628    19748948  12% /
tmpfs              2002944       0     2002944   0% /dev/shm
tmpfs                 5120       0        5120   0% /run/lock
/dev/sda15          106858    6182      100677   6% /boot/efi
tmpfs               400588       4      400584   1% /run/user/1000
nextcloud_tag  13522435584     128 13522435456   1% /mnt/nextcloud

4.5 fstab に書いて永続化

$ diff /etc/fstab.bak /etc/fstab
2a3
> nextcloud_tag  /mnt/nextcloud  virtiofs    defaults

5. 所感

かなりあっさり virtiofs としてマウントできてしまったのが印象的でした。

今後 PVE 8.X で UI からのポチポチでもこの恩恵を受けられるということなので大変楽しみです。

6. 参考