這裡介紹使用 Ubuntu Linux 12.04 LTS Server 版與 OpenMPI 來架設 MPI Cluster,而測試主機總共有三台,一台作為 master,兩台為 slave,硬體架構圖如下:

ubuntu-1204-openmpi-cluster-1

master 有兩張網路卡,一張對內,一張對外。

首先將 master 與兩台 slave 都安裝好 Ubuntu 12.04 LTS Server 版,接著設定網路。

如果要裝 Ubuntu Desktop 版本也是可以,不過 Desktop 版本會裝一堆用不到的套件,再加上啟動 X Window 又耗資源,因此建議若是您的機器是專門用於計算的,用 Server 版會比較好。

NAT

首先設定網路,master 的部分,有兩張網路卡,分別為 eth0 與 eth1,我們將 eth0 用於對外的網路連線,而 eth1 則用於內部的網路。

首先設定 eth1 對內的設定,更改 /etc/network/interfaces 設定檔:

auto eth1
iface eth1 inet static
address 192.168.0.1
netmask 255.255.255.0
network 192.168.0.0
broadcast 192.168.0.255

而 eth0 的部分則自己依照一般的網路設定來設就可以了。

設定 IP Forward 與 iptables,寫進 /etc/rc.local,讓每次重開機後都會自動執行:

sysctl net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth0 -j MASQUERADE

接下來設定 Slave1 的網路設定,更改 /etc/network/interfaces:

auto eth0
iface eth0 inet static
address 192.168.0.2
netmask 255.255.255.0
network 192.168.0.0
broadcast 192.168.0.255
gateway 192.168.0.1
dns-nameservers 168.95.1.1

DNS 這裡設定為 Hinet 的 DNS,若是您有自己慣用的 DNS,也可以設為自己的。

接著設定 Slave2 的網路設定,更改 /etc/network/interfaces:

auto eth0
iface eth0 inet static
address 192.168.0.3
netmask 255.255.255.0
network 192.168.0.0
broadcast 192.168.0.255
gateway 192.168.0.1
dns-nameservers 168.95.1.1

網路設定好之後,用 apt 將所有的系統更新到最新版本,包含 master 與兩台 slave:

apt-get update
apt-get -y dist-upgrade

設定 /etc/hosts

接下來要設定 /etc/hosts,這樣在使用 SSH 登入時,會比較方便,另外也因為這裡的主機名稱(master、slave1 與 slave2)都沒有在正式的 DNS Server 上設定,所以這樣在 SSH 登入時會因為找不到這些主機名稱而卡住,而若是直接寫在 /etc/hosts 中就沒這個問題了。

在 master 的 /etc/hosts 加入兩行:

192.168.0.2    slave1
192.168.0.3    slave2

在 slave1 的 /etc/hosts 加入兩行:

192.168.0.1    master
192.168.0.3    slave2

在 slave2 的 /etc/hosts 加入兩行:

192.168.0.1    master
192.168.0.2    slave1

NFS

master 安裝 NFS Server:

sudo apt-get install nfs-kernel-server

設定 NFS

sudo mkdir /export
sudo mkdir /export/home
sudo mount --bind /home /export/home

設定 /etc/fstab,加入一行:

/home /export/home none bind 0 0

更改 /etc/default/nfs-kernel-server,將 NEED_SVCGSSD 設為 no:

NEED_SVCGSSD=no

更改 /etc/default/nfs-common,將 NEED_IDMAPD 設為 yes,NEED_GSSD 設為 no:

NEED_IDMAPD=yes
NEED_GSSD=no

接著設定 /etc/exports

/export 192.168.0.0/24(rw,fsid=0,no_subtree_check,sync)
/export/home 192.168.0.0/24(rw,nohide,insecure,no_subtree_check,sync)

第一行是設定 /export 為根錄目(fsid=0 即是設定為根目錄的意思),另外將 /export/home 開放給 192.168.0.0/24 這個網域的所有機器。

設定/etc/idmapd.conf 的 Domain

Domain = your.domain

接著重新啓動 NFS Server 與 idmapd:

sudo /etc/init.d/nfs-kernel-server restart
sudo start idmapd # or...
sudo service idmapd restart

slave1 與 slave2 安裝 NFS Client:

sudo apt-get install nfs-common

再設定 /etc/default/nfs-common,將 NEED_IDMAPD 設為 yes:

NEED_IDMAPD=yes

設定/etc/idmapd.conf 的 Domain

Domain = your.domain

(重新)啟動 idmapd:

sudo start idmapd # or...
sudo service idmapd restart

設定 /etc/fstab,加入一行:

master:/home /home nfs4 _netdev,auto 0 0

NIS

master 安裝 nis

apt-get install nis

Domain 自行指定,記得要跟兩個 slave 的設定一樣。

設定 /etc/default/nis

NISSERVER=master
NISCLIENT=false

更新 yp 資料:

/usr/lib/yp/ypinit -m

重新啓動 yp:

/etc/init.d/ypserv restart

slave1 與 slave2 安裝 nis

apt-get install nis

設定 /etc/yp.conf,加入:

ypserver master

設定 /etc/nsswitch.conf:

passwd:         compat nis
group:          compat nis
shadow:         compat nis

hosts:          files nis dns
networks:       files

protocols:      db files nis
services:       db files nis
ethers:         db files
rpc:            db files

netgroup:       nis

重新啓動 yp:

/etc/init.d/ypserv restart

SSH

設定 SSH 使用 public key 登入:

ssh-keygen -t dsa
cd ~/.ssh
cat id_dsa.pub >> authorized_keys

測試登入是否不需密碼:

ssh seal@slave1
ssh seal@slave2

OpenMPI

安裝 OpenMPI:

apt-get install libopenmpi-dev openmpi-bin openmpi-doc

建立 MPI_Hello.c 檔:

#include <stdio.h>
#include <mpi.h>
int main(int argc, char* argv[]) {
   int myrank, nprocs;

   MPI_Init(&argc, &argv);
   MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
   MPI_Comm_rank(MPI_COMM_WORLD, &myrank);

   printf("Hello from processor %d of %d\n", myrank, nprocs);

   MPI_Finalize();
   return 0;
}

編譯:

mpicc MPI_Hello.c -o MPI_Hello

執行:

mpiexec --host slave1,slave2 -n 4 MPI_Hello

輸出為

Hello from processor 1 of 4
Hello from processor 3 of 4
Hello from processor 0 of 4
Hello from processor 2 of 4