無盤系統

出自 Arch Linux 中文维基

引用自 Gentoo Wiki:無盤節點

一台無盤機器是一台沒有任何諸如硬盤、軟盤驅動器或CD-ROM等常見引導設備的PC。無盤節點引導自網絡,並需要一台服務器來提供當作本地硬盤來使用的存儲空間。

服務端配置[編輯 | 編輯原始碼]

首先我們應當安裝如下組件:

  • 用於向無盤節點分配IP地址的 DHCP 服務端。
  • 用於分發啟動鏡像的 TFTP 服務端 (所有PXE鏡像必需)。
  • 選擇 (NFS 或 NBD) 中的一種作為存放和傳輸無盤節點的 Arch 安裝副本的網絡存儲服務。
注意: dnsmasq 能夠同時兼任 DHCP 和 TFTP 服務器。更多信息請見 Dnsmasq

DHCP[編輯 | 編輯原始碼]

安裝並配置 ISC dhcp:

/etc/dhcpd.conf
allow booting;
allow bootp;

authoritative;

option domain-name-servers 10.0.0.1;

option architecture code 93 = unsigned integer 16;

group {
    next-server 10.0.0.1;

    if option architecture = 00:07 {
        filename "/grub/x86_64-efi/core.efi";
    } else {
        filename "/grub/i386-pc/core.0";
    }

    subnet 10.0.0.0 netmask 255.255.255.0 {
        option routers 10.0.0.1;
        range 10.0.0.128 10.0.0.254;
    }
}
注意: next-server 應為 TFTP 服務端監聽的IP地址; 你需要酌情更改配置中的地址以匹配你已有的網絡環境。

RFC 4578 定義了"客戶機架構類型(Client System Architecture Type)" 的 dhcp 參數。在如上配置中,如果 PXE 客戶機(暨無盤系統)請求了 x86_64-efi 鏡像 (類型 0x7) 服務端將返回對應的文件, 否則自動回落到 legacy 鏡像。這樣,同一網絡中的 UEFI 和 legacy BIOS 均能正常啟動。

然後啟動 ISC DHCP systemd 服務。

TFTP[編輯 | 編輯原始碼]

TFTP 用於向無盤系統傳輸 啟動器、內核以及 initramfs。

將 TFTP 根目錄設置為 /srv/arch/boot。參閱 Tftpd server 配置安裝並配置。

網絡存儲[編輯 | 編輯原始碼]

NFS 與 NBD 的主要區別是,儘管兩者均允許你為多個無盤系統使用同一份安裝完畢的 Arch Linux,在使用 NBD 時 (由於其直接與文件系統交互的本質) 你將必需使用 CopyOnWrite 的模式, 並將導致在無盤系統斷開連接時丟棄所有改動。然而在一些場景中,這是一項不可多得的優勢。

NFS[編輯 | 編輯原始碼]

在服務端安裝 nfs-utils

你需要將 Arch 安裝副本的根目錄加入 NFS 的共享(「導出」)列表:

/etc/exports
/srv       *(rw,fsid=0,no_root_squash,no_subtree_check)
/srv/arch  *(rw,no_root_squash,no_subtree_check)

然後啟動 NFS 服務: rpc-idmapd rpc-mountd.

NBD[編輯 | 編輯原始碼]

安裝並配置 nbd

/etc/nbd-server/config
[generic]
    user = nbd
    group = nbd
[arch]
    exportname = /srv/arch.img
    copyonwrite = false
注意:
  • 如果你需要多台無盤系統同時啟動改鏡像,請將 copyonwrite 設為 true;詳情請參閱 nbd-server(5)
  • 可能需要使用 chown 將 exportname 目錄的所有權賦予 nbd 用戶。

啟動 nbd systemd 服務。

無盤系統配置[編輯 | 編輯原始碼]

接下來我們將在服務器端的子目錄中創建一個完整的 Arch Linux 安裝副本。啟動無盤機時,其將從 DHCP 服務器獲取一個 IP 地址,而後通過 PXE 啟動並掛載這份安裝副本作為根目錄。

安裝目錄創建[編輯 | 編輯原始碼]

創建一個至少 1GB 的 sparse file 並格式化為 btrfs。 (你當然也可以使用其他塊設備如實體硬盤或 LVM)。

注意: 對於 NBD,創建一個單獨的文件系統是必須的;但對於 NFS 這是可選的,故可酌情忽略或跳過。
# truncate -s 1G /srv/arch.img
# mkfs.btrfs /srv/arch.img
# export root=/srv/arch
# mkdir -p "$root"
# mount -o loop,compress=lzo /srv/arch.img "$root"

Bootstrap 安裝[編輯 | 編輯原始碼]

安裝 devtoolsarch-install-scripts, 然後運行 pacstrap 以為無盤系統 安裝必須的軟件包:

# pacstrap -d "$root" base linux linux-firmware mkinitcpio-nfs-utils nfs-utils
注意: 在任何配置中 mkinitcpio-nfs-utils 都必須安裝:它將提供早期啟動過程中所需的 ipconfig

現在應當生成好 initramfs。

NFS[編輯 | 編輯原始碼]

要使 NFSv4 掛載正常工作,需要輕微改動 net hook (這不被默認的net hook:nfsmount 所支持)。

# sed s/nfsmount/mount.nfs4/ "$root/usr/lib/initcpio/hooks/net" > "$root/usr/lib/initcpio/hooks/netnfs4"
# cp $root/usr/lib/initcpio/install/net{,nfs4}

此時需要備份 net 以防止其在 mkinitcpio-nfs-utils 升級時被覆蓋.

Edit $root/etc/mkinitcpio.conf and add nfsv4 to MODULES, netnfs4 to HOOKS, and /usr/bin/mount.nfs4 to BINARIES.

然後 chroot 到安裝副本的根目錄並執行 mkinitcpio:

# arch-chroot "$root" mkinitcpio -p linux

NBD[編輯 | 編輯原始碼]

在無盤系統的 Arch 安裝副本中安裝 mkinitcpio-nbdAUR。使用 makepkg 構建並安裝它:

# pacman --root "$root" --dbpath "$root/var/lib/pacman" -U mkinitcpio-nbd-0.4-1-any.pkg.tar.xz

然後你需要將 HOOKS array 中 net 之後加入 nbdnet 將負責配置網絡, 但只要不在 kernel 行中指定,它不會嘗試 NFS 掛載。

配置無盤系統[編輯 | 編輯原始碼]

在上述步驟完成後,你仍需要時情況完成主機名,時區,區域設置,鍵盤布局等其他 Installation guide 提及的配置步驟。

啟動器[編輯 | 編輯原始碼]

GRUB[編輯 | 編輯原始碼]

儘管沒有詳細文檔, GRUB 支持從 PXE 加載:

# pacman --root "$root" --dbpath "$root/var/lib/pacman" -S grub

使用 grub-mknetdir 在目標系統(無盤系統的 Arch 安裝副本)中創建一個 grub prefix:

# arch-chroot "$root" grub-mknetdir --net-directory=/boot --subdir=grub

幸運的是,grub-mknetdir 為所有已編譯/安裝的目標創建 prefix, 且 grub 的維護者在同一包中提供了兩種架構, 所以 grub-mknetdir 僅需執行一次。

現在我們創建一個 GRUB 配置:

# vim "$root/boot/grub/grub.cfg"
menuentry "Arch Linux" {
    linux /vmlinuz-linux quiet add_efi_memmap ip=:::::eth0:dhcp nfsroot=10.0.0.1:/arch
    initrd /initramfs-linux.img
}

GRUB 黑魔法將會自動設置 set root=(tftp,10.0.0.1),這樣內核和 initramfs 將自動通過 TFTP 傳輸過來,不過當你有其他非 TFTP 的啟動項時,你仍希望顯式聲明這些配置。

注意: 根據需要依照PXELINUX修改你的於NBD相關的內核行配置。

PXELINUX[編輯 | 編輯原始碼]

PXELINUX 由 syslinux 提供,詳見 PXELINUX

額外的掛載點[編輯 | 編輯原始碼]

NBD 根[編輯 | 編輯原始碼]

late boot 時你需要將根分區的文件系統切換為可讀寫(rw)並且啟動 compress=lzo 以獲得相較於 NFS 可觀的性能提升。

# vim "$root/etc/fstab"
/dev/nbd0  /  btrfs  rw,noatime,compress=lzo  0 0

程序狀態目錄[編輯 | 編輯原始碼]

本文或本章節的事實準確性存在爭議。

原因: 當 /var/log/journal 為 tmpfs 或不存在時,systemd 默認不會進行持久日誌記錄。(在 Talk:無盤系統 中討論)


你可以將 /var/log 掛載為例如 tmpfs 的文件系統,這樣多台主機的日誌將不會意外混雜在一起。對於 /var/spool/cups 亦可實行此操作,這樣 20 個使用相同 spool 的 CUPS 不會互相打架然後執行進行 1498 份打印工作並在一夜之間吃掉整摞紙(或更糟:墨盒)。

# vim "$root/etc/fstab"
tmpfs   /var/log        tmpfs     nodev,nosuid    0 0
tmpfs   /var/spool/cups tmpfs     nodev,nosuid    0 0

對於有某種唯一狀態或數據庫的軟件,最好的配置是為每台無盤主機配置唯一的儲存目錄。例,如果你想要運行 puppet 你可以簡單地在 puppet 的 systemd unit file 中使用 %H 標識符:

# vim "$root/etc/systemd/system/puppetagent.service"
[Unit]
Description=Puppet agent
Wants=basic.target
After=basic.target network.target

[Service]
Type=forking
PIDFile=/run/puppet/agent.pid
ExecStartPre=/usr/bin/install -d -o puppet -m 755 /run/puppet
ExecStart=/usr/bin/puppet agent --vardir=/var/lib/puppet-%H --ssldir=/etc/puppet/ssl-%H

[Install]
WantedBy=multi-user.target

Puppet-agent 將會在 vardir 或 ssldir 不存在時自動創建之。

如果上述方法都不適用,你還可以選擇使用 systemd generator 來針對當前主機創建一個 mount unit,不幸的是 %H 標識符無法使用。

無盤機啟動[編輯 | 編輯原始碼]

NBD[編輯 | 編輯原始碼]

本文或本章節的事實準確性存在爭議。

原因: 在服務端啟動了CopyOnWrite特性時,所有無盤系統應當均有效地只讀掛載了根分區所在的文件系統,所以理論上在NBD服務器上讀寫掛載是安全的。(在 Talk:無盤系統 中討論)


當使用 NBD 作為網絡存儲服務時,你需要無盤系統啟動前確保卸載(umount)安裝副本所在的塊設備。

這一特性使得內核更新的過程十分有趣:當客戶機開機時你不能掛載它所使用的文件系統, 這意味着你需要用一個單獨的內核來執行內核更新。

首先從客戶端安裝副本複製 $root/boot 到你的 tftp 根目錄 (通常即 /srv/boot).

# cp -r "$root/boot" /srv/boot

然後在客戶機啟動前卸載 $root

# umount "$root"
注意: 如上配置中如需升級內核,你需要在開始內核更新前於無盤機中使用 NFSfstab 中掛載 /srv/boot,或是在客戶機於NBD斷開後手動掛載客戶機文件系統。

參閱[編輯 | 編輯原始碼]