タイトル通りです。私が実際にやった作業をメモ代わりに記載しておきます。
Ubuntuのインストール
インストール方法などは本記事スコープ外。Ubuntuの公式サイトからisoイメージをDLし、Rufusを使ってUSBメモリに焼き込んでブータブル化、それを用いてPCにUbuntuをインストールしました。
UbuntuのバージョンはUbuntu 22.04.2 LTS (GNU/Linux 5.15.0-69-generic x86_64)です。
追記:Ubuntu 24.02 LTSでも動作確認しました。
パッケージ最新化
とりあえず最新化を行うおまじないのような作業です。
sudo apt -y update
sudo apt -y upgrade
番外編 矢印キーで履歴サーチ設定
番外編作業ですが、ターミナル操作で、矢印キーを使って履歴のサーチができるようにしたいので、.bashrcにbindコマンドを追記します。
bind '"\e[A": history-search-backward'
bind '"\e[B": history-search-forward'
ZFSのインストール
ZFSはデフォルトで入っていないため、インストールします。
sudo apt install zfsutils-linux
ZFSプール用のディスクIDの確認
プールを作成するためのメンバーディスクを確認します。下記コマンドで確認できます。WWMというのが、HDDの固有情報らしいのでそれをメモ。
ls -lA /dev/disk/by-id/
私の場合、メンバディスクはHDD6本で、RAIDZ2を構成します。
一応固有番号なので一部マスクしてます。
wwn-0x50014XXXbef8d74f
wwn-0x50014XXXbeff8538
wwn-0x50014XXX69a999a6
wwn-0x50014XXXbeff7e90
wwn-0x50014XXXbeff84d2
wwn-0x50014XXX69a98c86
これらをメンバディスクに、RAIDZ2プールを作成します。プール名はtankとします。
sudo zpool create -f tank raidz2 /dev/disk/by-id/wwn-0x50014XXXbef8d74f /dev/disk/by-id/wwn-0x50014XXXbeff8538 /dev/disk/by-id/wwn-0x50014XXX69a999a6 /dev/disk/by-id/wwn-0x50014XXXbeff7e90 /dev/disk/by-id/wwn-0x50014XXXbeff84d2 /dev/disk/by-id/wwn-0x50014XXX69a98c86
作成されたプールは、/tankにマウントされます。ちなみにマウント場所は、オプションで変えられるらしいです。
補足:そもそもWWMとは何なのか
あとは、細かい設定をします。アクセス時のタイムスタンプの機能であるatimeを切ったり、圧縮方式をzstdにしたりします。このへんの情報はこのサイトを参考にしました。
sudo zfs set atime=off tank
sudo zfs set compression=zstd tank
次に、データセットを作成します。プールのサブフォルダ的なものです。スナップショットなどはデータセット単位で取れます。メインで使うstorageと、Nextcloud用のデータセットcloudを作ることにしました。
sudo zfs create tank/storage
sudo zfs create tank/cloud
自動スナップショットの設定
ZFSの強みの一つはスナップショット機能です。これを定期的にとるためのツールが存在しています。
sudo apt install zfs-auto-snapshot
auto-snapshot機能はcronを使用して実行されます。そのため、設定ファイルは以下の場所にあります。
ラベル | ファイル名 |
---|---|
frequent | /etc/cron.d/zfs-auto-snapshot |
hourly | /etc/cron.hourly/zfs-auto-snapshot |
daily | /etc/cron.daily/zfs-auto-snapshot |
weekly | /etc/cron.weekly/zfs-auto-snapshot |
monthly | /etc/cron.monthly/zfs-auto-snapshot |
cronの設定ファイルには、以下の頻度でスナップショットをとるように記載されています。
ラベル | 取得タイミング | 保持個数 | 説明 |
---|---|---|---|
frequent | 15分 | 4 | 15分ごとに1時間確保 |
hourly | 1時間(60分) | 24 | 1時間ごとに1日分確保 |
daily | 1日(24時間) | 31 | 1日毎に1ヶ月(31日)分確保 |
weekly | 1週(7日) | 8 | 1週(7日)毎に8週(2ヶ月弱)分確保 |
monthly | 1ヶ月 | 12 | 1ヶ月ごとに1年分確保 |
このデフォルト設定でも問題ありませんが、個人的には、monthlyで一年分スナップショットを保持する形になってるので、ここはもう少し短くてもいいのかなと思っています(保存するものにもよりますが…)その場合は直接設定ファイルを編集してください。(要root)
参考サイト
古いスナップショット削除コマンド
スナップショットを無限に保持しておくわけにもいかないので、古いものは消していかないといけません。雑にシェルスクリプトを書いたのでメモします。これをcron実行すればいいと思います。
zfs list -t snapshot -o name -S creationは、スナップショット一覧を新しいもの順に表示するコマンド、
tail -n +100は、上から100行目以外を表示するコマンド、
xargs -n 1 zfs destroy -vは、一つ一つを引数に、zfs destroyを実行するコマンドです。
つまり最新100件以外のスナップショットを削除するコマンドになっています。
この辺りをうまく改良して使うといいかと思います。ちなみにroot権限で動かす必要があります。あと最後の-vはverboseなのでcronjobにするには必要ないかも。
zfs list -t snapshot -o name -S creation | tail -n +100 | xargs -n 1 zfs destroy -v
参考サイト

定期Scrub
ZFSには、「Scrub(スクラブ)」という仕組みが備わっています。これは、ZFSプールに保存されている全データのチェックサムを確認し、データが正しいかどうか=壊れていないかを確認する機能です。基本的にZFSにおいてデータ不一致が発生するということは、ハードウェアの異常であるということを意味します(ZFSにバグがあるという可能性もあるが、一般的な使い方をしているうえではかなり低い確率)。よって、Scrubを定期実行しておくことで、ハードウェアすなわちHDDやSSD等の故障にいち早く気付けるというメリットがあります。ただし、Scrubは、全データをチェックするという性質上時間がかかり、やりすぎると逆にハードウェアの寿命を縮めることにもつながりかねないので、数週間~1か月に1回くらいのペースがいいと思います。
スクラブについては下記を参照
定期的なScrubを実施する方法としては、systemdの機能を用いるのが簡単です。OpenZFSに最初から、systemdの設定ファイルが含まれており、上記の手順でZFSを導入していれば、すでに準備はできています。
一番バランスがいいと思われる、毎月実行の設定をします。プール名が「tank」の場合、
sudo systemctl enable zfs-scrub-monthly@tank.timer
を実行します。zfs-scrub-monthly@.timer.inとzfs-scrub-weekly@.timer.in、zfs-scrub@.service.inという設定ファイルがすでにあるので、上記のコマンドで設定ができます。ソースコードは下記参照。
Samba共有の準備
次に、Samba共有用の準備をします。今回作ったのは、ほぼ自分用のプライベートなローカルNASとしての目的なので、セキュリティはあまり考慮しない作り方になっております。セキュリティを気にする方はその店ご注意ください。
sudo apt install -y samba
Sambaによる共有用のユーザとして、「storage」というユーザを作ることにします。まず、Linux側にユーザを作成します。パスワードは設定必要ですが、Full Name, Room Number, Work Phone, Home Phone, Otherという項目は全部空白でエンターしてしまいます。
sudo adduser storage
次に、pdbeditコマンドでSamba用のユーザを追加します。
sudo pdbedit -a storage
ユーザ名やパスワードは同じにしましょう。
次に、/tank/storageの所有権とパーミッションを変更します。先述の通り、自分しか使わないのでザル設定です。
cd /tank/
sudo chmod -R 777 storage/
sudo chown -R storage:storage storage/
次に、/etc/samba/smb.confの修正です。
[global]
dos charset = CP932
unix charset = UTF-8
dns proxy = No
aio max threads = 2
max log size = 5120
load printers = No
printing = bsd
disable spoolss = Yes
kernel change notify = No
unix extensions = No
directory name cache size = 0
unix charset = UTF-8
obey pam restrictions = False
logging = file
server min protocol = SMB2_02
map to guest = Bad User
bind interfaces only = Yes
netbios name = neon
netbios aliases =
server role = standalone
workgroup = WORKGROUP
registry shares = yes
include = registry
dos filemode = no
store dos attributes = no
map archive = no
map hidden = no
map readonly = no
map system = no
log file = /var/log/samba/log.%m
max log size = 1000
logging = file
panic action = /usr/share/samba/panic-action %d
server role = standalone server
obey pam restrictions = yes
unix password sync = yes
passwd program = /usr/bin/passwd %u
passwd chat = *Enter\snew\s*\spassword:* %n\n *Retype\snew\s*\spassword:* %n\n *password\supdated\ssuccessfully* .
pam password change = yes
map to guest = bad user
usershare allow guests = yes
[storage]
path = /tank/storage
read only = no
browsable = yes
writable = yes
#guest ok = yes
#guest only = yes
create mode = 0777
directory mode = 0777
自分でもなんでこのコンフィグになったのか、正直覚えてません!とりあえずこれで動いてます
最後にsmbdを再起動します。
sudo systemctl restart smbd.service
別マシンで作成したzpoolのインポート
ZFSのいいところは、別マシンで作成したzpoolでも簡単にインポートできてしまえるところです。
sudo zpool import tank -f
基本的にこれで完了です。-fオプションをつけるのは、移行前のマシンでzpool exportをしていない場合でも強制的にインポートするためです。
sudo zpool status
で確認できます。こんな感じになりました。
$ sudo zpool status
pool: tank
state: ONLINE
status: Some supported and requested features are not enabled on the pool.
The pool can still be used, but some features are unavailable.
action: Enable all features using 'zpool upgrade'. Once this is done,
the pool may no longer be accessible by software that does not support
the features. See zpool-features(7) for details.
scan: scrub repaired 0B in 2 days 03:48:47 with 0 errors on Mon Mar 24 18:48:55 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
6058c47c-21f6-11e9-84aa-e03f496ebea1 ONLINE 0 0 0
fd51c3ee-1899-11e7-a309-e03f496ebea1 ONLINE 0 0 0
a5379724-9eb4-11eb-8709-e03f496ebea1 ONLINE 0 0 0
dff677ad-b032-11ed-9d8e-e03f496ebea1 ONLINE 0 0 0
16e8330e-f8ee-11eb-a44a-244bfe3d7a5a ONLINE 0 0 0
ffe73a48-1899-11e7-a309-e03f496ebea1 ONLINE 0 0 0
errors: No known data errors
ZFS プール上のディスクパスを UUID (中身は /dev/disk/by-partuuid/
のようなもの) ではなく wwn (たとえば /dev/disk/by-id/wwn-xxxxx
のような) で管理したいので、下記の手順で再インポートしてみます。
プールをエクスポート
sudo zpool export tank
WWN ベースでプールをインポート
sudo zpool import -d /dev/disk/by-id/ tank
動作確認
sudo zpool status
ZFSタイプについて
Ubuntu などの Linux 環境で新規に zpool を作成すると、各ディスクに「Solaris /usr & Apple ZFS (part1)」や「Solaris reserved 1 (part9)」といった GPT パーティションが作成されます。一方、TrueNAS(FreeBSD ベース)で ZFS を作成すると、「FreeBSD swap (part1) + FreeBSD ZFS (part2)」という形が一般的です。
fdisk や parted などのツールでディスクを確認すると、下記のように分かれています。
- Ubuntu 作成時:
- part1 →
Solaris /usr & Apple ZFS
- part9 →
Solaris reserved 1
(余白や予約領域)
- part1 →
- TrueNAS 作成時:
- part1 →
FreeBSD swap
- part2 →
FreeBSD ZFS
- part1 →
=== /dev/disk/by-id/wwn-0x50014XXXXXX46ce4 ===
Disk /dev/disk/by-id/wwn-0x50014XXXXXX46ce4: 5.46 TiB, 6001175126016 bytes, 11721045168 sectors
Disk model: WDC WD60EFZX-68B
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: 16C91E45-F8EE-11EB-A44A-244BFE3D7A5A
Device Start End Sectors Size Type
/dev/disk/by-id/wwn-0x50014XXXXXX46ce4-part1 128 4194431 4194304 2G FreeBSD swap
/dev/disk/by-id/wwn-0x50014XXXXXX46ce4-part2 4194432 11721045127 11716850696 5.5T FreeBSD ZFS
=== /dev/disk/by-id/wwn-0x50014XXXXXX98c86 ===
Disk /dev/disk/by-id/wwn-0x50014XXXXXX98c86: 5.46 TiB, 6001175126016 bytes, 11721045168 sectors
Disk model: WDC WD60EFZX-68B
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: DC3FE6FE-0575-704E-A846-CDB5A7A57E8F
Device Start End Sectors Size Type
/dev/disk/by-id/wwn-0x50014XXXXXX98c86-part1 2048 11721027583 11721025536 5.5T Solaris /usr & Apple ZFS
/dev/disk/by-id/wwn-0x50014XXXXXX98c86-part9 11721027584 11721043967 16384 8M Solaris reserved 1
これはあくまで「どんなパーティションコードを使うか」の違いであって、ZFS そのものの機能・性能に大きな差はありません。ZFS はディスク末尾や先頭など複数か所にメタデータ(ラベル)を持ち、GPT パーティションの種類が異なっていても同じように動作します。
たとえば TrueNAS が「ZFS + Swap」のレイアウトを作るのは、障害対応時のダンプ領域やスワップスペースを FreeBSD 側で確保するためです。一方で Ubuntu (OpenZFS on Linux) は、スワップを別途確保しない代わりに小さな予約領域(part9)を GPT に配置して、ZFS 用の領域 (part1) を広く確保する設計になっています。
混在運用しても問題ありませんが、ディスク故障などで新規ディスクを zpool replace
すると、Ubuntu 環境では自動的に「Solaris /usr & Apple ZFS」のパーティションコードが作成され、徐々に Solaris 形式のディスクが増えていくことがあります。
もちろん、パーティションを削除してディスク全体を「WWN 形式」で扱うこと(whole disk)も可能ですが、その際はディスクごとに zpool offline
→ fdisk/parted
→ zpool replace
(リシルバ待ち)といった手間が必要になります。
要するに、ZFS の「タイプ」は同じ ZFS でも OS やツールごとにパーティションのラベルや構成が変わりますが、性能や信頼性に違いはほぼありません。気になる方はディスク交換やメンテナンス時に揃えても良いですが、運用上はそのままでもまったく問題ないということを覚えておくと便利です。
番外編 Dockerインストール
全然関係ないですが、合わせてDockerのインストールもしたのでメモです。
sudo apt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
cat /etc/apt/sources.list.d/docker.list
sudo apt-get update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
ちなみに、合わせてDocker composeと、Docker buildxをインストールしてます。
Dockerクライアントがデーモンを操作するためには、sudoコマンドを使って管理者権限を取得するか、dockerグループに所属する必要があります。dockerグループに所属しておけば、sudoなしにコンテナの生成や操作ができますので何かと便利です。このdockerグループはdocker-engineインストール時に自動的に作成されていますので、あとはユーザーをグループに追加してログインしなおすだけです。
今操作しているユーザをdockerグループに加えることで、dockerコマンドをsudoなしで実行できるように権限付与しておきます。
sudo usermod -aG docker $USER
次回ログインから有効になるので、適宜再ログインしましょう。
コメント