目標は、
「MPIライブラリを使ったサンプルプログラムを複数ノードで実行する」
今回構築するクラスタの概要は、
*ヘッドノード、スレーブノード2ノードの計3ノード
*すべてのノードは、CentOS release 6.4 minimal
*ヘッドノードは、/home のみをNFSにて共有する(ディスクレスに挑戦したかったけどまた今度
ネットワークは、下図の様になる。
192.168.200.0/24がクラスタ専用のネットワークです。
各ノードのスペックは、
node name CPU RAM HDD
bwhead amd64 (1 core)*1 2 Gbyte 50Gbyte x 2*2
bwslv01 amd64 (1 core) 1 Gbyte 50 GByte
bqslv02 amd64 (1 core) 1Gbyte 50 GByte
*1 型名になっていないのは、今回構築したノードすべてが仮想マシンだからです。
*2 /home 用に1台、/用に1台
-目次-
[0] HeadノードへのOSのインストール
一番上の項目を選択
イメージをマウントしてますが、メディアテスト
Testを選択
OK
Continueを選択
OK
Next
Engilish
キーボードレイアウトの選択英字配列キーボードを使ってます。
Basic strage device
Yesを選択
ホスト名 ここでは、間違っていたので後でbwheadに修正しました。
タイムゾーン Tokyo/Asia
root のパスワード
パーティション構成を決めます
今回は、このように切ることにしました
Formatを押下
Write changes to diskを押下
Nextを押下
インストール中です
インストール完了 再起動します
再起動後 ログイン状況
[1] Head ノードの設定
A) ネットワークインターフェースの設定
前述のネットワーク構成図に沿って設定します。
/etc/sysconfig/network-scripts/ifcfg-eth0
ONBOOT=yes
BOOTPROTO=dhcp
/etc/sysconfig/network-scripts/ifcfg-eth1
ONBOOT=yes
BOOTPROTO=static
IPPADDR=192.168.200.1
NETMASK=255.255.255.0
B) /etc/hosts の編集
以下を追加
192.168.200.1 bwhead
192.168.200.2 bwslv01
192.168.200.3 beslv02
上記の編集を反映させるためにネットワークサービスを再始動
/etc/init.d/networking restart
C) DHCPサーバーのインストール
slaveノードへのOSのインストールは、物理マシンでの構築の演習としてPXEによるネットワークブートとします。ネットワークブートでは、ブートローダーの場所等の情報を配布するのにDHCPを用います。そこでDHCPサーバーを構築します。
yum list dhcp
でパッケージを検索
yum install dhcp
そして、設定ファイルを作成
---- /etc/dhcp/dhcpd.conf ------
#
# DHCP Server Configuration file.
# see /usr/share/doc/dhcp*/dhcpd.conf.sample
# see 'man 5 dhcpd.conf'
#
DHCPDARGS=eth1;
# network boot setttings
allow booting;
allow bootp;
option option-128 code 128 = string;
option option-129 code 129 = text;
next-server 192.168.200.1;
filename "pxelinux.0";
subnet 192.168.200.0 netmask 255.255.255.0{
# default gateway
option routers 192.168.200.1;
option subnet-mask 255.255.255.0;
option domain-name-servers 192.168.100.1;
range 192.168.200.100 192.168.200.254;
default-lease-time 21600;
max-lease-time 43200;
host bwslv01{
hardware ethernet 08:00:27:9C:25:55;
option host-name "bwslv01";
fixed-address 192.168.200.2;
}
host bwslv02{
hardware ethernet 08:00:27:29:4E:37;
option host-name "bwslv02";
fixed-address 192.168.200.3;
}
}
------------------------------------
設定ファイルの構文チェック
service dhcpd configtest
service dhcpd start
chkconfig dhcpd on
dhcpの使うポートを開けておく
iptables -I INPUT -i eth1 -p udp --dport 67:68 --sport 67:68 -j ACCEPT
再起動時に設定が無効にならないように
/etc/init.d/iptables save
ファイヤーウォールの再起動
/etc/init.d/iptables restart
D) tftpサーバーのインストール
ネットワークブートにおいてブートローダ等を配布するのに必要
yum install tftp tftp-server
/etc/xinetd.d/tfptd
chkconfig xinetd on
service xnetd start
chkconfig tftp on
E) slave ネットワークブートのための準備
syslinuxをインストールします。
yum install syslinux
PXEブートにブートローダ関係の必要なファイルをtftpの公開ディレクトリにコピーします。
cp /usr/lib/syslinux/pxelinux.0 /var/lib/tftpboot
cp /usr/lib/syslinux/menu.c32 /var/lib/tftpboot
cp /usr/lib/syslinux/memdisk /var/lib/tftpboot
cp /usr/lib/syslinux/mboot.c32 /var/lib/tftpboot
cp /usr/lib/syslinux/chain.c32 /var/lib/tftpboot
OS関係の必要なファイルをtftpサーバーの公開ディレクトリに取ってきます。
yum install wget
mkdir -p /tftpboot/images/centos/x86_64/6.4
cd /var/lib/tftpboot/images/centos/
wget http://linux.mirrors.es.net/centos/6.4/os/x86_64/images/pxeboot/initrd.img
wget http://linux.mirrors.es.net/centos/6.4/os/x86_64/images/pxeboot/vmlinuz
ブートローダメニューの設定ファイルを作成
---/var/lib/tftpboot/pxelinux.cfg/default---
default menu.c32
prompt 0
timeout 300
INTIMEOUT local
MENU TITLE PXE Menu
LABEL local
MENU LABEL Boot from local hard disk drive
LOCALBOOT 0
LABEL CentOS 6.4 x86_64
MENU LABEL CentOS 6.4 x86_64
KERNEL images/centos/6.4/x86_64/vmlinuz
APPEND load initrd=images/centos/6.4/x86_64/initrd.img devfs=nomount
--------------------------------------
tftp(udp 69番ポート)を開ける
iptables -A INPUT -m state --state NEW -i eth0 -p udp --dport 69 -j ACCEPT
再起動時に設定が無効にならないように
/etc/init.d/iptables save
ファイヤーウォールの再起動
/etc/init.d/iptables restart
フォワーディングを有効にする
-- /etc/sysctl.conf--
# Controls IP packet forwarding
net.ipv4.ip_forward = 1 # 0 から 1に変更
----------------------
[2] slavve ノードのOSインストール
仮想マシンを起動したら即座にF12キーを押下する
PXEブートするために「l」キーを押下する
予め行った設定が適切に行われていれば
tftpサーバーからブートロードがDLされてメニューが表示される
CentOSを選択して、Enterを押下
インストール中に用いる言語の選択
キーボードレイアウトの選択
OSインストーラーのメディア種別を選択。セキュリティ的には、
あまり宜しくないけどHTTPで取ってきます。
ネットワーク設定
IPv4は、DHCPにします。
NIC設定中
インストーラーイメージ取得中
これ以降は、Headノードと同じGUIなインストーラーが起動しての同じインストールとなる。
[3] ssh でのhead から slave へのパスワード無しログイン
MPIライブラリのデータの移動、設定ファイルの配布のための仕組みを構築します。
よくr系コマンドが用いられますが、自分の環境では、rootでのパスワード無しログインが
できるようにすることを断念したため、sshを用います。
A) slave ノードへssh-server のインストール
yum install openssh-server
scpを使うため
yum install openssh-client
/etc/ssh/sshd_configの以下のコメントをはずす
#PermitRootLogin yes -> PermitRootLogin yes
chkconfig ssh on
service sshd start
試しにrootで全てのslaveノードにログインしてみる
ssh root@192.168.200.n # n は、整数
ログインしたまま後の作業の準備
cd $HOME
mkdir .ssh
B) head ノードでの作業
公開鍵生成
ssh-keygen -b 1024 -t rsa
鍵のパスフレーズは空にしておく
公開鍵を全てのslaveノードに配布しておく。
scp ~/.ssh/id_rsa.pub root@192.168.200.n:.ssh/authorized_keys
クラスタは、外からの開始される接続を許可しないネットワーク内で運用するのでとりあえずSElinuxは無効化しておく。
setenforce 0
そして、起動後も無効になるように/etc/selinux/configのSELINUXTYPEを下記のようにdisabledに変更しておく。
SELINUXTYPE=diabled
C)シェルスクリプトの作成
各ノードに同様の実行するためのシェルスクリプトを用意( rshでも実現可能だが自分の環境では、rootでの実行がPermission Denied ど言われで実現できなかった
----${HOME}/utils/rssh.sh-----
#!/bin/bash
BEGIN_ADDR=2
END_ADDR=3
ADDR_PREFIX="192.168.200."
for i in `seq $BEGIN_ADDR $END_ADDR`
do
DST_ADDR="$ADDR_PREFIX$i"
echo "Processing for $DST_ADDR"
ssh $DST_ADDR<<EOF
$*
EOF
done
---------------------------
chmod 744 ${HOME}/utils/rssh.sh
各ノードにファイルコピーするためのコマンド
---${HOME}/utils/rsscp.sh---
#!/bin/bash
SRC_FILE=$1
DST_PATH=$2
BEGIN_ADDR=2
END_ADDR=3
ADDR_PREFIX="192.168.200."
for i in `seq $BEGIN_ADDR $END_ADDR`
do
DST_ADDR="$ADDR_PREFIX$i"
echo "Copying $SRC_FILE -> $DST_ADDR:$DST_PATH"
scp $SRC_FILE $DST_ADDR:$DST_PATH
done
--------------------------
D) /etc/hosts の配布
/etc/hosts を作成して
${HOME}/utils/rsscp.sh /etc/hosts /etc/hosts
[4] NIS を用いたアカウント一元管理
A) サーバーの構築
アカウントを一括管理するためにNISサーバーを構築する
まずは、サーバーのインストール
yum install ypserv
ドメインの設定 このドメインは、DNSとは関係がない
ypdomainname clnet
/etc/sysconfig/network に 先ほど設定したNISドメインを追加
NISDOMAIN = clnet
/var/yp/Makefile の編集(下記がオリジナルのファイルとの差分)
-----差分-----------------------
*** Makefile.org 2013-04-27 17:41:09.642037547 +0900
--- Makefile 2013-04-27 17:42:41.594036564 +0900
***************
*** 39,49 ****
# Should we merge the passwd file with the shadow file ?
# MERGE_PASSWD=true|false
! MERGE_PASSWD=true
# Should we merge the group file with the gshadow file ?
# MERGE_GROUP=true|false
! MERGE_GROUP=true
# These are commands which this Makefile needs to properly rebuild the
# NIS databases. Don't change these unless you have a good reason.
--- 39,49 ----
# Should we merge the passwd file with the shadow file ?
# MERGE_PASSWD=true|false
! MERGE_PASSWD=false
# Should we merge the group file with the gshadow file ?
# MERGE_GROUP=true|false
! MERGE_GROUP=false
# These are commands which this Makefile needs to properly rebuild the
# NIS databases. Don't change these unless you have a good reason.
***************
*** 114,120 ****
# If you don't want some of these maps built, feel free to comment
# them out from this list.
! all: passwd group hosts rpc services netid protocols mail \
# netgrp shadow publickey networks ethers bootparams printcap \
# amd.home auto.master auto.home auto.local passwd.adjunct \
# timezone locale netmasks
--- 114,120 ----
# If you don't want some of these maps built, feel free to comment
# them out from this list.
! all: passwd shadow group hosts rpc services netid protocols mail \
# netgrp shadow publickey networks ethers bootparams printcap \
# amd.home auto.master auto.home auto.local passwd.adjunct \
# timezone locale netmasks
--------------------------------
このままだとすべてのホストからNIS情報を引き出すことができるようになっているので
NIS情報を引き出せるホストを限定するために /var/yp/securenets を作成して
以下を書き込みます。
255.255.255.0 192.168.200.0
これで指定したネットワークに属するホストだけがNIS情報を引き出せるようになりました。
ここでサーバーデーモンの起動
/etc/rc.d/init.d/ypserv start
/etc/rc.d/init.d/yppasswdd start
そして、起動時に自動でデーモンが走るように以下を実行
chkconfig ypserv on
chkconfig yppasswdd on
/usr/lib64/yp/ypinit -m を実行
NISサーバーの情報を確認される。今回は、サーバーは1台体制(冗長化無し)なのでNISDOMAINで設定した内容が表示されていればおk
B) ファイヤーウォールの設定
portmapper が使う tcp と udp 111番ポートへの通信を受け入れるようにしておく。
C ) クライアントの準備 (サーバーマシンでも実行する)
./rssh.sh ' echo "NISDOMAIN = clnet" >> /etc/sysconfig/network '
./rssh.sh "sed -ei 's/\(USENIS=\)no/\1yes/' /etc/sysconfig/authconfig "
./rssh.sh 'echo "domain clnet server bwhead" > /etc/yp.conf'
slaveノード用のNS設定ファイルを作成して配布する。
mkdir tmp
cd tmp
cp /etc/nsswitch.conf tmp.conf
スレーブ用設定ファルの変更。以下がオリジナルのファイルとの差分
------差分----------
*** /etc/nsswitch.conf 2013-04-29 15:43:35.280253996 +0900
--- tmp.conf 2013-05-06 22:59:03.979813909 +0900
***************
*** 30,38 ****
#shadow: db files nisplus nis
#group: db files nisplus nis
! passwd: files nis
! shadow: files nis
! group: files nis
#hosts: db files nisplus nis dns
hosts: files dns nis
--- 30,38 ----
#shadow: db files nisplus nis
#group: db files nisplus nis
! passwd: nis files
! shadow: nis files
! group: nis files
#hosts: db files nisplus nis dns
hosts: files dns nis
--------------------
cd
./rscp.sh ./tmp/tmp.conf /etc/nsswitch.conf
ypbind をインストールする
./rssh.sh 'yum -y install rpcbind'
./rssh.sh '/etc/rc.d/init.d/rpcbind start'
./rssh.sh 'chkconfig rpcbind on'
./rssh.sh 'yum -y install ypbind'
./rssh.sh '/etc/rc.d/init.d/ypbind start'
./rssh.sh 'chkconfig ypbind on'
D) ユーザーの追加 (適宜)
NISサーバーにて
useradd newuser_name
passwd newuser_name
以上で通常通りユーザーを追加した後
cd /var/yp
make
でNIS DBに追加したユーザーの情報を追加する。
これでもログイン出来ない場合は、まずクライアントマシンで
ypcat passwd して追加したユーザーの情報が反映されれているかチェック。
追加されているにもかかわらずログイン出来ない場合は、
/etc/ypserv.conf中の
files: 30
を
files: 0
に変更してキャッシュを無効にする。
[5] NFS の構築
すべてのノードでホームディレクトリを共有できるようにする。
A) サーバーの構築
yum -y install nfs-utils
共有するディレクトリに関する設定を行う /etc/exports に以下を追加
/home 192.168.200.0/24(rw,sync,no_root_squash,no_all_squash)
/home … 共有するディレクトリの指定
192.168.200.00/24 … 共有を許すネットワーク
sync … 遅延書き込みをしない
no_root_squash … root の特権を行こうにする
no_all_squash … そのままの権限でアクセスさせる
/etc/idampd.conf にドメインの設定をする。デフォルトでは、「Domain = 」を含む行がコメントアウトされているので有効にしてドメインを記述する。
Domain = clnet
起動していないデーモンを起動しておく
/etc/rc.d/init.d/rpcbind start
/etc/rc.d/init.d/nfslock start
/etc/rc.d/init.d/nfs start
起動時にデーモンが自動で起動するようにしておく
chkconfig rpcbind on
chkconfig nfslock on
chkconfig nfs on
B) クライアントの準備
サーバーマシンからシェルスクリプトを用いて実行する
./rssh.sh 'yum -y install nfs-utils'
先ほど編集したNFSサーバーの /etc/idamp
./rssh.sh '/etc/rc.d/init.d/rpcbind start'
./rssh.sh '/etc/rc,d/init.d/nfslock start'
./rssh.sh '/etc/rc.d/init.d/netfs start'
./rssh..sh 'chkconfig rpcbind on'
./rssh.sh 'chkconfig nfslock on'
../rssh.sh 'chkconfig netfs on'
ここからは、各ノードに直接ログインして操作する
まずは、サーバーのパーティションをマウントできるかをテスト
mount -t nfs bwhead:/home /home
df -h
でマウントされたかどうかを確認する。
次に起動時に自動でマウントされるように/etc/fstab を変更
以下の行を追記
bwhead:/home /home nfs bg,intr 0 0
bg… NFSでのマウントが失敗した時にバックグランドで試行を繰り返す。
intr … 停止しているプロセスをkillするために、割り込みを可能にする。
0 … dump頻度
0 … fchkパスのフィールド
さらにインストール時に切った/home のパーティションをマウントしないようにコメントアウトしておく。
これ以上ができたNFSクライアントマシンを再起動して無事にマウントされるかを確認しておく。
[6] OpenMPI のインストール(headノード含めすべてのノードで)
その前にgcc とg++ ,makeのインストール
yum -y install gcc
yum -y install gcc-c++
yum -y install make
今回は、OpenMPI Ver.1.6.4 を用いる。
wget http://www.open-mpi.org/software/ompi/v1.6/downloads/openmpi-1.6.4.tar.gz
cd openmpi-1.6.4
./configure --prefix=/usr/local
make all # 複数コアある場合は make -j num_proc all で並列コンパイルできるらしい
[7] サンプルプログラムの実行
実行用専用ユーザーをNISサーバーにて作る
useradd cltest
passwd cltest
NIS DBへの反映
cd /var/yp ; make
ヘッドノードにてログアウトしてcltestでログインする
以下のソースを作成
-----main.c------------
#include <stdio.h>
#include <mpi.h>
int main(int argc, char **argv){
int rank, size, namelen;
char name[256];
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Get_processor_name(name, &namelen);
sleep(5);
printf("This is %d of %d on %s\n", rank, size, name);
MPI_Finalize();
return 0;
}
----------------------
mpicc main.c
でコンパイル。
実行前にライブラリサーチPATHをbashrcに追加
export LD_LIBRARY_PATH=/usr/local
source .bashrc
そして、root権限を得て/usr/local/etc/openmpi-default-hostfile (headノード)
にどのユーザーのジョブでも常に実行させたシステム共通の計算ノードを追記する。
以下例
bwhead
bwslv01
bwslv02
本来なら、ヘッドノードは、ジョブ実行のみで計算は行わないがホストPCのリソースがそんなに潤沢ではないためヘッドノードも追加した。
mpirun -np 3 a,out
これで下記の様に各ノードでの出力が表示されればクラスタ構築一応完了。
---実行結果-----
This is 0 of 3 on bwhead.clnet
This is 1 of 3 on bwslv01
This is 2 of 3 on bwslv02
----------------
[7]参考
http://kuni255.blogspot.jp/2013/04/iptables.html