0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

複数台のAlmaLinuxで並列計算してみた(MPIの環境構築)

Last updated at Posted at 2022-04-13

はじめに

 本記事では, 複数台のAlmaLinuxを用いて, 並列計算を行うための環境構築を行います. AlmaLinuxは, CentOS8のサポート終了に伴い, その後継として開発されたLinuxディストリビューションです. 本記事は, LinuxのインストールができるMPI初心者を対象としています.

MPIとは  MPI (Message Passing Interface) とは, プロセス間で通信を行うための規格です. よく利用されるものには, MPICHやopenMPI があります. これらを利用して並列計算を実現させます.

使用環境

 ・AlmaLinux 8.5

MPIの環境構築

 本記事で構築する分散システム(図1)によって, 以下の作業が可能になります.
  ・複数台を用いて分散メモリ型の並列処理を行う.
  ・子が親を経由してインターネットに接続する(各マシンのアップデートに便利!).
  ・応用として, n対nのデータ通信をしながら数値計算を行う.
 
ネットワークの構成

             図1 分散システム

 この環境を構築するために, 以下の手順が必要です.

 手順          内容   キーワード 
- OSをインストールする(本記事の対象外)
1 ネットワークを構築する  IPマスカレード, SSH 
2 ファイルを共有する(マウントを行う) NFS
3 mpirun を実行する        

1. ネットワークを構築する

(a) ネットワークで用いるIPアドレス範囲を定める

 IPアドレスを決めます. プライベートIPアドレスとして自由に使用できる範囲は表の通りです.

 クラス   IPアドレス範囲 
A 10.0.0.0 ~ 10.255.255.255
B 172.16.0.0 ~ 172.31.255.255
C     192.168.0.0 ~ 192.168.255.255    

 本記事のネットワークの構成を図2に示します. 今回は8台のAlmaLinuxを用いて, 並列計算を行います. ホスト名をALMA01 ~ ALMA08とし, 図のように「IPアドレス/サブネットマスク」を定めました. このとき, ネットワークアドレス, およびブロードキャストアドレスはホストに割り当てられないので注意してください. (今回の割り当てでは, 最大で254台の分散システムを構築することができますね!)

 以降では, 全体の通信を制御するマスターノード(1台)と, 指示を受けてデータを送信するスレーブノード(複数)という用語を用います.

           図2 ネットワークの構成
 
 ネットワークの構成が決まったら, 各ノードでネットワーク設定を開き, IPアドレス, サブネットマスク, ゲートウェイ の設定を行います. スレーブノードのゲートウェイはマスターノードのIPアドレス(今回の場合は192.168.1.1)です.

 その後, 今回は小規模の閉じたネットワークであるため, 全ノードで/etc/hostsファイルを編集して, 名前解決を行います.

/etc/hosts
; 次の行を追加する
192.168.1.1    ALMA01    ; IPアドレス  ホスト名
192.168.1.2    ALMA02
   ...
192.168.1.8    ALMA08

ヒント
OSを1台ずつインストールする場合は, ここまで進めましょう.

以降では, SSH (Secure Shell) を用いてスレーブノードに接続し, 作業を行います.
SSHがインストールされていない場合は, 1-(c) の一行目を実行してください.

 図2を参考にしてハブと各ノードをLANで接続し, 物理的な環境を構築 します.

 pingコマンドを利用して, 互いに認識できるかどうかを確認してください.

$ ping ALMA08

 あとで必要になるため, マスターノードでifconfigコマンドを実行し, ネットワークインターフェース名(ここではeno1eno2)を確認しておきます.

$ /sbin/ifconfig
eno1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet xxx.xxx.xxx.xxx  netmask xxx.xxx.xxx.xxx  broadcast xxx.xxx.xxx.xxx
        inet6 xxxx::xxxx:xxxx:xxxx:xxxx  prefixlen 64  scopeid 0x20<link>
        ether xx:xx:xx:xx:xx:xx  txqueuelen 1000  (Ethernet)
        RX packets 160418  bytes 19653083 (18.7 MiB)
        RX errors 0  dropped 94720  overruns 0  frame 0
        TX packets 3332  bytes 1228201 (1.1 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 16

eno2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.1  netmask 255.255.255.0  broadcast 192.168.1.255
          ...

(b) ファイアウォールでIPマスカレードを設定する

 スレーブノードからインターネットに接続するには, マスターノードにルーターの働きをさせる必要があります. Linuxでは, プライベートIPアドレスをグローバルIPアドレスに変換する技術のことを IPマスカレード といいます.

 インターネットにつながったeno1とプライベートネットワークにつながったeno2は独立しています. この2つを接続するために, マスターノードで/etc/sysctl.confファイルを編集し, IPフォワーディングを有効化 します.

/etc/sysctl.conf
; 次の一行を追加する
net.ipv4.ip_forward=1

 次のコマンドで設定を反映させます.

# sysctl -p
net.ipv4.ip_forward = 1

 設定が反映されているかどうかを確認します.

$ cat /proc/sys/net/ipv4/ip_forward
1

 マスターノードでゾーンの設定を行います.

# firewall-cmd --permanent --zone=home --change-interface=eno1
The interface is under control of NetworkManager, setting zone to 'home'.
success
# firewall-cmd --permanent --zone=internal --change-interface=eno2
The interface is under control of NetworkManager, setting zone to 'internal'.
success

 ゾーンの設定を確認します.

# firewall-cmd --get-active-zones
home
  interface: eno1
internal
  interface: eno2
...

 マスターノードで IPマスカレードを有効化 し, ファイアウォールの永続設定を反映させます.

# firewall-cmd --permanent --zone=home --add-masquerade
success
# firewall-cmd --reload
success

 それぞれのゾーン(homeinternal)で設定が反映されているかどうかを確認します. activeの状態かどうか, interfaces, masqueradeの設定を確認してください.

# firewall-cmd --list-all --zone=home
home (active)
  target: default
  icmp-block-inversion: no
  interfaces: eno1
  sources: 
  services: cockpit dhcpv6-client mdns samba-client ssh
  ports: 
  protocols: 
  forward: no
  masquerade: yes
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 
# firewall-cmd --list-all --zone=internal
internal (active)
  target: default
  icmp-block-inversion: no
  interfaces: eno2
  sources: 
  services: cockpit dhcpv6-client mdns samba-client ssh
  ports: 
  protocols: 
  forward: no
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules:

 以上で, スレーブノードからマスターノードを経由してインターネットへ接続できるようになります. しかし, このままではMPIを実行することができません. そこで, マスターノードで以下のリッチルールを追加し, 反映させます. 長いので\を用いて改行していますが, \なしの1行で実行してください.

# firewall-cmd --permanent --zone=internal \
    --add-rich-rule='rule family="ipv4" source address="192.168.1.2" accept'
success
  ...
# firewall-cmd --permanent --zone=internal \
    --add-rich-rule='rule family="ipv4" source address="192.168.1.8" accept'
success
# firewall-cmd --reload
success

 次のコマンドで設定が反映されているかどうかを確認します.

# firewall-cmd --list-rich-rules --zone=internal
rule family="ipv4" source address="192.168.1.7" accept
rule family="ipv4" source address="192.168.1.3" accept
...

(c) パスフレーズなしのSSHで接続する

 MPIを用いて各ノードを通信させるとき, SSHが利用されます. 通常, SSHを利用する際にはパスワードを設定しますが, 並列処理による通信のたびにパスワードを入力することは現実的ではありません. そのため, パスフレーズなしの公開鍵認証を利用する必要があります.
 SSHでは, クライアント(SSHで接続する)側とサーバー(SSHで接続される)側にわかれます. マスターノードにはクライアント, スレーブノードにはサーバーの設定を行います. (本記事では, マスターノードにサーバーの設定も行っています. )

 全ノードでSSHに必要なパッケージをインストールします.

# dnf install -y openssh openssh-server

 マスターノードは追加で必要なパッケージをインストールします.

# dnf install -y openssh-clients

 全ノードで/etc/ssh/sshd_configファイルを編集し, SSHの 公開鍵認証を有効化 します.

/etc/ssh/sshd_config
; 次の行の#を外す
#PubkeyAuthentication yes  ->  PubkeyAuthentication yes

 全ノードでsshdを再起動し, 設定を反映させます.

# systemctl restart sshd

 全ノードで同じユーザー名(ここではuser)のアカウントを作成し, 任意のパスワードを設定します.

# useradd user
# passwd user
/* 任意のパスワードを入力する */

 マスターノードでユーザーを切り替えます.

# su user

 マスターノードでパスフレーズなしの鍵を作成します.

$ ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa

(またはssh-keygenコマンドを実行し, 何も書かずにEnterを押すと同じ出力が得られます. )
 これより, 秘密鍵 (id_rsa)公開鍵 (id_rsa.pub) が作成されました.

 マスターノードで生成した公開鍵をスレーブノードに転送し, authorized_keysに書き込みます. 次のコマンドを実行してください.(実行するときに接続先のパスワードを求められます. )

$ ssh-copy-id -i ~/.ssh/id_rsa.pub user@ALMA02  # ユーザー名@接続先
$ ssh-copy-id -i ~/.ssh/id_rsa.pub user@ALMA03
    ...
$ ssh-copy-id -i ~/.ssh/id_rsa.pub user@ALMA08

注意
 公開鍵を渡す方法は他にもあります. このとき, ディレクトリやファイルの権限が正しくないとMPIの実行時にパスワードを聞かれることがあります.
 必ず, chmod 600 authorized_keys, およびchmod 700 .ssh となっていることを確認してください.(上記の意味が理解できない場合はssh-copy-idコマンドを用いて自動登録した方がよいでしょう. )

sshコマンドを用いてパスフレーズなしで入れるかどうかを確認します.

$ ssh ALMA08 -l user -Y

2. ファイルを共有する(マウントを行う)

(a) NFSを設定する

 MPIを実行するためには, 全ノードでディレクトリやファイルが共有されている必要があります. そこで, NFS(Network File System)を用いて, マスターノードのディレクトリを共有してあげましょう. このように, 外部のファイルシステムにアクセスできるようにすることを マウント といいます.

 全ノードでNFSに必要なパッケージをインストールします.

# dnf install nfs-utils

 マスターノードで共有するディレクトリを作成します. 今回は/DATAディレクトリとします.

# mkdir /DATA

 userが利用できるようにディレクトリの所有者を変更(またはアクセス権限を付与)します.

# chown user:user /DATA

 マスターノードで/etc/exportsファイルを編集し, 公開するディレクトリの設定を行います. アクセスできる範囲には, ネットワークアドレスを指定しています. また, *(rw,async)とすることでアドレスの制限なしにも設定できます.

/etc/exports
; 次の1行を追加する
/DATA    192.168.1.0/24(rw,async)    ; アクセスできる範囲(読み書き可, 非同期書き込み)

 次のコマンドで設定を反映させます.

# /sbin/exports -ra

 設定が反映されているかどうかを確認します.

# /sbin/exports -v
/DATA       	192.168.1.0/24(async,wdelay,hide, ...

 マスターノードでファイアウォールにNFSの許可を与えます. (1-(b)で追加したリッチルールにより, 許可を与えなくても動作します. )

# firewall-cmd --permanent --zone=internal --add-service=nfs
success
# firewall-cmd --reload
success

 マスターノードでNFSサーバを起動させます. 自動起動も有効化しておきましょう.

# systemctl start nfs-server     # NFSサーバの起動
# systemctl enable nfs-server    # 自動起動の有効

(b) マウントする

 あとは, 各スレーブノードで設定を行い, マウントしていきます.

 スレーブノードでマウントポイントを作成します.

# mkdir /DATA

 スレーブノードで/etc/fstabファイルを編集し, マウントの設定を行います.

/etc/fstab
; 次の1行を追加する
ALMA01:/DATA    /DATA    nfs    defaults,hard,intr,noauto    0    0

 準備が整いました. マウントを実行します.(エラーが出なければOKです. )

# mount /DATA

3. mpirun を実行する

 それでは, 実際に並列計算を行ってみます.

 今回はmpichを使用します. 全ノードでインストールしてください.

# dnf install -y mpich mpich-devel

 マスターノードでmpichのパスを通します. パスの永続化については, 使用しているシェルに合わせて各自で行ってください. (次のコマンドは, 一時的にパスを通す例です. )

$ export PATH=$PATH:/usr/lib64/mpich/bin    # bashの場合
$ set path=($path /usr/lib64/mpich/bin)     # tcshの場合

 以上で, マウント済みのディレクトリ内でMPIが実行可能です. cdコマンドで移動します.

$ cd /DATA

 例えば, /DATAディレクトリ内に, 次のようなsample.cを作成します.

/DATA/sample.c
#include <stdio.h>
#include <mpi.h>

int main(int argc, char *argv[]) {
  int rank;                 // ランク
  int name_length = 32;     // ホスト名の長さ
  char name[name_length];   // ホスト名

  MPI_Init(&argc, &argv);                      // MPIの初期化
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);        // ランクの取得
  MPI_Get_processor_name(name, &name_length);  // ホスト名の取得

  printf("Hello world from %s! Rank is %d.\n", name, rank);

  MPI_Finalize();                              // MPIの終了
  return 0;
}

 実行には, ホストファイルが必要になります. /DATAディレクトリ内にhostsファイルを準備してください. ファイル名は自由です.

/DATA/hosts
; 計算資源として利用するノードを記述する
ALMA01
ALMA02
...
ALMA08

 mpiccコマンドを用いて, コンパイルします.

$ mpicc smaple.c

 実行してみましょう. ファイアウォールやSSHの設定上, マスターノードでのみ実行可能です.

$ mpirun --hostfile hosts -n 8 ./a.out
Hello world from ALMA01! Rank is 0.
Hello world from ALMA07! Rank is 6.
Hello world from ALMA06! Rank is 5.
Hello world from ALMA05! Rank is 4.
Hello world from ALMA04! Rank is 3.
Hello world from ALMA03! Rank is 2.
Hello world from ALMA08! Rank is 7.
Hello world from ALMA02! Rank is 1.

 /DATA/hostsファイルの内容や, -n 8の値を変化させて実行してみましょう.

4. 応用例

 分散システムを用いて数値計算を行うとき, 境界データのやり取りが必要になるため, n対nのデータ通信を行いながらMPIを進める必要があります. ここでは, 上記環境に加えて必要な手順を示します.

(a) プライベートネットワーク内のセキュリティを無効化する

 閉じたネットワークであるため, 面倒な設定を省いてセキュリティを無効化します.(または, 1-(b)を参考にリッチルールを追加することで解決します. )

 スレーブノードのファイアウォールを停止します. 自動起動も無効化しておきましょう.

# systemctl stop firewalld       # ファイアウォールの停止
# systemctl disable firewalld    # 自動起動の無効

(b) 互いにパスフレーズなしのSSHで接続する

 n対nのMPI通信では, 各ノードが互いにパスフレーズなしのSSHで接続できる必要があります. そこで, 1-(c)を参考に, どのノード間でも移動できるように鍵を渡します.

 スレーブノードで以下のコマンドを実行します. なお, 接続先に自分自身を含める必要はありません.

$ ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa      # 鍵の生成
$ ssh-copy-id -i ~/.ssh/id_rsa.pub user@ALMA01  # ユーザー名@接続先
$ ssh-copy-id -i ~/.ssh/id_rsa.pub user@ALMA02
    ...
$ ssh-copy-id -i ~/.ssh/id_rsa.pub user@ALMA08

 
 以上で, n対nのデータ通信のほか, どのノードからでも実行可能になります.

まとめ

 本記事では, 複数台のAlmaLinuxを用いて, 並列計算を行うための環境構築を行いました. 本記事がネットワーク技術のハンズオン教材となれば幸いです.

 最後まで読んでいただきありがとうございました!

参考文献

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?