在ZFS檔案系統上安裝完整Manjaro - Linux

Andrew avatar
By Andrew
at 2021-06-08T00:27

Table of Contents

Hi,
最近成功的將完整的 Manjaro KDE edition 成功裝在 ZFS 檔案系統上
發現這裡關於 ZFS 的討論很少,於是想分享一下我的安裝經驗
原文發在 Manjaro 論壇上,有興趣的也可以去看看
https://t.ly/C141
希望可以多推廣 ZFS 在 Linux 上的使用.
教程上寫的比我實際的情形來得簡單許多. 比如我的 EFI 系統分割是裝在軟體磁碟陣列上, 教程中略過 RAID 設定的部份

========正文開始========
# 0. 準備 Live Media
隨便找一個支援 ZFS 的版本並下載 ISO 檔將其燒錄成可開機媒介 (USB, DVD 等)

# 1. 開機並進入 Live environment
進入 BIOS/UEFI 將你的可開機媒介啟動順序調前並開機進入 Live 環境

# 2. 準備磁碟分割
我們要將系統碟至少做下列三個分割區:
(1) EFI system partition (ESP): 檔案系統為 FAT32, 大小至少為 512 MB.
圖形介面下記得加入 esp 旗標
(2) SWAP: 檔案系統為 linuxswap, 大小依據記憶體及使用需求而異
(3) ZFS: 使用圖形介面的話將其保留為未格式化, 然後標籤為 Solaris Root
這裡推薦使用 gdisk 做磁碟分割以利於設立正確的標籤

# 3. 建立 ZFS pool 及 dataset
ZFS 檔案系統使用虛擬磁碟機的概念, 我們可以將 pool 當作 container, 而 dataset 才是我們用來掛載的檔案系統
這裡要注意的是要事先規劃好系統要使用哪種開機加載器 (GRUB 或 systemd-boot), 這將影響到建立 ZFS pool 的參數
首先以 sudo modprobe zfs 確認 zfs 模組已加載至核心
接著以 ls -lh /dev/disk/by-id 找出我們要用來建立 ZFS 的磁碟分割的 ID
再來使用下列指令來使用該磁碟分割建立 ZFS pool

sudo zpool create -f -o ashift=12 \
-O acltype=posixacl \
-O relatime=on \
-O xattr=sa \
-O dnodesize=legacy \
-O normalization=formD \
-O mountpoint=none \
-O canmount=off \
-O devices=off \
-R /mnt \
-O compression=lz4 \
<zfs-pool-name> /dev/disk/by-id/<id-to-partition-partx>

若是你要使用 GRUB 做為開機加載器的話, 使用以下指令

sudo zpool create -d -o ashift=12 \
-o feature@allocation_classes=enabled \
-o feature@async_destroy=enabled \
-o feature@bookmarks=enabled \
-o feature@embedded_data=enabled \
-o feature@empty_bpobj=enabled \
-o feature@enabled_txg=enabled \
-o feature@extensible_dataset=enabled \
-o feature@filesystem_limits=enabled \
-o feature@hole_birth=enabled \
-o feature@large_blocks=enabled \
-o feature@lz4_compress=enabled \
-o feature@project_quota=enabled \
-o feature@resilver_defer=enabled \
-o feature@spacemap_histogram=enabled \
-o feature@spacemap_v2=enabled \
-o feature@userobj_accounting=enabled \
-o feature@zpool_checkpoint=enabled \
<zfs-pool-name> /dev/disk/by-id/<id-to-partition-partx>

則該 ZFS pool 將只支援 GRUB 可使用的功能, 否則到後面執行 grub-install 時會失敗
若想使用完整的 ZFS 功能, 推薦使用 systemd-boot 做為開機加載器, 設定上會簡單點

接著若有其他的磁碟也想做為 ZFS 使用且該磁碟只有一個磁碟分割區的話, 那在建立 ZFS pool 時直接指定整顆磁碟 (沒有-partx) 即可.
接著我們在已建立的 ZFS pool 底下建立 datasets 用來掛載系統

sudo zfs create -o mountpoint=none <zfs-pool-name>/manjaro
sudo zfs create -o mountpoint=/ -o canmount=noauto <zfs-pool-name>/manjaro/root

datasets 的層級設計很有彈性, 唯一要注意的是要掛載在 / 的 dataset 一定要加入 -o canmount=noauto

在所有的 ZFS pool 及 dataset 都建立好後, 我們要將其先匯出再匯入, 否則之後掛載會有問題

sudo zpool export <zfs-pool-name>
sudo zpool import -d /dev/disk/by-id -R /mnt <zfs-pool-name> -N

# 4. 掛載檔案系統
先掛載做為 / 的 ZFS dataset

sudo zfs mount <zfs-pool-name>/<zfs-dataset-for-root>

若有其他 ZFS datasets 也依樣畫葫蘆將其掛載. 接著再掛載其他非 ZFS 的檔案系統及 ESP
此時注意若開機加載器使用的是 GRUB, 則將 ESP 掛載於 /mnt/boot/efi 下. 若使用 systemd-boot 的話則直接掛載在 /mnt/boot 底下即可.

接著我們要掛在於 / 的 ZFS pool 設定 bootfs 參數, 這樣系統才知道要去哪裡找系統

sudo zpool set bootfs=<zfs-pool-name>/<zfs-dataset-for-root> <zfs-pool-name>

然後為每個 ZFS pool 設定 cachefile 的位置

sudo zpool set cachefile=/etc/zfs/zpool.cache <zfs-pool-name>

最後將 zpool.cache 複製到準系統碟底下, 這樣開機時才會自動掛載 ZFS datasets

sudo mkdir -p /mnt/etc/zfs
sudo cp /etc/zfs/zpool.cache /mnt/etc/zfs/zpool.cache

接著準系統的磁碟掛載都準備好在 /mnt 之下了. 以上的準備工作應該適用於各個發行版. 接下來的安裝將會以 Manjaro 為主. 其他發行版若有手動安裝的方式應該能自行套用

# 5. 使用官方發佈的 iso-profile 及 basestrap 指令將完整系統安裝到準系統碟
如果不想像 Arch 一樣一切從基本系統開始的話, 我們可以用官方發佈的 iso-profile 將完整的系統安裝起來
首先先取得 iso-profile

git clone https://gitlab.manjaro.org/profiles-and-settings/iso-profiles.git ~/iso-profiles

底下有各個版本的 ISO 資料. 比如說我們想安裝的是 KDE 版本, 我們就查看 ~/iso-profiles/manjaro/kde 這個目錄, 底下應該有如下的檔案結構

desktop-overlay
live-overlay -> ../../shared/manjaro/live-overlay
Packages-Desktop
Packages-Live -> ../../shared/Packages-Live
Packages-Mhwd -> ../../shared/Packages-Mhwd
Packages-Root -> ../../shared/Packages-Root
profile.conf

其中最重要的是 Packages-Desktop Packages-Root 這兩個檔案, 及 desktop-overlay 資料夾
那兩個檔案中是該 版本所安裝的套件, 而 desktop-overlay 裡是 Manjaro 為該版本所預設的設定檔
需要注意的是 Packages-Root 裡面的 KERNEL 套件為核心, 使用者需自行以 linux510 之類的名稱來替換
我們接著隨便以任何方法將裡面的套件整理成清單, 要注意 KERNEL-zfs (linux510-zfs) 及 zfs-utils 這兩個套件必須在清單內以提供 ZFS 支持
接著以 basestrap 安裝所有清單內的套件

sudo basestrap /mnt <所有所需套件>

安裝完之後, 再將 desktop-overlay 裡的所有東西複製到 /mnt 底下, 系統就算基本安裝完了. 我們還得先做些基本設定以確保系統能正常運作
第一件事是編輯 /etc/fstab 以讓系統自動掛載其他非 ZFS 檔案系統, 再來是在 initramfs 中加入 ZFS 的支持, 並且安裝開機加載器及啟動必要的 systemd 服務
在進入 chroot 環境之前, 我們先以 ls -lh /dev/disk/by-uuid 找出其他分割區的 UUID
接著執行

sudo manjaro-chroot /mnt /bin/bash

以 bash 進入 /mnt 的 chroot 環境
接著編輯 /etc/fstab, 內容大概如下

# Static information about the filesystems.
# See fstab(5) for details.

# <file system> <dir> <type> <options> <dump>
<pass>
UUID=1A66-24E1 /boot vfat defaults 0 0
UUID=5af3f596-1068-457f-9d64-4db5aa649caa none swap defaults 0 0
UUID=388de0df-1d0b-4f78-b6a7-2888859d3fa1 none swap defaults 0 0

再來我們編輯 /etc/mkinitcpio.conf 檔案以對 initramfs 加入 zfs 支持
找到 HOOKS 那行, 並在 keyboard 及 filesystem 之間加入 zfs, 內容大概如下

HOOKS=(base udev autodetect modconf block keyboard zfs filesystems fsck)

接著執行 mkinitcpio -P 以重新建立 initramfs 供開機使用

接著安裝開機加載器. 如果使用 GRUB 的話, 執行

grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=Manjaro
grub-mkconfig -o /boot/grub/grub.cfg

如果使用的是 systemd-boot 的話, 執行

bootctl install

然後建立 /boot/loader/entries/manjaro5.10.conf 的 entry 設定檔, 內容大約如下

title Manjaro Linux 5.10
linux /vmlinuz-5.10-x86_64
initrd /amd-ucode.img
initrd /intel-ucode.img
initrd /initramfs-5.10-x86_64.img
options zfs=zroot/manjaro/root rw

此設定檔也可以透過安裝 systemd-boot-manager 並執行sdboot-manage gen 來自動産生
接著啟動必要的 systemd 服務使系統能自動掛載 ZFS datasets

systemctl enable zfs.target
systemctl enable zfs-import-cache
systemctl enable zfs-mount
systemctl enable zfs-import.target

接著啟動顯示管理員 (display manager) 的服務使系統能直接在開機時進入桌面環境
以 KDE 版本為例, 其預設的顯示管理員為 SDDM, 因此我們啟動

systemctl enable sddm.service

最後, 我們需要在系統産生 hostid 的設定檔, 否則系統在關機或重開機的過程中會無法卸載 ZFS
執行

zgenhostid $(hostid)

至此為止, 系統已安裝完成且可正常運作. 下一步我們將客製化系統.

# 6. 設置系統並新增一般使用者
以下的設置流程應該也適用其他發行版. 我們將設定鍵盤配置, 系統語言, 時區, 系統時鐘, 主機名稱, 主機名稱設定檔, 開啟管理員權限, 網路功能, 時間同步功能及 Root 密碼
接著上面的流程, 我們還是在 chroot 環境之下
6.1 鍵盤配置
鍵盤配置的清單位於 /usr/share/kbd/keymaps 底下. 鍵盤配置的設定檔位於 /etc/vconsole.conf 預設為 US 鍵盤, 內容為

KEYMAP=us
FONT=
FONT_MAP=

若想改用其他如德國鍵盤配置, 將 us 改為 de 即可

6.2 系統語言
編輯 /etc/locale.gen 檔案, 將想使用的語言 ( 如 zh-TW.UTF-8) 去掉註解, 然後執行

locale-gen

然後編輯 /etc/locale.conf 檔案, 將 LANG 參數設定為指定的語言

6.3 時區
時區列表位於 /usr/share/zoneinfo/ 之下. 如要設定為臺灣時區, 我們可將 /usr/share/zoneinfo/Asia/Taipei 符號連結到 /etc/localtime

ls -sf /usr/share/zoneinfo/Asia/Taipei /etc/localtime

6.4 系統時鐘
讓系統使用 UTC 加上時區資訊的方式記錄時間

hwclock --systohc --utc

6.5 主機名稱
設定主機名稱

echo 主機名稱 > /etc/hostname

6.6 主機名稱設定檔
編輯 /etc/hosts, 內容大約如下

127.0.0.1 localhost
::1 localhost
127.0.1.1 主機名稱.localdomain 主機名稱

如果系統使用靜態 IP 連接網路的話, 將 127.0.1.1 改成該 IP 即可

6.7 設定管理員權限
此步驟是為了讓 wheel 群組的成員有管理員權限
執行

visudo

然後找到 %wheel ALL=(ALL) ALL 的行並移除開頭的註解符號
按 ESC+shift+z+z 存檔並離開

6.8 開啟網路功能

systemctl enable NetworkManager

6.9 開啟時間同步功能

systemctl enable systemd-timesyncd

6.10 設定 Root 密碼

passwd

6.11 建立一般使用者

useradd -m -G lp,network,power,sys,wheel -s /bin/bash 使用者名稱
passwd 使用者名稱

若不想讓使用者有管理員權限的話, 不要加入 wheel 群組即可

至此我們已完成所有系統設定. 可輸入 exit 離開 chroot 環境

# 7 卸載檔案系統並匯出 ZFS pool
ZFS pool 必須要先匯出, 否則在重開機後掛載將出現問題
首先先卸載非 ZFS 檔案系統 (如 /boot)

sudo umount 掛載點

再來卸載所有 ZFS datasets

sudo zfs unmount -a

最後匯出所有 ZFS pool

sudo zpool export <zfs-pool-name>

接著就能重新開機, 系統應當能正常運作並進入桌面環境了.

# 設定例行性資料擦洗
例行性資料擦洗 (data scrubbing) 是維持 ZFS pool 良好的秘訣. 使用者可自行建立 systemd 服務與計時器來安排例行性資料擦洗
Arch Linux 及其分支發行版可安裝 AUR 套件 systemd-zpool-scrub.
該套件會建立 zpool scrub 的 systemd 服務及計時器, 預設為每週排程
啟動計時器的指令為

sudo systemctl enable zpool-scrub@<zfs-pool-name>.timer

========心得========
ZFS 是個先進的檔案系統, 有許多優秀的功能能防止資料損毀, 並提供了相當的彈性.
以上的流程主要為 Manjaro, 但在準備磁碟分割及 ZFS dataset 的部份應適用於各發行版. 使用者可在安裝系統及客製化的部份根據各發行版自行調整.
希望以上教程能幫助推廣 ZFS 在 Linux 上的普及.

--
Tags: Linux

All Comments

Mason avatar
By Mason
at 2021-06-12T22:49
Donna avatar
By Donna
at 2021-06-17T21:11
推 想請問大大覺得zfs btrfs xfs在一般個人使用上有
Audriana avatar
By Audriana
at 2021-06-22T19:34
什麼主要差異嗎 謝謝
Lydia avatar
By Lydia
at 2021-06-27T17:56
推 ZFS 號稱究極檔案系統
Enid avatar
By Enid
at 2021-07-02T16:18
所以 EXT4 不好嗎?
Freda avatar
By Freda
at 2021-07-07T14:41
沒辦法,Oracle家的東西,要用還是會怕怕。
Lydia avatar
By Lydia
at 2021-07-12T13:03
不是有OpenZFS嗎
Edith avatar
By Edith
at 2021-07-17T11:25
Linux 上的 ZFS 是 OpenZFS, 跟 Oracle 無關
James avatar
By James
at 2021-07-22T09:47
激推zfs,搭lxd做測試環境snapshot回溯都超方便!!
Jessica avatar
By Jessica
at 2021-07-27T08:10
zfs回溯lxd snapshot只能回溯最新的那個,更舊的就不行了
Todd Johnson avatar
By Todd Johnson
at 2021-08-01T06:32
Feature comparison https://reurl.cc/R0X7Nr
btrfs還比zfs多了兩個yes
Hazel avatar
By Hazel
at 2021-08-06T04:54
感謝A大分享,跳板切我都乖乖發佈.. btrfs可以自由跳?
Enid avatar
By Enid
at 2021-08-11T03:17
如果只是要切版用copy+rename也可以,這樣就不用一個
Belly avatar
By Belly
at 2021-08-16T01:39
一個回溯
Valerie avatar
By Valerie
at 2021-08-21T00:01
看到文件了!改天來玩玩看,再次感謝A大推薦
Aaliyah avatar
By Aaliyah
at 2021-08-25T22:24
要用zfs的話直上BSD吧
Kristin avatar
By Kristin
at 2021-08-30T20:46
很多 Linux 上的桌面軟體 BSD 不支援唷
Linda avatar
By Linda
at 2021-09-04T19:08
哪個BSD www
Catherine avatar
By Catherine
at 2021-09-09T17:30
很多 Windows 上的桌面軟體 Linux 也不支援唷
Joe avatar
By Joe
at 2021-09-14T15:53
我以為一般講的 BSD 是指 FreeBSD XD

有關 /usr/src/linux-headers-*-generic

Jack avatar
By Jack
at 2021-06-07T14:29
Ubuntu 會同時維護不同版本的 Linux kernel 來滿足不同的需求 -generic 只是一個名稱用來區別現在到底是使用哪個 kernel 這個名稱跟 Linux kernel 本身的原始碼無關 以 Ubuntu 20.04 為例可以找到下面各種版本 仔細看一下名稱跟說明應該可以猜到用途吧 $ ...

GCP 雲端VM,誤刪.ssh檔無法進入後台,

Victoria avatar
By Victoria
at 2021-06-06T08:01
https://i.imgur.com/AQSRREf.jpg 報錯如圖。 帳號為ez75843 近期假設遊戲伺服器,因要實體ip採用google could platform建立虛擬VM。 伺服器運行一段時間都很正常,想進ssh連結備份時發現無法正常取得金鑰。 報錯說找不到.ssh 以及目錄,才想起 ...

Taoyuan 板有一台Linux學習機在賣

Jack avatar
By Jack
at 2021-06-05T18:10
※ 引述《adwong (獨釣寒江雪)》之銘言: : 標題: [分享] Taoyuan 板有一台Linux學習機在賣 : 時間: Sat Jun 5 09:23:13 2021 : : #1WkPA1qy (Taoyuan) : 有興趣可以去看看,是否可以省下自己摸索的時間,看來這台主要是針對資管人而設, ...

openSUSE LEAP 15.3 is now available.

Elizabeth avatar
By Elizabeth
at 2021-06-02T22:29
Hi,各位先進好。 小小的推廣一下,openSUSE Leap 15.3 已經釋出囉。 Release announcement 15.3 https://zh-tw.opensuse.org/Release_announcement_15.3 Features 15.3 https://tinyu ...

想幫Pop!_OS 20.10裝Gcin

Eartha avatar
By Eartha
at 2021-06-02T14:45
乳提 本人新手 首先在Pop!_Shop載了 打開也不知道怎麼輸入 改照Ubuntu的教學 im-config調了 也沒看到Gcin出現在輸入法 然後看到一個好像很可靠的解法 https://github.com/pop-os/pop/issues/1445 把 etc/profile.d/pop- ...