ZFS on LinuxでXubuntu18.04をセットアップしてみた -1 インストール編-

#1 はじめに
SolarisやFreeBSDユーザーの間で大人気のファイルシステム，ZFSを使ってXubuntuをセットアップしてみます．とりあえずZFSを使ってみようということで，SSDのパーティションを3つ切ってRAIDZを構成します．(それだと意味がないだって？)
ファイルシステムって何？ZFSって何？な人でも大丈夫．きっと分かります．何事もチャレンジです．
では次に進みましょう．

##ファイルシステムって何？
*ここで説明するファイルシステムとはストレージのファイルフォーマットです．*

実物の本やCDがあるとします．みなさんはこれらを管理しやすくするために本棚を用意したり，ラベルをつけたり，工夫しますよね？
PDFやMP3などのファイルもコンピュータが管理しやすいように様々な方法で工夫をしています．
したがってファイルシステムとは，コンピュータがHDDやSSD内のファイルを管理する方式のことを広義に指します．
ファイルシステムにもさまざまな種類があり，代表的なものに「NTFS」「FAT(FAT16/32/ex)」「ext(ext/2/3/4)」「XFS」などが挙げられます．**ZFSはその中の1つです．**
NTFSは主にWindows系で使われ，FATはUSBメモリやSDカード,PS4など，ext4は主に最近のLinux系で採用されています．XFSはLinuxはもちろんですがNASにも多いような...(ここら辺は好みもあるので割愛します)

今回はそのファイルシステムにZFSを使ってみようということです．

##そもそもZFSって何？
[Wikipedia]("Wikipedia",https://ja.wikipedia.org/wiki/ZFS)を見ると，以下のような特徴を持っているファイルシステムです．


>チェックサムが64ビット化された
コピーオンライトの実装
ボリュームマネージャが必要なく、ボリュームの構成が容易にできるようになった
ディスクの違い（容量、種類）を吸収する仮想ボリューム（ストレージプールと呼称）をサポート
ストレージプールの作成・フォーマット・マウントがコマンド一行ですむ
ファイルシステム自身がRAID機能を持つ
RAID-Z2（ダブルパリティによるRAID-6相当の機能）
ホットスペア
クローンプロモーション（アクティブなZFS領域を複製と置換を容易にする機能）
再帰的スナップショットコマンドの簡素化オプション

何やら難しそうですね．もっと簡単にすると，
・扱えるストレージの容量が1000兆ZetaByte(ZB>EB>PB>PT>TB>GB>MB...)
・複数のストレージ(HDDやSSD)を1つの記憶領域としてまとめて利用できる．
・簡単に容量を拡張できる
・エンドツーエンドのチェックサムやコピーオンライト機能による高いストレージの信頼性
・簡単にRAIDを構成できる
・ストレージの状態をスナップショットとしてバックアップできる

など，可用性と信頼性に重きを置いた革新的なファイルシステムなのです!!((

##パーティションについて
**今回のセットアップに必要な知識です．これだけでは不十分かもしれません．ググって…**

パーティションとは，HDDやSSDなどのストレージにおいて，任意のサイズで区切られた領域のことを指します．
広い部屋を仕切りで区切って使うことと同じです．
パーティションは，OS用の領域，データ領域，回復用領域など用途に応じて複数構成することが出来，問題が発生した場合はそのパーティションだけをクリアすることでデータ消失の被害を最小限に抑えることが出来ます．

Windowsを使っている人ならHDD/SSDが1つしかないのに，Cドライブ，Dドライブが用意されているマシンがあります．これは1つのHDD/SSD内をWindowsOS用(Cドライブ)とデータ用(Dドライブ)でパーティションで区切っているというわけです．

パーティションの構成(パーティショニング)はOSが起動するために注意しなければなりません．

WindowsやXubuntuが起動するためには，最低限
1. EFI領域(起動に必要な情報を格納するパーティション)
2. OS領域(データ領域含む．OSの実行ファイルやユーザーデータを格納するパーティション．)
の2つが必要です．(UEFIの場合)

正しくパーティショニングさえすれば，複数のOSを1台のマシンに共存させることができます．
上記の1,2のパーティションをOSの数だけ作れば何とかなります．
今回はWindows10とXubuntuを共存させました．

さて，予備知識はこれくらいにして，試しながら理解していきましょう！

#2 用意したもの
セットアップ対象のPCと作業用のPCを1台ずつ用意します．Windowsマシン前提で説明します．
今回用意したセットアップ対象はiiyamaのBTOノートPCです．プリインのWindows10を生かしたままセットアップします．
さすがに時は2018年なので，以降はUEFIマシンで説明します．BIOSな場合は読み替えて進めてください．

**UEFIの設定からセキュアブートをオフにしてください!!**
[僕んちのTV別館](https://freesoft.tvbok.com/tips/efi_installation/about_secure_boot.html)さんのサイトを参考にしてください．

|名前|種類|
|:-:|:-:|
|CPU|Core i7(8th genだったかな)|
|RAM|8GB(LPDDR4)|
|SSD|480GB(Sandisk)|

次にインストールメディアとして，[xubuntu-18.04-desktop-amd64.iso](http://ubuntutym2.u-toyama.ac.jp/xubuntu/18.04/release/)を書き込んだUSBメモリまたはDVDを用意．
僕はUSBメモリに[Rufus](https://forest.watch.impress.co.jp/library/software/rufus/)を使って書き込みました．
この他に有線LANによるネットワーク環境を用意しました．(Xubuntu側で認識すればWiFiでも行けます．)
**ZFS関係のパッケージをダウンロードするためにネットワーク環境は必須です．**

#3 Xubuntu LiveCDの起動
まずは作ったインストールメディアをPCに差し込んでXubuntuを起動します．うまく起動できない場合は，UEFIのBootオプションから起動順序を変更するか，BootOverrideからUSBメモリ(またはディスクドライブ)の機器名を選択します．


・Windows8以降が起動する場合
Shift＋再起動クリック→トラブルシューティング→詳細オプション→UEFIファームウェアの設定
ホットキーが分からなくても上記操作で入れます．

*UEFI設定画面への入り方は取扱説明書等を確認してください．iiyamaのマシンはF2連打起動でUEFI設定画面に入れました．*
こんな感じの画面が出ると思います．一番上のTry Xubuntu~をEnterで選択してください．

![VirtualBox_Xubuntu_30_05_2018_21_17_43.png](https://qiita-image-store.s3.amazonaws.com/0/260298/7412fc62-5a95-f763-ee15-97d67e392fcf.png)


#4 パーティションの構成
パーティショニングはGPartedというツールが便利です．パーティションを好きなファイルシステムで作成することはもちろん．簡単に縮小したり，削除することが可能です．

左上の丸いネズミのロゴをクリックし，GPartedを起動します．(スクリーンショットを添付する予定です)

今回は480GB SSDのパーティションを以下表のとおり構成しました．ラベルは適宜入れてください．

EFIパーティションは100MBでfat32，boot用のパーティションは100MB以上ext4でフォーマットしてください．

XubuntuのGPartedではZFSでフォーマットできないため，領域だけ確保して後でフォーマットします．未フォーマットで構いません．
今回はディスク3本(32GBx3)を1つのRAIDZとして構成するため，Xubuntu用にNo4～6の通り3つ未フォーマット(NONE)でパーティションを作成します．**64GBを3つでも128GBを3つでも構いませんが，すべてサイズは一致させてください．後でZFSにフォーマットするので，未フォーマット(NONE)で問題ありません．**

余りまくってますが，これは気にしないキニシナイ…
No2は縮小という形で32GBに縮めました．

**No1,2,8は既に存在するパーティションです．マシンによって初期構成は異なります．使用中の場合はNo2のサイズ変更をします．
Windowsを消す場合は削除してかまいません．**

| No |ラベル | サイズ |ファイルシステム|用途|
|:-:|:-:|:-:|:-:|:-:|
| 1  | Windows10 EFI  |  100MB |FAT32|Windowsの起動に必要な領域|
| 2  | Windows10  　  | 32GB  |NTFS|Windows10のいわゆるCドライブ|
|* 3  | Xubuntu EFI   |  100MB   |FAT32|Xubuntuの起動に必要な領域|
|* 4  | Xubuntu1       | 32GB  |none|Xubuntuのデータ領域|
|* 5 |Xubuntu2  |32GB|none|Xubuntuのデータ領域|
|* 6 |Xubuntu3  |32GB|none|Xubuntuのデータ領域|
|* 7 |Xubuntu boot|500MB|ext4|Xubuntuの/boot領域|
| 8 |回復パーティション||NTFS|リカバリ領域|

**\*印のパーティションは必須です．**

なんだか複雑な構成，Windowsを残すためにこうするしかなかったんだ...
Xubuntuだけでいいなら全部消した後No3~7を作ってしまえばOK．順番とラベルは適当です．

#4 ZFSの構成
ZFSは「ストレージプール」と言う複数のストレージやパーティションをまとめた領域を作成し，そこにデータを置きます．作成したストレージプールには後からストレージを追加したり，別のストレージと交換することが出来ます．

まずはターミナル(Winキー＋T)を起動し，常に管理者(スーパーユーザー)権限で実行するようにします．

```terminal
sudo -i
```

必要なパッケージ(ソフトウェア)をインストールします．(ネットワーク環境が必要です) 

```terminal
apt update
apt install --yes debootstrap gdisk zfs-initramfs
```

ZFSコマンドでは*[ストレージのデバイス名-Part番号]*で**どのストレージのどのパーティションか**を指定します．
というわけで，ストレージのデバイス名を取得します．

```terminal
ls -l /dev/disk/by-id

```

手元のマシンは内臓SSDドライブ，インストールメディアのUSBメモリを認識していたため，以下のように出力されました．
Part番号は先ほどGpartedで作成したパーティション番号と一致するはずです．(まれに一致しない時もありますが総数は同じはずです．)


```terminal
ata-sandisk480G...>/dev/sda
ata-sandisk480G-part1...>/dev/sda1
ata-sandisk480G-part2...>/dev/sda2
⋮
ata-sandisk480G-part8...>/dev/sda8
usb-disk8G...>/dev/sdb
```
この時，デバイス名の*ata-sandisk480G...>/dev/sda*はSSD自体を，*ata-sandisk480G-part1...>/dev/sda1*はSSDの1番目のパーティションを指します．

ZFSの構成にはこれ(ata-sandisk480-partN)を指定します．ターミナルのTabキーで補完しながら入力しましょう．

ストレージプールをrpoolという名前で作成してみます．書式は以下の通りです．atimeとかcompressionたちはおまじないだと思ってください．コピペミスやスペース入れ間違えがあるとうまくいきません．やり直してください．

```terminal
zpool create -o ashift=12 \
      -O atime=off -O canmount=off -O compression=lz4 -O normalization=formD \
      -O xattr=sa -O mountpoint=/ -R /mnt \
      rpool raidz /dev/disk/by-id/[デバイス名]-part[パーティション番号] \
                  /dev/disk/by-id/[デバイス名]-part[パーティション番号] \
                  /dev/disk/by-id/[デバイス名]-part[パーティション番号] \
```
今回はパーティションNo4~6を使うので，以下のように入力します．

```terminal
zpool create -o ashift=12 \
      -O atime=off -O canmount=off -O compression=lz4 -O normalization=formD \
      -O xattr=sa -O mountpoint=/ -R /mnt \
      rpool raidz /dev/disk/by-id/ata-sandisk480G-part4 \
                  /dev/disk/by-id/ata-sandisk480G-part5 \
                  /dev/disk/by-id/ata-sandisk480G-part6 \
```

**-Oはアルファベットのオーです．” \”の前に半角スペースを入れてください．**

ストレージプールの状態を確認してみます．

```terminal
zpool status rpool
```

以下のように3つデバイス名が表示されていれば，正しく構成されています．

```terminal


```



これで3つのパーティションをRAIDZで構成できました．

#5 ディレクトリの構成
XubuntuをはじめとするLinuxでは，**root,home,var,boot**などのディレクトリにOSを使うために必要なデータやユーザデータを格納します．この章ではこれらのディレクトリを作成します．

まずはROOTディレクトリから．

```terminal
zfs create -o canmount=noauto -o mountpoint=/ rpool/ROOT/xubuntu
zfs mount rpool/ROOT/xubuntu
```
**mountpoint=/ スペース rpool/...です**

次はホームディレクトリやキャッシュなど，必要なディレクトリを作成します．

```terminal
zfs create -o setuid=off                              rpool/home
zfs create -o mountpoint=/root                        rpool/home/root
zfs create -o canmount=off -o setuid=off  -o exec=off rpool/var
zfs create -o com.sun:auto-snapshot=false             rpool/var/cache
zfs create -o acltype=posixacl -o xattr=sa            rpool/var/log
zfs create                                            rpool/var/spool
zfs create -o com.sun:auto-snapshot=false -o exec=on  rpool/var/tmp
```

#6 Xubuntuのインストール
Xubuntuのコア機能をダウンロードします．

```terminal
chmod 1777 /mnt/var/tmp
debootstrap bionic /mnt
zfs set devices=off rpool
```
Xubuntu18.04の開発コードであるbionic beaver(訳すと超人的なビーバ？ですかね)の略称をとってdebootstrap bionicと入力します．

##Xubuntuの設定-その１-
まずはホスト名を設定します．(ターミナル上に出てくるxubuntu@xubuntuの後ろの部分です)

```terminal
echo [設定したい英数字] > /mnt/etc/hostname
```
ここではホスト名をHOSTPC1とします．

```terminal
echo HOSTPC1 > /mnt/etc/hostname
```
テキストエディタのnanoで/mnt/etc/hostsを編集します．

```console
nano /mnt/etc/hosts
以下を追記する↓
127.0.1.1       HOSTNAME
```
入力したら，ctrl+Oを押してEnterキーで保存します．

次にパッケージを取得するアドレスを設定します．

```console
nano /mnt/etc/apt/sources.list
以下を入力↓
deb http://archive.ubuntu.com/ubuntu bionic main universe
deb-src http://archive.ubuntu.com/ubuntu bionic main universe

deb http://security.ubuntu.com/ubuntu bionic-security main universe
deb-src http://security.ubuntu.com/ubuntu bionic-security main universe

deb http://archive.ubuntu.com/ubuntu bionic-updates main universe
deb-src http://archive.ubuntu.com/ubuntu bionic-updates main universe
```
Ubuntuではなく，Xubuntuでは？と思うかもしれませんがこれでOK．

##ここまでの設定を反映
ここまでの作業はLiveCD(お試しXubuntu)上に設定しただけの状態なため，実環境に反映させます．

```console
mount --rbind /dev  /mnt/dev
mount --rbind /proc /mnt/proc
mount --rbind /sys  /mnt/sys
chroot /mnt /bin/bash --login
sudo -i
```
再帰的にサブディレクトリもマウントするので，bindではなくrbindをオプションとして使います．
chrootでLiveCD上から実環境に移動します．

**ここからミスると厄介なので一旦休憩するなりしましょう．**

##Xubuntuの設定-その2-
ロケールを設定します．日本語環境は後で入れるので，今は英語圏とします．

```console
locale-gen en_US.UTF-8
echo LANG=en_US.UTF-8 > /etc/default/locale

dpkg-reconfigure tzdata
```
次にマウントの設定にシンボリックリンクを張ります．おまじないだと思ってください．

```console
ln -s /proc/self/mounts /etc/mtab
```

実環境には何も入っていないので，パッケージリストの取得をしてから，テキストエディタのnanoをインストールします．

```console
apt update
apt install --yes nano
```

システムのコア機能とブートイメージ，ZFSツールをインストールします．(時間がかかります)

```console
apt install --yes --no-install-recommends linux-image-generic
apt install --yes zfs-initramfs
```

#7 インストールの仕上げ
##EFIの設定
boot領域のパーティションを/bootにマウントします．(grubの不具合回避のためにbootをext4のパーティションに分けています．)
**part番号はboot用にフォーマットしたパーティションを指定します．**
僕の場合は例の表のパーティションNo8なので*ata-sandisk480G-part8*です．
fstabの設定も同じ書き方で行けると思いますが，うまくいかなかったので*/dev/sda8*と相対パスで設定しました．(要検証)

```console
mount ata-sandisk480G-part8 /boot
echo "/dev/sda8 /boot rw ext4 0 0" >> /etc/fstab
```

EFIパーティションを構成します．最初に作ったEFIパーティションを指定します．
例の表でいうパーティション番号3のXubuntu EFIパーティションです．

デバイス名的には*ata-sandisk480G-part3*です．
書式は以下の通り．

```console
apt install dosfstools
mkdosfs -F 32 -n EFI /dev/disk/by-id/[デバイス名]-part[パーティション番号]
mkdir /boot/efi
echo PARTUUID=$(blkid -s PARTUUID -o value \
      /dev/disk/by-id/[デバイス名]-part[パーティション番号]) \
      /boot/efi vfat nofail,x-systemd.device-timeout=1 0 1 >> /etc/fstab \
      
mount /boot/efi
apt install --yes grub-efi-amd64
```

僕の場合は以下の通りです．

```console
apt install dosfstools
mkdosfs -F 32 -n EFI /dev/disk/by-id/ata-sandisk480G-part3
mkdir /boot/efi
echo PARTUUID=$(blkid -s PARTUUID -o value \
      /dev/disk/by-id/by-id/ata-sandisk480G-part3) \
      /boot/efi vfat nofail,x-systemd.device-timeout=1 0 1 >> /etc/fstab \
      
mount /boot/efi
apt install --yes grub-efi-amd64
```

ここまで行けばもう少しです！
##ユーザグループの設定
プリンター使うときに必要らしい．

```console
addgroup --system lpadmin
addgroup --system sambashare
```

##rootパスワードの設定
rootアカウントのパスワードを設定します．

```console
passwd
```
タイプしてもカーソルが移動しませんが，入力自体はされているので心の眼で進めます．

##ZFSファイルシステムのマウント設定
どうやらXubuntu18.04というか，現在のZFS on linuxではlog,tmpのマウントに一工夫必要らしいです．

```console
zfs set mountpoint=legacy rpool/var/log
zfs set mountpoint=legacy rpool/var/tmp
cat >> /etc/fstab << EOF
rpool/var/log /var/log zfs defaults 0 0
rpool/var/tmp /var/tmp zfs defaults 0 0
EOF
```
rootファイルシステムを認識しているかチェックします．

```console
grub-probe /
```
```
zfs
```
と出力されればOKです．

##ブートローダの設定
PCは電源を入れると

UEFI→デバイス認識→ブートローダ読み込み→OS起動

という順序でOSが起動します．ブートローダはOSの起動のためにUEFIとやり取りをするための小さなプログラムです．

まだブートローダの設定が終わっていないため，
このまま再起動してしまうと何事もなくWindows10が起動します．
（またはOS Not Foundとエラー画面が出て動きません．)

というわけでブートローダの設定行い，それをUEFIに教えてあげます．

###ブートイメージの再構築
ブートイメージを再構築します．
このイメージには小さなシステム(ミニルートって言うらしいです)が入っており，ファイルシステムを扱ったりカーネルとやり取りするためのプログラムが入っています．
ブートローダが起動するとき，カーネルのほかにこいつを読み込みます．結構大事．

```console
update-initramfs -c -k all
```

こんな感じの出力がされると思います．少し待ちます．

```console
update-initramfs: Generating /boot/initrd.img-4.15.0-12-generic
```

###GRUBの設定
ブートローダには様々な種類があります．WindowsならWindowsBootManager，Linux系ならGrubが有名です．
今回はGrub2.02を使います．

まずはGRUBの設定をします．

```console
nano /etc/default/grub
```
以下の変更を加えます↓
GRUB_HIDDEN_TIMEOUT=0のコメントアウトを外します

GRUB_CMDLINE_LINUX_DEFAULT=""に書き換えます

GRUB_TERMINAL=consoleのコメントアウトを外します

ctrl+Oを押した後Enterキーで保存します．


設定を反映します

```console
update-grub
```
ここで以下のように出力されるか確認します

```console
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-4.15.0-12-generic
Found initrd image: /boot/initrd.img-4.15.0-12-generic
(省略)
done
```
Found linux imageとinitrd imageが1つも表示されない場合はXubuntuの起動イメージを認識していません．
もう一度7章をやり直してください．

###GRUBの書き込み
設定したGRUBをEFIパーティションに書き込みます．

```console
grub-install --target=x86_64-efi --efi-directory=/boot/efi \
      --bootloader-id=xubuntu --recheck --no-floppy
```
エラーが出なければ成功です．

最後にZFS関連のモジュールが存在するかチェックします

```console
ls /boot/grub/*/zfs.mod
```

#8 後片付け
現時点の状態をバックアップしてログアウトします．

```console
zfs snapshot rpool/ROOT/xubuntu@install
exit
```

すべてのデバイスのマウントを解除して再起動します．

```console
mount | grep -v zfs | tac | awk '/\/mnt/ {print $3}' | xargs -i{} umount -lf {}
zpool export rpool
reboot
```

再起動後GRUBの画面が出ます．10秒放置するとXubuntuが起動するはずです．
**GRUB RESCUEなどと出たら失敗です．でも大丈夫．またインストールメディアから起動して途中から始められます．
後で追加します．**

お疲れ様でした．これでインストールは完了です．
次回は初期設定編です．

#9 参考資料
bootパーティションだけ注意すれば，これをなぞって行けると思います.
[Ubuntu 18.04 Root on ZFS](https://github.com/zfsonlinux/zfs/wiki/Ubuntu-18.04-Root-on-ZFS)
[gihyo.jp » ADMINISTRATOR STAGE » 連載 » Ubuntu Weekly Recipe » 第384回　Initramfsのしくみ](http://gihyo.jp/admin/serial/01/ubuntu-recipe/0384)