カスタマイズ

一応、ディスクレス・クライアントのカーネルが立ち上がるところまで確認したので、先ずはカスタマイズをした。

/home/TFTPbootへの引越し

/ftfpboot はルートファイルシステムにある。勿論、どこかのパーティションをマウントすれば別のファイルシステムになるが、/tftpbootの為にパーティションを用意するのも行き過ぎだし、今のマシンには余ったパーティションはない*1。そこで、/tftpbootの下のディレクトリの一部を別のファイルシステムの中のディレクトリへシンボリックすることになる。例えば、/tftpboot/f8を/home/TFTPboot/f8へリンクするような感じだ。

しかし、(tftpdのソースコードを見ていないので確認はしていないが)tftpdは"-s"オプションでルート・ディレクトリを変更できるが、これはアプリケーション(tftpd)で意識的に管理しているのではなくchrootでプロセスのルートディレクトリ自身を変えていると思われる。そのため/tftpbootの下に上位のディレクトリ(この場合 /)まで遡らないとたどり着けないパスへのシンボリックリンクは実現できない。つまり、シンボリックリンクのリンク先も/tftpbootの下でないとリンクをたどれないことになる。これではルート・ファイルシステムから外へは抜け出せない。と、あきらめかけたが。

PXEのブート手順は、①BIOSがTFTPを使ってPXEローダ(pxelinux.0)をダウンロードし起動する、②PXEローダがTFTPを使って(←推測)LinuxカーネルとRAMディスク・イメージをダウンロードし、起動する、③LinuxカーネルNFSを使って必要なファイルをマウントする、ということになる。ここで①と②はTFTPプロトコルを使っている(推測)ので、必要なファイルは/tftpbootの下に置いておかなければならないが、③のNFSでマウントするファイル、つまりクライアントのルート・ファイルシステムは/tftpbootの下に置かなくても構わない。そこで次のような構成にした。

# ls -l /tftpboot
total 12
lrwxrwxrwx 1 root root   17 2008-01-22 23:39 f8 -> /home/TFTPboot/f8
drwxr-xr-x 5 root root 4096 2008-01-24 01:24 linux-install

# ls -l /home/TFTPboot
total 8
drwxr-xr-x 4 root root 4096 2008-01-22 23:40 f8

つまり、Linuxカーネルのロード&ブートまでに必要なファイルを格納いしてる「linux-install」は/tftpbootの下に実体を置き、NFSでマウントするクライアントのルート・ファイルシステムを格納する「f8」は/home/TFTPbootに実体を置き、/tftpbootからはシンボリックシンクを張っておいた。

f8に何故シンボリックリンクを張ったかというと、「PXEでディスクレス・クライアントを実現するには」にも書いてあるが、「クライアントのファイルを格納するディレクトリ名は、最初が/tftpbootで、最後がrootでなければならない」という奇妙の性質を持っているためである。つまり、/tftpboot/f8/rootはOKだが、/home/TFTPboot/f8/rootはNGになる。(最初、それを知らずにやっていて、設定が出来ずにハマっていた。しかし、何でこんな制限があるのか???)

ちなみに、NFSの設定ファイル /etc/exportsではシンボリックリンクを使ったパスで記述してある。

# cat /etc/exports
/tftpboot/f8/root       192.168.0.10/24(ro,sync,no_root_squash)
/tftpboot/f8/snapshot   192.168.0.10/24(rw,sync,no_root_squash)

クライアント用ファイルシステムの最適化

今回、ディスクレスクライアントを実現しようとしたのは古くなってHDDが使えなくなったPCをVMware Serverのコンソールとして使おう、と思ったからである。従って、クライアントで動くWindowsなりLinuxなりのOSは最小限の機能があれば良く、OSが立ち上がった状態でvmware-server-consoleが動けばいい。また、HDDが無いのでスワップも使えず、全てメモリ上で収まる範囲内のサービスしか動かせない。(今回の場合、メモリが192MBなので、その範囲内で動く必要がある) 「PXEでディスクレス・クライアントを実現するには」では「稼働しているLinux(ここでは、FC6)を用意して、そこから全ファイルをコピーするのが一番簡単な方法だ」とあるが、確かに簡単だが、既に動いている標準的な環境では色々なサービスが動いてメモリは400MB近くを占領しているのでNG。また、ファイルシステムも4GB近くもある。

既にあるマシンでディスクレス用にOSをカスタマイズすると「既にあるマシン」が使い物にならなくなってしまう。こうした時に便利なのが仮想マシンだ。仮想マシンを1つ作って、そこにFedora 8をインストールし、不必要なパッケージを削り、さらに不必要なサービスを起動しないようにした。Xウィンドウはtwmでも良かったちょっと寂しいのでGNOMEの最小限の機能がけを残した。

ファイルシステムの大きさは大体、1.9GBだった。(仮想ディスクのスペースとしては少々余裕をみて2.2GBとってある。)

# df
Filesystem           1K-blocks      Used Available Use% Mounted on
rootfs                 2269184   1892352    261632  88% /

ログイン直後のメモリの使用状況は以下の通りである。

# free
              total       used       free     shared    buffers     cached
 Mem:        190168     175776      14392          0          0     119664
 -/+ buffers/cache:      56112     134056
 Swap:            0          0          0

56MB程度しか使っていない。vmware-server-consoleを起動しても80MB程度の消費である。

クライアント用ファイルシステム「イメージ」の作成

さて、仮想マシンで作ったファイルシステムを「PXEでディスクレス・クライアントを実現するには」に紹介されているようにrsyncを使って(私の場合は)/home/TFTPboot/f8/root の下にコピーして来てもいいが、私の環境ではちょっと問題がある。/homeの下は仮想マシン用の仮想ディスクを数多く格納することを主目的としているため、比較的大きいファイル(数GB〜数十GB)を数多く置くことを前提に4MBブロックでmkfsしている。ディスクアクセスの回数を減らして高速化を計るためである。そのため、たとえ1バイトの大きさのファイルでも4MBのエリアを喰ってしまう。小さいファイルを数多く置くには効率が悪い。つまりルートファイルシステムなどのOSを格納するには不向きである。

そのため、ディスクレス・クライアントのファイルシステムは「ファイル」として/home/TFTPboot/f8/rootの下に格納するのではなく、2.2BGのディスクイメージとして適当な場所(今回は/home/TFTPboot/f8)において置き、として/home/TFTPboot/f8/rootにマウントする方法にした。一回ループデバイスを通してのアクセスになるので、ちょっと遅くなるかも知れないが、今回のケースでは一旦クライアントでvmware-server-consoleが動き出せばメモリ上だけで動作し、殆どディスクへのアクセスは無くなるので問題はないだろう。

そのために仮想マシンで、ディスクイメージを作る作業を行なった。
① 最適化したクライアントのファイルシステムを格納している仮想ディスク(A)の他に、作業の仮想ディスク(B)を追加する。実はディスクAは一旦、Fedora 8をインストールして、要らないサービスやパッケージを削るために10GBとちょっと大きめに作ってあった。作業終了後、ファイルシステムの大きさは1.9GB程度と分かったので、少々余裕を持った2.2GBの作業用ディスクBを追加して、FedoraのLiveCDでブートした。以下はLiveCDのターミナルからイメージファイルを切り出すための作業である。

# mkdir /a /b
# mount /dev/sda1 /a
# mkfs -t ext3 /dev/sdb1
# mount /dev/sdb1 /b

# cd /a
# dump -0f - . | ( cd /b; restore -rf - )

# umount /dev/sdb1
# dd if=/dev/sdb1 of=/a/tmp/Fedora-8-Diskless.img bs=512M

# ssh cat \> /home/TFTPboot/f8/Fedora-8-Diskless.img < /a/tmp/Fedora-8-Diskless.img
# rm /a/tmp/Fedora-8-Diskless.img

dump & restoreで一旦、AにあるファイルをBへ移している。cpやtarを使わなかったのはSELinuxのコンテキストがコピーされないからだ。(-Zフラグととかも付けてみたが。rsyncでもコピーできないようだ。)

sshはサーバへイメージファイルを転送するの使っているだけで、sshでなくても構わない。

これをPXIサーバでは/home/TFTPboot/f8/rootにマウントして使う。(以下はPXEサーバでの操作)

# cd /home/TFTPboot/f8
# ls root/
# mount -o loop Fedora-8-Diskless.img root
# ls root/
#    boot  etc   lib         media  net  proc  sbin     srv  tmp  var
bin  dev   home  lost+found  mnt    opt  root  selinux  sys  usr

*1:と書いていて、シンボリックリンクなんかを使わないで/tftpbootごとディスクイメージファイルにまとめてマウントしてしまえばいいじゃん、と気がついた。今度やっていみよう。