PXEを使ったネットワークブート

初めはWOL (Wake On LAN)と混同していた、ネットワークブート規格のPXE (Preboot eXecution Environment)について弄って分かった(?)ことなど。

[ PXEとは | 事の起こり | ハードウェア | BIOS設定 | 起動プロセス | 用意する物 | 手順 | 起動 | トラブルシュート | 参考 ]

PXEとは

検索して貰うと早いのですが(ぉ、Intelが策定したネットワークブート規格です。
他にもRPL (Remote Program Load)等がありますが、PXEの方が新しい規格のようですし、何よりCentOSには既にpxebootが用意されていたのでこれ幸いということで。
RPLについては「Personal NetWareサーバーを使ってThinkPadをネットワークブートする試み」 が参考になるかと思います。(先輩のサイトだったりする)

事の起こり

失意体前屈参照。

ハードウェア

NIC
IntelのNICであれば基本的にPXEは対応しているかと思います。今回はIntel PRO/100+ Server Adapterを使用しました。どの辺がServerなのかがちょっと分からないのですが…。
Intel PRO/100+ Server Adapter
M/B
Akia GM300 Series
Pen3世代のPCなので初期設定のBIOSではLANからの起動に対応していませんでした。 BIOSのVerUPで対応。

BIOS設定

失意体前屈で書いた通り、BIOSでLANを選択すると起動するようになっているので選択しておきます。
Boot Device > LAN
なお、「Boot Other Device」をEnableに設定すると、他のFDやCD、HDDなどから起動出来ない場合にNICのBIOSを呼び出して試すようなので、こちらでも構わないかも知れません。
PXE RPL
今回は使いませんが、右はRPLを選択した際の画面です。まだサーバが用意出来てないので、当然起動はしません。

起動プロセス

ちょっと内容が古いですが、ディスクレスブートの概要にAAで解説されています。
野暮ですが私なりに理解した限りでは、

  1. NICのBoot ROMがdhcpクライアントとして働き、dhcpサーバからIPその他を割り当てて貰う。
  2. NICのBoot ROMがtftpクライアントとして働き、OS起動用Boot Loaderを転送して貰う。
    Boot Loaderのtftpサーバ上でのパスはdhcpdから取得している。
  3. Boot Loader(今回はpxelinux)が起動し、tftpサーバ上の設定ファイルを探す。
    見つかったらその内容に従って、見つからなければデフォルト設定でtftpサーバ上のOSのカーネルを探す。
  4. OSのカーネルが起動する。

という流れになっているようです。

用意する物

もちろんこれらのサーバを動かすOSが要りますが、せっかくだから(tm)それもCentOSにやらせました。
なお、ネットワークブートさせたPCはハードウェアにあるように実機ですが、サーバまで実機で用意する余裕が無かったのでVMware5上に構築しました。
また、クライアントPC(実機)もサーバPC(VMware)も、DHCPを有効にしたルータに同じサブネットのLANで繋がっているのですが、
ルータのDHCPとサーバPC上のdhcpdが衝突したりということは無いようです。(ルータのDHCPからIPを割り当てて貰うことも無し)

手順

PXEネットワークブート用サーバを構築するにはを参照しながら作業しました。というよりほとんど書いてある通りです。

[ tftp | dhcpd | pxelinux ]
tftp

まずtftpサーバを用意します。デフォルトでは導入されていないのでyumで取得してきます。
なお、以下ユーザによる入力はこの色を、viなどによる変更箇所はこの色を、コメントや注意点などはこの色を使って区別します。

[root@localhost ~]# rpm -qa |grep tftp
[root@localhost ~]# yum install tftp-server

Installed: tftp-server.i386 0:0.39-1
Complete!
[root@localhost ~]# rpm -qa |grep tftp
tftp-server-0.39-1

tftpサーバはxinetdを介して起動されるので、/etc/xinetd.d/tftpを書き換えます。

[root@localhost ~]# vi /etc/xinetd.d/tftp
# default: off
# description: The tftp server serves files using the trivial file transfer \
#       protocol.  The tftp protocol is often used to boot diskless \
#       workstations, download configuration files to network-aware printers, \
#       and to start the installation process for some operating systems.
service tftp
{
        socket_type             = dgram
        protocol                = udp
        wait                    = yes
        user                    = root
        server                  = /usr/sbin/in.tftpd
        server_args             = -s /tftpboot	#ここで指定されたディレクトリ以下が公開される
        disable                 = no
        per_source              = 11
        cps                     = 100 2
        flags                   = IPv4
}

tftpはユーザや認証といった概念がないので、サーバを実行するユーザや公開ディレクトリに関しては注意しませう。
さて、修正したらxinetdを 再起動します。

[root@localhost ~]# service xinetd restart
Stopping xinetd:                                           [  OK  ]
Starting xinetd:                                           [  OK  ]

さて、tftpサーバ上に必要なファイルをあげておきます。

[root@localhost pxeboot]# wget ftp://ftp.riken.jp/Linux/centos/4.1/os/i386/images/pxeboot/vmlinuz
[root@localhost pxeboot]# wget ftp://ftp.riken.jp/Linux/centos/4.1/os/i386/images/pxeboot/initrd.img
[root@localhost ~]# ls -R /tftpboot/
/tftpboot/:
pxeboot

/tftpboot/pxeboot:
initrd.img  vmlinuz

設定が正しいか、実際に転送してみて確認しておきませう。

D:\tmp>tftp -i 192.168.0.150 GET /pxeboot/vmlinuz
Transfer successful: 1429017 bytes in 2 seconds, 714508 bytes/s
dhcpd

tftp-serverと同様にyumで取得してきます。

[root@localhost ~]# yum install dhcp

[root@localhost ~]# rpm -qa | grep dhcp
dhcpv6_client-0.10-8
dhcp-3.0.1-12_EL.centos4

設定ファイルを用意します。サンプルが付属しているのでそれをコピーして修正します。

[root@localhost ~]# cp /usr/share/doc/dhcp-3.0.1/dhcpd.conf.sample /etc/dhcpd.conf
[root@localhost ~]# vi /etc/dhcpd.conf
ddns-update-style interim;
ignore client-updates;

subnet 192.168.0.0 netmask 255.255.255.0 {

# --- default gateway
        option routers                  192.168.0.1;
        option subnet-mask              255.255.255.0;

#       option nis-domain               "domain.org";
        option domain-name              "mitty.jp";
        option domain-name-servers      192.168.0.50;

        option time-offset              -18000; # Eastern Standard Time
        filename                        "/pxeboot/pxelinux.0";
#       option ntp-servers              192.168.1.1;
#       option netbios-name-servers     192.168.1.1;
# --- Selects point-to-point node (default is hybrid). Don't change this unles
# -- you understand Netbios very well
#       option netbios-node-type 2;

        range dynamic-bootp 192.168.0.128 192.168.0.254;
        default-lease-time 21600;
        max-lease-time 43200;

        # we want the nameserver to appear at a fixed address
#       host ns {
#               next-server marvin.redhat.com;
#               hardware ethernet 12:34:56:78:AB:CD;
#               fixed-address 207.175.42.254;
#       }
}

Boot ROMはfilenameで指定されたファイルをBoot Loaderとしてtftpでロードします。
この指定が間違っていたりファイルがないと当然起動出来なくなりますが、最初pxelinux.0が必要なことが分からなくてはまりました。
参考:PXELINUX によるネットワーク・ブート(EPIA Diskless PC の作成)
DHCP

この後、@ITでは/var/lib/dhcpd/dhcpd.leasesというファイルを作っておくように説明していますが、作らなくても動作はしました。
が、複数台dhcpにぶら下げた際IPアドレスが衝突したりするかも知れないので説明に従って作っておきましょう。

[root@localhost ~]# mkdir /var/lib/dhcpd/
[root@localhost ~]# touch /var/lib/dhcpd/dhcpd.lease
[root@localhost ~]# service dhcpd start
Starting dhcpd:                                            [  OK  ]
pxelinux

PXEからLinuxのカーネルを起動するためのBoot Loaderがsyslinuxに含まれるpxelinuxです。CentOS 4.1ではsyslinux-2.11-1が既にインストールされていました。
syslinuxやpxelinuxについては/usr/share/doc/syslinux-2.11/以下にdocumentがあります。
ここでは上に指定した通りpxelinux.0というファイルを使います。

[root@localhost ~]# cp /usr/lib/syslinux/pxelinux.0 /tftpboot/pxeboot/

次に、pxelinuxにLinuxのカーネルは何処にあるか示す設定ファイルを用意します。pxelinux.docによると、

  1. 設定ファイルはpxelinux.0が置かれているディレクトリ内の、pxelinux.cfgディレクトリに配置される。
    私の場合は/tftpboot/pxeboot/pxelinux.cfg/ということになります。
  2. pxelinux.cfgディレクトリで、起動したいPCにdhcpから割り当てられたIPを16進数表記したファイル名のファイルがあるか探す。
    例えば割り当てられたIPが192.0.2.91であればpxelinux.cfg/C000025Bを読み込もうとします。
  3. 存在しない場合、末尾を一つ削って再度試す。
    つまりC000025B, C000025, C00002, C0000, C000, C00, C0, Cという順で探します。
  4. すべて存在しなかった場合、 pxelinux.cfg/defaultというファイルを試す。
  5. それも無かった場合はpxelinux自体のデフォルト設定でLinuxのカーネルをロードしようとする。

ということになっているようです。
複数のクライアントPCをそれぞれ違うカーネルで起動したいときなど、設定ファイルを複数用意出来るので便利です。
設定ファイルのフォーマットはsyslinux.docが参考になるかと思います。(面倒なんで詳しく読んでないのは内緒)

[root@localhost ~]# mkdir /tftpboot/pxeboot/pxelinux.cfg
[root@localhost ~]# cat >/tftpboot/pxeboot/pxelinux.cfg/default
default centos4

label centos4
kernel vmlinuz
append load initrd=initrd.img devfs=nomount

なお、設定ファイルでカーネルファイルがvmlinuzと指定されていますが、設定ファイルがない場合デフォルトカーネルはlinuxなのでそのファイルが存在した場合は自動でロードされます。
linuxが無い場合はプロンプトが出て停止します。
pxelinux

ここで、

boot: vmlinuz initrd=initrd.img

と入力することで問題なく起動出来ます。

なおこの画像のあるように、pxelinuxの設定ファイルとして上記2.の前にpxelinux.cfg/01-"NICのMACアドレス"というファイルがあるか試しているので、
documentには書かれていませんでしたがMACアドレスを設定ファイル名として使うことも出来るかと思います。

ちなみに、syslinux自体はMS-DOS上で動作するLinux用のBoot Loaderということです。
pxelinux以外にもFDイメージその他から起動するためのツールなども入っているようなので、Linuxに限らず色々試してみると面白そうです。

起動

以上の設定で起動するようになります。
Booting...

今回使用したvmlinuzとinitrd.imgはCentOS 4.1のインストーラなので、この後はCDなどから起動した場合と同じようにCentOSのインストール画面へと進みます。

トラブルシュート

忘れがちなのがiptablesなどのFWの設定です。今回使用したサーバは以下のポートを使用するので、忘れずに開けておきましょう。

DCHP udp:67
TFTP udp:69
PXE udp:4011

参考

PXEネットワークブート用サーバを構築するには
PXEを使ってPCもディスクレスにしよう
PXEの使い方
pxelinuxを使用した Red Hat Linuxインストール方法 シリアルコンソール対応


../