FreeBSDでディスクレスクラスターⅡ

今回は?

前回までに、TFTPの設定とDHCPの設定、配布用OSの調整を行い、PXEbootで起動できるようになりました。
今回はSlurm Workload Managerのインストールと設定を行い、Jobの発行とクラスターノードでのJobの実行ができるようにしていきます。

Slurm Workload Manager

インストールはPortsからやってもいいのですが、時間かかるので、

pkg install slurm-wlm

とやってしまいましょう。これで依存するもの(認証に使うmunge等)もインストールされます。
設定は/usr/local/etc/slurm.confから行うのですが、そのうち詳細をかくので、今は良しなにやってみてください。(本当はここが重要なのにゴメンナサイ。クラスタのメンテ中でまだ設定の見直し中なのです…。)
サービスの起動設定は、head(管理サーバ)は/etc/rc.confに

slurmctld_enable="YES"
munged_enable="YES"

と追記してください。
計算ノードのための設定は、/conf/default/etc/rc.confに

slurmd_enable="YES"
munged_enable="YES"

として、

# ./clone_root

を実行してくだい。
このままでは、/varファイルにディレクトリツリーが作製されないため、slurmとmungeのlogが書き出せず、head(管理サーバ)からidle*となってJobを実行できません。また、計算ノードの/varはRamディスクのため、/disklessに定義済みの/varを置くということもできません。かといって/disklessを読み書き可能にすると、複数台の計算ノードから大量のLogの書き込みが常に掛かるため、ディスクにもネットワークにも計算以外の無駄な負荷をかけることになり、気分がよろしくありません。
そこで、デフォルトのディレクトリツリーを定義しているファイルがあるので、そのファイルを書き換えてしまいましょう。
デフォルトのディレクトリツリーは/etc/mtree/BSD.var.distというファイルになります。このファイルをまずは、

# cp /etc/mtree/BSD.var.dist /conf/etc/default/mtree/BSD.var.dist

として、コピーしていまいましょう。
コピーしたファイル(/conf/etc/default/mtree/BSD.var.dist)を開いてみるとなんとなく定義の仕方がわかると思います。
とりあえず、

︙
lib
    munge   mode=0711
    ..
    slurm   uname=slurm gname=slurm
    ..
..
︙
log
    munge   mode=0711
    ..
    slurm   uname=slurm gname=slurm
    ..
..
︙
run
    munge   mode=0711
    ..
    ︙
    slurm   uname=slurm gname=slurm
    ..
    ︙
..

こんな感じに追記してあげてください。
※終わりの「..」(ドット×2)を忘れるとエラーを吐いてシングルユーザーモードでしかログインできなくなるの注意です。
再度、

# ./clone_root

を実行してくだい。
最後にmunge認証のkeyを設定します。これは自分で決めても良いのですが、公式が推奨してる方法を使いましょう。
こんな感じでコマンドを実行してください。

# dd if=/dev/random bs=1 count=1024 > /usr/local/etc/munge/munge.key

これでkeyは生成されました。
計算ノードにも配布しなければならないのですが、今回は/usrはNFSでマウントされるので、これで共有(配布)されることになります。
これでslurmの設定は完了です!!
とりあえずログインノード(head)にログインして、

$ srun -n 4 hostname

とやってみると、各計算ノードでhostnameを実行した結果が表示されます。
順番は、実行される順序が不定であったり、ネットワークで決まるため、実行するたびに変わります。

FreeBSDでディスクレスクラスターⅠ

あらまし

研究室のパソコンが増えてきて、それぞれにSSHで入って計算させるのがめんどくさくなった。
せっかくなら、クラスタリングしてジョブ管理までしたい。
それぞれのパソコンにOSを入れてクラスタリングするのは、ソフトウェア管理的にめんどくさいからディスクレスクラスターにしよう。
せっかくだから、ジョブスケジューラも導入してスパコンっぽくしよう。
今回はそんな内容のディスクレス起動まで。
なお、本クラスターではいわゆるBeowulf方式(こんな言葉使ってるの見たこと無いが…)をとっているが、制御ネットワークとデータ転送ネットワークを分けるなんて高尚なことはお金がかかってできないのでやっていない。
また、古いパソコンで組んでいるので、蟹チップだし100Base-Txである。そのうち更新するつもりで、Cat6ケーブル使ったり、GbEハブ使ってるけど…。たぶんその前に卒業するほうが先だろうなぁ…。

システム概要

システムの構成として

  • 管理用サーバ(head)(ログインノード兼用)が1台
  • 計算用ノード(nodex)が7台

の計8台の構成としました。(ネットワーク構成図は準備中)
管理用サーバにはNICを2つ搭載し、片方を学内ネットワークに、片方を計算用ノード側として、計算用ノードを学内ネットワークとは別のネットワークにしました*1
計算用ノードはディスクレス構成とし、PXEbootを用いて管理用サーバからOSを取得するようにしました。
OSには管理用サーバ、計算用ノード共にFreeBSD 11.0-RELEASEを使用しました。計算用ノードのOSはNFS-rootを用いて、管理用サーバの/disklessに構築した計算用ノード用OSをRead onlyでマウントしています。また計算用ノードの/home, /usrはNFSを用いて、管理用サーバの/home, /usrをマウントしています。なお計算用ノードの/var,/tmpは各計算用ノードにRAMディスクを用意しています*2
ジョブスケジューラにはSlurm Workload Managerを用いました。

PXEboot

Intelの策定したネットワークブートプロセスの規格です。省略しないとPreboot eXecusion Environmentと言います。ネットワークブートの標準的な規格です。PXEbootに対応したネットワークインターフェースを持つマザーボードまたは、PXEbootに対応したNICを追加し、BIOSの起動優先順位をPXEbootが最上位に来るように設定することで、NICに搭載されたブートROMを読み込んで、サーバのOSを自動で取得、起動します。
サーバーとクライアントのシーケンスは以下のようになります。
(図は準備中)
この図からIPアドレスの付与を行うDHCPサーバー、ブートローダーの提供を行うTFTPサーバー、OS本体の提供を行うNFSサーバーが必要であることがわかります。本クラスターでは、この全てを管理用サーバ(head)が受け持っています。

参考URL

基本的に公式のドキュメント(21.7. ディスクレス稼働)を参考にしています。

管理用サーバの準備

パーティションの切り方

/home,/usrと/diskless(計算用ノードのOSを収める領域)は別のパーティションに割り当てるのが良いと思います。バグか仕様かわからないですが、NFSで公開するときに、/homeのみ公開する設定なのに/が見えてしまっていたので、、、。パーティションを別にすると、目的のディレクトリのみ公開できたのでそのようにしています。
/var,/tmpは別にするのが普通なのでしょうか?/varは/tmp/varのシンボリックリンクにするような構成もあるようですし、、、。今回はどちらもパーティションを切っています。
ZFSは使ってません。情弱です。

/etc/hostsに計算用ノードを追加

計算用ノードのホスト名と対応するIPアドレスを/etc/hostsに追加していきます。計算用ノード側には192.168.10.0/24のネットワークを使用します。

︙
192.168.10.10 node1
192.168.10.11 node2
192.168.10.12 node3
192.168.10.13 node4
192.168.10.14 node5
︙

DHCPサーバ

portsからテキトウにインストール。

# cd /usr/ports/net/isc-dhcp-43-server
# make install

/etc/rc.confにこんな感じに設定を追記。

dhcpd_enable="YES"
dhcpd_flags="-q"
dhcpd_conf="/usr/local/etc/dhcpd.conf"
dhcpd_ifaces="em0" # IPアドレスをばらまく側のネットワークを接続しているNIC指定する。
dhcpd_withuser="dhcpd"
dhcpd_withgroup="dhcpd"

dhcpd_ifacesに計算用ノード側のNICを指定する。NICの指定を間違えるとDHCPサーバーが2台存在するようになったり…。既存ネットワークに障害を発生させる原因になるので注意する。
/usr/local/etc/dhcpd.confにDHCPの設定を書く。計算用ノードのMACアドレスを調べておく。

default-lease-time 600;
max-lease-time 7200;
subnet 192.168.10.0 netmask 255.255.255.0 {
   use-host-decl-names on;
   option routers 192.168.10.1;
   option subnet-mask 255.255.255.0;
   option broadcast-address 192.168.10.255;
   next-server 192.168.10.1;     # TFTPサーバーのアドレス要は管理用サーバーのアドレス
   filename "pxeboot";           # ブートローダー?のファイル名
   option root-path "/diskless"; # NFSで配布するOS本体のルートディレクトリ
}

host node1{ # ここで指定するホスト名が計算用ノードに割り当てられる。
   hardware ethernet 00:00:00:00:00:00; # 計算用ノードのMAC。
   fixed-address node1; # hostsファイルに設定したIPアドレスが設定される。
}
︙

hostから始まる4行を各計算用ノードの数だけ設定する。
下記コマンドでdhcpサーバーをstartさせる。なお、OSを再起動すると、rc.dのdhcp_enable="YES"を読み込んで自動起動する。

# /usr/local/etc/rc.d/isc-dchp start

TFTPサーバ

/etc/inetd.confを開き、tftpから始まるudpの行のコメントを外す。

tftp dgram udp wait root ...

最後にTFTPで配布するディレクトリが設定されているため、そのディレクトリを確認する。11.0Releaseでは/tftpbootになっていました。
起動時にTFTPサーバーが自動起動するように、/etc/rc.confに下記を追記する。

inetd_enable="YES"

PXEboot用のブートローダーを/tftpbootに配置する。

# mkdir /tftpboot
# cp /boot/pxeboot /tfptboot

これでTFTPサーバーの設定は終了。下記コマンドでTFTPサーバーを起動する。DHCPと同様にOSの再起動時は自動で起動します。

/etc/rc.d/inetd start

ここまで行うと、計算用ノードを起動するとブートローダーまでは自動で起動するはずです。BIOSでPXEbootの設定をしていなければ起動しませんが...

NFSの設定

/etc/rc.confに以下を追記します。

nfs_server_enable="YES"
mountd_enable="YES"
rpcbind_enable="YES"
rpc_statd_enable="YES"
rpc_lockd_enable="YES"
nfs_client_enable="YES"

これで、サービスの起動設定ができました。次に、
/etc/exportsに公開するディレクトリの設定を記述します。今回は以下のようにしました。

/diskless -maproot=0 -network 192.168.10.0 -mask 255.255.255.0
/home -maproot=0 -alldirs -network 192.168.10.0 -mask 255.255.255.0
/usr -maproot=0 -network 192.168.10.0 -maks 255.255.255.0

NFSのサービスを以下のコマンドの順に起動します。

# /etc/rc.d/rpcbind start
# /etc/rc.d/mountd start
# /etc/rc.d/nfsd start
# /etc/rc.d/statd start
# /etc/rc.d/lockd start

これで、計算用ノード側のネットワークにOSのディレクトリが公開されました。

NTPの設定

NTPの設定をします。本クラスタはProxy環境下に作成するため、NICTやInternet MultifeedのNTPサーバが使えません。そこで、情報センターが用意しているntpサーバを使う設定をします。また、計算用ノード側の時刻設定をするための、ntpサーバとなるための設定も行います。
/etc/ntp.confの設定を変更します。

︙
server 172.24.2.55 # 適宜自分の環境に合わせてください
︙
restrict 192.168.10.0 mask 255.255.255.0 notrust nomodify notrap
︙

OS再起動時にNTPサーバが起動するように、/etc/rc.confに

ntpd_enable="YES"

を追記する。

計算用ノード用OSの構築

計算用ノード側のOSを構築していきます。FreeBSDにはディスクレス起動用のセットアップツールであるclone_rootというスクリプトが標準で用意されています。スクリプトをrootのホームディレクトリにコピーします。

cp /usr/share/example/diskless/clone_root ~/
chmod +x clone_root

このスクリプトは、スクリプトを実行している環境を/disklessにコピーします。いくつか修正が必要ですので、修正していきます。

︙
DEST=/diskless # コピーする先。
︙
TOCOPY="bin boot etc sbin lib libexec" # コピーするディレクトリ
︙

※注意:まだ実行しないでください。

計算用ノード用各種設定ファイルの準備

FreeBSDディスクレス起動時には/etcディレクトリの設定ファイルを別のディレクトリ(/conf)に用意したファイルと置き換える機能を備えています。また、IPアドレス毎に異なる設定を適用する仕組みも備えています。ここではその機能を利用します。
まずはじめに、管理用OマシンのOS上に計算用ノード用OSの設定ファイルを管理するディレクトリ作成します。

mkdir -p /conf/default/etc
mkdir -p /conf/base/etc

この中に計算用ノードに適用する設定ファイルを作成します。/defaultの部分をIPアドレスにすることで、そのIPアドレスを持つ特定のノードのみに適用する設定ファイルを作成することもできます。
まず、/conf/default/etc/fstabを作成します。

192.168.10.1:/diskless /     nfs ro 0 0
192.168.10.1:/usr      /usr  nfs ro 0 0
192.168.10.1:/home     /home nfs rw 0 0
proc         /proc           procfs rw 0 0

次に、/conf/default/etc/rc.confを作成します。

keymap="jp.106kbd"
ifconfig_re0="dhcp" # interface名は適宜変えてください
sshd_enable="YES"
ntpd_enable="YES"
inetd_enable="YES"
nfs_client_enable="YES"
tmpmfs="YES"
tmpsize="20m"
varmfs="YES"
varsize="32m"
dumpdev="AUTO"

次に、/conf/base/etc/diskless_remountを作成します。

/etc

ntp.confを上書きしないと、計算用ノードが時間を撒き散らしてしまうので、先程作ったntp.confを/conf/default/etcにコピーしてrestrictの行を消しておく。また、管理用ノードに時刻を同期するようにserverの設定を書き換える。

cp /etc/ntp.conf /conf/default/etc/

これで、ntp.confをコピー。次にntp.confを以下のように書き換える。

# server 172...... #さっき作ったやつはコメントアウトなり、消すなり。
server 192.168.10.1 iburst #管理用ノードを同期するように。
︙
# restrict ....    #restrictはコメントアウト

これで全ての設定ができました。
最後に、

~/clone_root

を実行することで、/disklessに管理用に計算用ノードのOSが全てコピーされます。
これでディスクレス起動の準備ができました。ディスクレスノードのBISO(UEFI)で、PXEbootを起動順序の先頭にし、管理用ノード→計算用ノードの順で起動するこで、計算用ノードでもFreeBSDが起動するはずです。

*1:別のネットワークにする理由として、後述するPXEbootを行うためにDHCPを用いるからで、学内ネットワーク側にIPアドレスの配布を行わないようにする目的があります。同時に学内ネットワーク側から計算用ノードを見えないようにするという意味もあります。

*2:計算用ノードはディスクレス構成であり、またOSはRead onlyのため、/var,/tmpを保存することができません。そこで/var,/tmpはRAMディスクを各計算用ノードに用意し、それをマウントしています。再起動時に消えてしまいますが、当方の運用方針では問題無いとしています。