要約
ストレージプールを作りたいドライブ(ただしLXDはsnapで動いているので/mediaまたは/mnt以下にマウントされている必要がある)に空ファイルを作成します。次に、その空ファイルをターゲットとして/var/lib/incus/disks/foo.imgというようなシンボリックリンクを作成します。そして、incus storage create foo btrfs(ループデバイスが使えるものならbtrfsでなくてもいけるはず)を実行します。これで元の空ファイルがストレージプールの本体として使われるようになります。
ただし、おそらく非公式なやり方なので不具合が起きる可能性も否定できません。
背景
Incus(LXD)のストレージはbtrfs, zfs, dir(ディレクトリ)などのいくつかのフォーマットがあります。dirなどはテスト用という感じで、本格的に使うならbtrfsやzfsなどのファイルシステムを使うことになります。この中でも一番ちゃんとしたやり方は、Incus専用にパーティションを切ってフォーマットすることなのですが、容量の配分などを考えるのがちょっと面倒です。
そこでIncusには、ループデバイスを使ってbtrfsやzfsを使用する方法も用意されています。incus storage create foo btrfsなどと実行すると、/var/lib/incus/disks/foo.imgというファイルが作成され、これが/dev/loopXとして使われるようになり、それが/var/lib/incus/storage-pools/fooにマウントされてbtrfsパーティションとして使えるようになる、というところまで勝手にやってくれます。
ただし、この/var/lib/incus/disks/という部分は基本的に固定されていて、incus storage createでの作成時に指定することはできず、Changing storage source path - Incus - Linux Containers Forumに書いてあるように管理者設定をいじらないとデフォルト値も変えられません。
また、ループバックデバイスのマウントの部分を自分で設定して指定することもできると思いますが、その場合incus側での扱いとしてはループデバイスではなく単なるzfs/btrfsのパーティションとなるので、マウント状態の永続化(再起動後の維持)やサイズの変更などをマネージドな感じで行うことはできなくなるはずです。
うまくいかない方法
こういうときにソフトウェアを「騙す」方法としてシンボリックリンクを使う自体は自然な発想で、結論としてはそれでうまくいったというのがこの記事なのですが、タイミングを間違えるとうまくいきません。
つまり、incus storage create foo btrfsをして/var/lib/incus/disks/foo.imgが作られてしまった後でこのファイルを移動してシンボリックリンクを張るとかすると、ループバックデバイスまわりの設定がおかしくなって(losetup -aで見ると"(deleted)"というような表示)、結局元の(/var/lib/incus/disksがある)パーティションが消費されるような状況になります。
この状況になってしまっても、incus moveなどで別ストレージプールに移動させれば大丈夫です。
再起動などしてしまったらどうなるかは知りません。
LXDにおける注意点
LXDはsnapで動いているので、snap(より正確にはおそらくremovable-media interface)の制限により、/homeや/mntや/mediaといった限られたパスにしかアクセスできません。
従ってストレージプールのデータを保持するimgファイルはこのどれかのディレクトリに配置する必要があります。
これはシンボリックリンクによって回避することはできません(imgファイルの実体が上記のディレクトリのどれかにある必要がある)。bind mountを利用することは可能です。
この記事の手法の安定性
シンボリックリンクを使うことの安定性についてですが、How to move a storage to other places? - LXD - Linux Containers Forumには、
Symlinks won’t work.
(中略)
Again, stay away from symlinks, those will not work or may break at any time.
などと書いてあります。これを真に受けるなら、本番環境でないとしてもシンボリックリンクを使うのは避けたほうがよさそうにも見えます。
ただ、上記のコメントには/var/lib/lxd/disksにbind mountを設定することも可能と書いてあるので、/と同じパーティションじゃなければダメということでは必ずしもないようです。
How can I create a loop-backed storage pool in a custom directory? - LXD - Linux Containers Forumでは、snapのmount関連機能との相性が悪いというようなことも書かれていますが、上記のアクセス先パスの制限の話でしょうか?LXDではなくIncusで使う分には大丈夫という説もありそうです。
試した限りはLXDでも見た感じ問題なく動作しています。
各ストレージの違い・パフォーマンス
各ストレージタイプには色々なトレードオフがあります。
まず、(この記事では紹介していない)最も単純な方式であるdir(ディレクトリ)についてですが、LXD Dir vs ZFS or BTRFS Instance Performance? - LXD - Linux Containers Forumによると基本のパフォーマンス自体は高速(多分、ホストのファイルシステムを直接使うのと同等)なかわりにスナップショットが(当然ながら)不得意とのことです。
zfsとbtrfs(とLVM)の比較についてはComparing Storage Drivers - Incus - Linux Containers Forumに詳しいベンチマークがあがっていますが、この中だとbtrfsが最速で、またループデバイスのオーバーヘッドもあまりなさそうです(Overhead of using loop-mounted images under Linux - Unix & Linux Stack ExchangeによるとループデバイスはLinux 4.4から速くなったらしいです)。
Btrfsを13年使ったのでその経験の話 - ChienomiなどにもLinux上ではbtrfsのほうがzfsよりいいと書いてあります。
Incus公式ドキュメントを含めてzfsが良いという情報もところどころで見かけましたが、上記のことから、個人的にはbtrfsのほうが良いものと判断しました。