ディスクレスシステム

提供: ArchWiki
2016年11月24日 (木) 21:36時点におけるKusakata (トーク | 投稿記録)による版 (同期)
ナビゲーションに移動 検索に移動

関連記事

Wikipedia:Diskless node より:

ディスクレスノード (またはディスクレスワークステーション) とは、ディスクドライブを使わずに、ネットワークブートを利用してサーバーからオペレーティングシステムをロードするワークステーション、またはパーソナルコンピュータのことである。

サーバー設定

まず最初に、以下をインストールする必要があります:

  • ディスクレスノードに IP アドレスを割り当てるための DHCP サーバー。
  • ブートイメージを転送するための TFTP サーバー (全ての PXE オプション ROM の必須要件)。
  • Arch 環境をディスクレスノードにエクスポートするためのネットワークストレージ (NFS または NBD)。
ノート: 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 サーバーのアドレスにしてください。他の値はネットワークにあわせて変更してください。

RFC 4578 には "Client System Architecture Type" dhcp オプションが定義されています。上記の設定の場合、PXE クライアントが x86_64-efi バイナリ (タイプ 0x7) をリクエストした場合、適切に返答し、そうでない場合はレガシーなバイナリを使います。これによって、同一のネットワークセグメント上で同時に UEFI とレガシーな BIOS のクライアントを起動できるようにしています。

ISC DHCP の systemd サービスを起動してください。

TFTP

TFTP サーバーはブートローダーやカーネル、initramfs などをクライアントに転送にするのに使います。

TFTP の root は /srv/arch/boot に設定してください。詳しくは TFTP を参照。

ネットワークストレージ

NFS と NBD どちらを使用する場合でも複数のクライアントを扱うことができますが、大きな違いとして、NBD では (ファイルシステムを直接操作するため) copyonwrite モードを使う必要があります。そのため、クライアントが切断すると全ての書き込みが破棄されます。ただし、場合によってはこれが望ましいということも考えられます。

NFS

サーバーに nfs-utils をインストールしてください。

Arch 環境の root を NFS の exports に追加する必要があります:

/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 をインストールして設定します。

# vim /etc/nbd-server/config
[generic]
    user = nbd
    group = nbd
[arch]
    exportname = /srv/arch.img
    copyonwrite = false
ノート: 複数のクライアントで NBD 共有を同時に使用したい場合 copyonwrite を true に設定してください。詳しくは man 5 nbd-server を参照。

nbd systemd サービスを起動してください。

クライアントのインストール

次に、サーバーのサブディレクトリに完全な Arch Linux 環境を構築します。起動時、ディスクレスノードは DHCP サーバーから IP アドレスを取得して、PXE を使ってホストから起動し、構築した環境を root としてマウントします。

ディレクトリのセットアップ

最低でも1ギガバイトのスパースファイルを作成して、ファイル上に btrfs ファイルシステムを作成してください (もちろん、必要であればブロックデバイスや LVM を使うこともできます)。

# truncate -s 1G /srv/arch.img
# mkfs.btrfs /srv/arch.img
# export root=/srv/arch
# mkdir -p "$root"
# mount -o loop,discard,compress=lzo /srv/arch.img "$root"
ノート: NBD ではファイルシステムを作成する必要がありますが NFS では必須ではありません。

ブートストラップのインストール

devtoolsarch-install-scripts をインストールしてから mkarchroot を実行してください。

# pacstrap -d "$root" base mkinitcpio-nfs-utils nfs-utils
ノート: In all cases mkinitcpio-nfs-utils is still required. ipconfig used in early-boot is provided only by the latter.

そして initramfs を生成してください。

NFS

NFSv4 のマウントをするためには net フックに細かい修正を加える必要があります (net フックのデフォルトである nfsmount はサポートされていません)。

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

クライアント側で mkinitcpio-nfs-utils がアップデートされたときに上書きされないように net のコピーを作成する必要があります。

$root/etc/mkinitcpio.conf を編集して MODULESnfsv4 を、HOOKSnet_nfs4 を、BINARIES/usr/bin/mount.nfs4 を追加してください。

そして、作成した環境に chroot して mkinitcpio を実行します:

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

NBD

クライアントに mkinitcpio-nbdAUR パッケージをインストールする必要があります。makepkg でビルドしてインストールしてください:

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

HOOKS 行の net の後ろに nbd を追加する必要があります。net はネットワークの設定を行いますが、カーネル行で nfsroot が指定されていない場合 NFS のマウントは行いません。

クライアント設定

以下の設定の他に、ホストネームタイムゾーンロケールキーマップなども設定する必要があります。インストールガイドを見て下さい。

ブートローダー

GRUB

ドキュメントで明記はされていませんが、GRUB は PXE によるロードをサポートしています。

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

Create a grub prefix on the target installation for both architectures using grub-mknetdir.

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

Luckily for us, grub-mknetdir creates prefixes for all currently compiled/installed targets, and the grub maintainers were nice enough to give us both in the same package, thus grub-mknetdir only needs to be run once.

以下のような 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 以外のメニューエントリが必要な場合、明示的に設定すると良いでしょう。

ノート: kernel 行を必要に応じて変更してください。NBD 関連のオプションは Pxelinux を参照。

Pxelinux

syslinux には Pxelinux が含まれています。詳しくは Syslinux#Pxelinux を参照。

マウントポイントの追加

NBD root

In late boot, you will want to switch your root filesystem mount to both rw, and enable compress=lzo, for much improved disk performance in comparison to NFS.

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

Program state directories

You could mount /var/log, for example, as tmpfs so that logs from multiple hosts do not mix unpredictably, and do the same with /var/spool/cups, so the 20 instances of cups using the same spool do not fight with each other and make 1,498 print jobs and eat an entire ream of paper (or worse: toner cartridge) overnight.

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

It would be best to configure software that has some sort of state/database to use unique state/database storage directories for each host. If you wanted to run puppet, for example, you could simply use the %H specifier in the puppet unit file:

# 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 creates vardir and ssldir if they do not exist.

If neither of these approaches are appropriate, the last sane option would be to create a systemd generator that creates a mount unit specific to the current host (specifiers are not allowed in mount units, unfortunately).

クライアントの起動

NBD

NBD を使用する場合、クライアントを起動する前に arch.img をアンマウントする必要があります。

This makes things particularly interesting when it comes to kernel updates. You cannot have your client filesystem mounted while you are booting a client, but that also means you need to use a kernel separate from your client filesystem in order to build it.

You will need to first copy $root/boot from the client installation to your tftp root (i.e. /srv/boot).

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

You will then need to umount $root before you start the client.

# umount "$root"
ノート: To update the kernel in this setup, you either need to mount /srv/boot using NFS in fstab on the client (prior to doing the kernel update) or mount your client filesystem after the client has disconnected from NBD

参照