UbuntuにZFSを導入しSambaファイルサーバにする

スポンサーリンク

タイトル通りです。私が実際にやった作業をメモ代わりに記載しておきます。

スポンサーリンク

Ubuntu 22.04.2 LTSのインストール

インストール方法などは本記事スコープ外。Ubuntuの公式サイトからisoイメージをDLし、Rufusを使ってUSBメモリに焼き込んでブータブル化、それを用いてPCにUbuntuをインストールしました。
UbuntuのバージョンはUbuntu 22.04.2 LTS (GNU/Linux 5.15.0-69-generic x86_64)。

パッケージ最新化

とりあえず最新化を行うおまじないのような作業です。

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にマウントされます。ちなみにマウント場所は、オプションで変えられるらしいです。

あとは、細かい設定をします。アクセス時のタイムスタンプの機能であるatimeを切ったり、圧縮方式をzstdにしたりします。このへんの情報はこのサイトを参考にしました。

ZFS RAID-ZをUbuntuで試してみる (暗号化、圧縮)
Ubuntu Server で RAID-Z を試してみたので、その...
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の設定ファイルには、以下の頻度でスナップショットをとるように記載されています。

ラベル取得タイミング保持個数説明
frequent15分415分ごとに1時間確保
hourly1時間(60分)241時間ごとに1日分確保
daily1日(24時間)311日毎に1ヶ月(31日)分確保
weekly1週(7日)81週(7日)毎に8週(2ヶ月弱)分確保
monthly1ヶ月121ヶ月ごとに1年分確保

このデフォルト設定でも問題ありませんが、個人的には、monthlyで一年分スナップショットを保持する形になってるので、ここはもう少し短くてもいいのかなと思っています(保存するものにもよりますが…)その場合は直接設定ファイルを編集してください。(要root)

参考サイト

# UbuntuでZFSを使ってみよう ## 第10回 Ubuntu 20.04 LTSの auto-snapshot 機能 前回は、zsysdとそれを使用するzsysctl の機能について説明しました。今回は自動的にスナップショットを取得してくれる、auto-snapshot 機能について説明します。 | 株式会社デジタル・ヒュージ・テクノロジー
ZFSのスナップショット(snapshot)とはスナップショットは ZFSの有用な機能の1つで、スナップショット取得時点のディスクイメージを保持する機能です。

古いスナップショット削除コマンド

スナップショットを無限に保持しておくわけにもいかないので、古いものは消していかないといけません。雑にシェルスクリプトを書いたのでメモします。これをcron実行すればいいと思います。

zfs list -t snapshot -o name -S creationは、スナップショット一覧を新しいもの順に表示するコマンド、
tail -n +30は、上から100行目以外を表示するコマンド、
xargs -n 1 zfs destroy -vは、一つ一つを引数に、zfs destroyを実行するコマンドです。
つまり最新30件以外のスナップショットを削除するコマンドになっています。

この辺りをうまく改良して使うといいかと思います。ちなみにroot権限で動かす必要があります。あと最後の-vはverboseなのでcronjobにするには必要ないかも。

zfs list -t snapshot -o name -S creation | tail -n +100 | xargs -n 1 zfs destroy -v

参考サイト

Ubuntuのzfs supportを使って、アップグレード後などのrollbackを実現する - Qiita
Ubuntu 20.04 -> 20.10 にアップグレード後、カーネルパニックが起こるようになり、zfsの機能で20.04に戻すことができたという記事です。また、/home/であるpool/US…

定期Scrub

ZFSには、「Scrub(スクラブ)」という仕組みが備わっています。これは、ZFSプールに保存されている全データのチェックサムを確認し、データが正しいかどうか=壊れていないかを確認する機能です。基本的にZFSにおいてデータ不一致が発生するということは、ハードウェアの異常であるということを意味します(ZFSにバグがあるという可能性もあるが、一般的な使い方をしているうえではかなり低い確率)。よって、Scrubを定期実行しておくことで、ハードウェアすなわちHDDやSSD等の故障にいち早く気付けるというメリットがあります。ただし、Scrubは、全データをチェックするという性質上時間がかかり、やりすぎると逆にハードウェアの寿命を縮めることにもつながりかねないので、数週間~1か月に1回くらいのペースがいいと思います。

スクラブについては下記を参照

ZFS ファイルシステムの整合性をチェックする - Oracle Solaris ZFS 管理ガイド
このドキュメントは、Oracle ZFS ファイルシステムの設定と管理を担当するユーザーを対象としています。必要に応じて、SPARC システムと x86 システムに分けて説明しています。

定期的な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という設定ファイルがすでにあるので、上記のコマンドで設定ができます。ソースコードは下記参照。

zfs/etc/systemd/system/zfs-scrub-monthly@.timer.in at master · openzfs/zfs
OpenZFS on Linux and FreeBSD. Contribute to openzfs/zfs development by creating an account on GitHub.

Samba共有の準備

次に、Samba共有用の準備をします。今回作ったのは、ほぼ自分用のプライベートなローカルNASとしての目的なので、セキュリティはあまり考慮しない作り方になっております。セキュリティを気にする方はその店ご注意ください。

sudo apt install -y samba

Sambaによる共有用のユーザとして、「storage」というユーザを作ることにします。まず、Linux側にユーザを作成します。

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

番外編 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

次回ログインから有効になるので、適宜再ログインしましょう。

コメント

タイトルとURLをコピーしました