ディスクレスサーバを作ろう - その2.NFS-rootで構築

Snow Mountain


さて、前回書いたときから、随分と間が空いてしまいました。
前のエントリはコチラ(d:id:rx7:20080131:p1)。

今回からは、ディスクレスサーバの具体的な作り方を書きたいと思います。


まずは、一番簡単な方式として、ルートファイルシステムを作成して、それをオンメモリではなく、外部ディスク上のNFSで共有されているルートファイルシステムをマウントするやり方を紹介しようと思います。

ネットワークブートの(簡単な)流れ

登場人物は論理的には3人(3機?)。

  1. ディスクレスサーバ(今回の主人公です)
  2. DHCP&TFTPサーバ
  3. NFSサーバ

私は、物理的には2.と3.を同居させて、2つの筐体で構築してみました。

処理の流れとしては、以下となります。

  • ディスクレスサーバの電源をオン
  • ディスクレスサーバでPXEブート開始
  • DHCPサーバに問合せ
  • DHCPサーバから、IPアドレスとブートローダの場所を取得
  • TFTPサーバにブートローダを要求
  • TFTPサーバから、ブートローダがファイル転送され、取得
  • ブートローダが、再びTFTPサーバにファイル要求
  • TFTPサーバから、Linux kernelとinitrdがファイル転送され、取得
  • ディスクレスサーバ上で、Linux kernelおよびinitrdがメモリ上に展開される

以上が、ネットワークブートの処理の流れとなります。

構築開始

私は、DHCPTFTPNFSのサービスを1筐体で動かして、そこにディスクレスサーバを(LAN経由で)接続しました。

尚、上記のサーバも、ディスクレスサーバの上にのせるサーバもOSは、Debian GNU/Linuxを使いました(使い慣れているって理由だけだけど)。

その前提で、以下が構築ログとなります。
# ファイヤーウォール等が動いている場合は、適宜設定(DHCP, TFTP, NFS)を書き換えるようにしてください。

TFTPサービスのインストール&設定

以下のaptコマンドでインストールを実施します。

# apt-get install tftpd-hpa

Debianでは、aptでインストールTFTPサーバはいくつかあるのですが、以下URLで、tftpd-hpaが推奨されているため従います。

TFTP ブートで Pre-boot Execution Environment (PXE) 法を使用するには、 tsizeをサポートする TFTP サーバが必要になります。 Debian GNU/Linux サーバでは、atftpd と tftpd-hpa がその資格があります。 tftpd-hpa をお奨めします。

4.6. TFTP ネットブート用ファイルの準備


続いて、inetdのTFTPの項目の設定を行います。

vi /etc/inetd.conf
tftp  dgram  udp  wait  root  /usr/sbin/in.tftpd  /usr/sbin/in.tftpd -s /tftpboot

こんな感じで編集。上の例は、/tftpboot以下を転送する前提で設定しています。

# /etc/init.d/openbsd-inetd restart

設定後、inetdを再起動させます。

DHCPサービスのインストール&設定

こいつも同様にaptでインストールします。

# apt-get install dhcp3-server

続いて、DHCPサービスの設定を実施。

# vi /etc/dhcp3/dhcpd.conf
subnet 10.2.2.0 netmask 255.255.255.0 {
  range 10.2.2.224 10.2.2.240;
  option subnet-mask 255.255.255.0;
  option broadcast-address 10.2.2.255;

  next-server 10.2.2.1;
  filename "pxelinux.0";
}

こんな感じで編集。
注意点としては、DHCPサービスは設定を間違えると、場合によってはLAN内に大きなインパクトを与えてしまうため、PXEブート用のセグメントのみで有効となるよう設定を施します。

上記の設定例で、next-serverは自分自身(DHCPサーバ)のIPアドレス。filenameは、PXEブート用のブートローダとなるファイル(今回は、pxelinux.0のままでOK)とします。


ちなみに、DHCPサービスでMACアドレスに応じて、固定でIPアドレスを割り振りたい場合は、以下のような感じで定義しておきます。上記の設定の下にでも、貼り付けておけばOKです。

host hostname {
  hardware ethernet 00:1C:XX:XX:XX:XX;
  fixed-address 10.2.2.128;
  filename "pxelinux.0";
}

これは、"hostname"ってマシンのMACアドレスに対して、"10.2.2.128"ってIPアドレスを割り振る例です。MACアドレスは事前に調べておきましょう。
あと、ここにはIPアドレスを直に書かず、/etc/hostsでホスト名とあわせて管理し、ここにはホスト名を記載するのがオススメです。

# /etc/init.d/dhcp3-server start

んで、DHCPサービスを起動させます。

NFSサービスのインストール&設定

これまた同様にaptでインストールします。

# apt-get install nfs-kernel-server

インストール後、NFSマウントを許可するパスおよびホスト/ネットワークの設定を行います。

# vi /etc/exports
/tftpboot       10.2.2.0/255.255.255.0(rw,no_root_squash)

こんな感じで設定。私の場合、ルートファイルシステムの共有をPXEブートを実施したネットワークセグメントで行う設定にしました。上記の10.2.2.0/24というセグメントがそれに当たります。

# /etc/init.d/nfs-kernel-server start

設定後、NFSサービスを起動します。

ルートファイルシステムの作成

Debianなので、もちろんdebootstrapを使います。

# apt-get install debootstrap

debootstrapがインストールされていないなら、aptでインストールして、、、

debootstrap --arch i386 etch /tftpboot/Linux http://ftp.jp.debian.org/debian

debootstrapで、"/tftpboot/Linux"に、ルートファイルシステムを作成。
"/tftpboot/Linux"をルートファイルシステムとし、ここをNFS経由で共有する前提とします。

その後、ホスト名やNICの設定など、必要な設定をあらかじめルートファイルシステム内の設定ファイルに書き込んでおきます。

# cd /tftpboot/Linux

ルートファイルシステムがある場所にcdして、下記の4ファイルを書き換えます。

# vi etc/hostname

ホスト名の設定。この辺は任意の値を設定しましょう。

# vi etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address xxx.xxx.xxx.xxx
netmask 255.255.255.192
network xxx.xxx.xxx.xxx
broadcast xxx.xxx.xxx.xxx
up route add -net xxx.xxx.xxx.xxx netmask 255.255.255.248 gw xxx.xxx.xxx.xxx eth0
down route add -net xxx.xxx.xxx.xxx netmask 255.255.255.248 gw xxx.xxx.xxx.xxx eth0

auto eth2
#iface eth2 inet dhcp
iface eth2 inet static
address xxx.xxx.xxx.xxx
netmask 255.255.255.0
network xxx.xxx.xxx.0
broadcast xxx.xxx.xxx.255
gateway xxx.xxx.xxx.xxx

ネットワークの設定。このあたりも環境にあわせて設定しましょう。

一応、私が設定した値を例として載せておきます。マスキングしたら、分かりづらい感じになってしまいました。eth1は、PXEブート用に使っていて、ブート時に割り振られるため、OS側では設定しません。

# vi etc/hosts

hostsの設定。このあたりも環境にあわせて設定。

# vi etc/fstab
10.2.2.1:/tftpboot/Linux / nfs defaults        0       0

今回、NFS-rootを使うので、それに合わせて上記のように設定します。
ルートファイルシステムを置くNFSサーバのアドレスは、構築する環境にあわせてください。
上記の例だと、NFSサーバのIPアドレスが10.2.2.1となり、ルートファイルシステムのあるパス、つまりNFSマウントするべきパスが/tftpboot/Linuxとなります。

カーネルの作成(コンパイル)

さて、今回NFS-rootを用いるので、それに対応したカーネルが必要となります。

試しに、普通にCDからインストールしたDebianのvmlinuz & initrdを使ってみましたが、ダメでしたので、下記の様な感じで作成。

# apt-get install libc6-dev
# apt-get install libncurses-dev

カーネルコンパイル時に上記あたりのパッケージがないと怒られちゃうので、あらかじめaptでインストールしておきます。

# cd ~/install
# wget http://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.23.tar.gz
# tar zxvf linux-2.6.23.tar.gz
# mv linux-2.6.23 /tftpboot/Linux/usr/src/
# cd /tftpboot/Linux/usr/src/linux-2.6.23/

私は、自分が作業したときの最新版のカーネルをコンパイルしました。この辺は好みに合わせて。
今のkernel2.6系の最新版は2.6.24ですね。

# make menuconfig

で、テキストレベルの設定ファイル(.config)を編集しても良いのですが、メニュー画面に設定を実施します。私が行った設定は以下。

  • "Networking options"の中の "IP: kernel level autoconfiguration"をチェック
  • "BOOTP support"のもチェック
  • "DHCP support"のもチェック
  • "Filesystems"の"Network File Systems"にある"NFS filesystem support"もチェック
  • "Network device support"にある"Ethernet (100M)から、"Realtek8139"と、(1000M)のところから、Broadcomの"tg3"をチェック
    • 私の場合は、NICが2種類あったので・・・
    • このあたりは、マシンのNICにあわせて選択してください
  • "SCSI device support"にチェック
  • "Keyboards"関連全てにチェック
  • "USB Human Interface Device (full HID) supports"にチェック
  • "Support for Host-side USB"にチェック
  • "EHCI HCD (USB 2.0) support"にチェック
  • "OHCI HCD support"にチェック
  • "UHCI HCD (most Intel and VIA) support"にチェック
  • "USB Mass Storage support"にチェック


上から5つ目くらいまでは、基本的にチェックが必要かと思います。

それ以外は、使っているハードウェアによりけりですので、必要に応じて選択してください。
# それを思うと、ハードウェアの自動判別機能ってすごいと思うなぁ。

# make

設定が終わった後は、コンパイル実施。

# cp arch/i386/boot/bzImage /tftpboot/Linux/boot/vmlinuz-2.6.23
# cp System.map /tftpboot/Linux/boot/System.map-2.6.23

コンパイル後は、出来上がったbzImageSystem.mapを上記のような感じで、ルートファイルシステムのbootディレクトリ以下にコピーします。

PXEブート用の設定

PXEブート用のブートローダを用意します。

# apt-get install syslinux

まずは、aptでsyslinuxをインストール。

# cp /usr/lib/syslinux/pxelinux.0 /tftpboot

事前に、TFTPで/tftpboot以下を転送するよう設定&DHCPでTFTP経由で転送するファイル名を設定してあるので、pxelinux.0ファイルを/tftpboot直下に配置します。

# mkdir /tftpboot/pxelinux.cfg
# vi /tftpboot/pxelinux.cfg/default

で、起動パラメータを記す設定ファイルを編集します。

DEFAULT linux

LABEL linux
  KERNEL Linux/boot/vmlinuz-2.6.23
  APPEND root=/dev/nfs nfsroot=10.2.2.1:/tftpboot/Linux ip=dhcp
  IPAPPEND 0

構築した環境、ファイル名にあわせた設定としましょう。
PXEブート用の設定ファイルを編集したところで、PXE用の設定は完了。

構築完了

ここまで設定が完了したら、ディスクレスサーバの電源を入れ、PXEブート後、NFSマウントを実施することで、OSが起動する・・・はずです。

この方法では、サーバ自体はディスクレスとなりますが、ルートファイルシステム自体は別筐体のディスクをマウントすることとなりますので、耐障害性はそれほど高くなりません。
# ストレージ等が高価で頑丈なら話は別ですが。。。


次回は、ルートファイルシステムを完全にオンメモリで持たせる耐障害性の高いサーバを構築する方法を書き記したいと思います。