Linux で計算機クラスタを作る (1. ネットワーク構築)

必要に迫られて計算機クラスタを作ったのでその手順を解説します。

# 何を作ったのか

うちの研究室では高性能なCPU/GPU を搭載したマシンを数台所有しており、使いたい人に配って個別管理してもらっていたのですが、このたび使いたい人が増加し、話し合って融通するのも面倒なので、ジョブ管理システムを備えたクラスタを構築することにしました。あくまで稼働率向上のためのクラスタ化なので、ノード間並列機能は備えておりません。

本記事は「ユーザーとしての Linux の操作にはひと通り慣れたけど、ネットワークの詳しい知識は持ってない」という人を対象に書いています。つまり僕くらいの人です。詳しい人から見ればところどころ勘違いがあると思いますがご了承願います。

# 環境

* OS: Ubuntu Server 14.04
* Network: Gigabit Ethernet
* ジョブ管理: Torque

サーバー用途としては CentOS のほうが直感的で使いやすい気がするのですが、Ubuntu だと一番面倒な Torque が apt-get で取れるというだけの理由で Ubuntu にしました。Ubuntu Server とはあまり耳慣れないと思いますが要は GUI のない Ubuntu です。

# 手順
長くなるので複数記事に分割します。

1. ネットワーク構築 (本記事)
2. 分散ファイルシステム NFS 導入
3. ユーザー情報共有システム NIS 導入
4. ジョブ管理システム Torque 導入編

# ネットワーク構築 (ハードウェア)

上述した理由で今回のクラスタはさほどノード[^node]間の通信速度が求められないため、Gigabit Ethernet を使います[^GiE] 。ノード間並列など通信を頻繁に行う場合は InfiniBand などの高価なネットワークを使う場合があるそうですが詳しくは知りません。

[^node]: クラスタに組み込まれるコンピュータのことだと思ってください。
[^GiE]: 普通の有線LANのことだと思って差し支え無いです。ただし古い LAN ケーブルや LAN カードでは Gigabit に対応していない場合があるので確認が必要です。

構築するクラスタ名を「**Futon**」とします。

下図のようにノードを接続します。ユーザーが直接ログインするノードを1台用意し、これをヘッドノードと呼びます。その先に、実際に計算を行う複数のノードを接続し、これらを計算ノードと呼びます。この仲介をするのが Switch[^switch] です。
![futon.png](https://qiita-image-store.s3.amazonaws.com/0/40166/d362081b-5c23-3bbd-f8f4-ce7e2744d4aa.png)

ヘッドノードは、クラスタ内部と外部につなぐため2個のNIC (LANカード) を必要とします。通常のコンピュータは1個しか付いてないので買い足しましょう。

# ネットワーク構築 (ソフトウェア)

まずヘッドノードにOSをインストールします。今回は Ubuntu Server 14.04 を使いました。

次にIPアドレスを設定します。ヘッドノードには外向きと内向きの2個のIPを設定する必要があります。今回は外向きが 10.1.1.x, 内向きが 192.168.2.x であるとします。まず

```
[FutonHead]$ ifconfig
```

とすることで、搭載されているネットワークインターフェースが確認できます。p134p1 および p135p1 という2個の NIC が接続され、それぞれ外向き、内向きに使うとします。Ubuntu では IP アドレスは /etc/network/interfaces というファイルに設定します。

```bash:/etc/network/interfaces
# 外向き
auto p134p1
iface p134p1 inet static
        address 10.1.1.128
        netmask 255.255.255.0
        network 10.1.1.0
        broadcast 10.1.1.255
        gateway 10.1.1.XXX
        dns-nameservers 8.8.8.8

# 内向き
auto p135p1
iface p135p1 inet static
        address 192.168.2.200
        netmask 255.255.255.0
        network 192.168.2.0
        broadcast 192.168.2.255
```

こんな感じになります。gateway については外部ネットワークの管理者に聞いて適切な IP を指定してください。ファイル編集後にネットワークを再起動し、

```
[FutonHead]$ ping google.com
```

などと入力してインターネットにつながること・DNSが機能していることを確認します。

次に計算ノードにも OS をインストールし /etc/network/interfaces を編集します。こちらは NIC が1個ですが、その名前が em1 だったとします。

```bash:/etc/network/interfaces
auto em1
iface em1 inet static
        address 192.168.2.1
        netmask 255.255.255.0
        network 192.168.2.0
        broadcast 192.168.2.255
        gateway 192.168.2.200
        dns-nameservers 8.8.8.8
```

address の部分はノードごとに違うのでそれぞれ適切な番号を指定してください。これでネットワークを再起動します。この時点で

```
[Futon01]$ ping 192.168.2.200
```

は通ると思いますが

```
[Futon01]$ ping google.com
```

は通らないと思います。つまりクラスタ内のネットワークにはつながるけどインターネットにはつながらないという状態です。これでは不便なので、計算ノードから直接インターネットにアクセスできるように **IPフォワーディング** および **IPマスカレード** を設定します。


## IPフォワーディング

ヘッドノードに戻り `/etc/sysctl.conf` というファイルを開きます。`# net.ipv4.ip_forward=1` となっている行を探し、コメントを外します。 

```bash:/etc/sysctl.conf
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1
```

これで計算ノードからヘッドノードに来たパケットを、インターネットに向けて再送できるようになります。

## IPマスカレード

```
[FutonHead]$ sudo iptables -t nat -A POSTROUTING -s 192.168.2.0/255.255.255.0 -j MASQUERADE
```

とします。これでクラスタ内ネットワーク 192.168.2.x のパケットに対しIPマスカレードが適用されるようになります。ただしこの設定は一時的なものなので、恒久的にマスカレードが通るように以下のように設定ファイルを出力します。

```
$ sudo iptables-save -c > iptables.rules
$ sudo mv iptables.rules /etc/iptables.rules
```

```bash:iptables.rules
# Generated by iptables-save v1.4.21 on Mon Nov  9 16:23:08 2015
*nat
:PREROUTING ACCEPT [6:1004]
:INPUT ACCEPT [6:1004]
:OUTPUT ACCEPT [1:128]
:POSTROUTING ACCEPT [1:128]
[0:0] -A POSTROUTING -s 192.168.2.0/24 -j MASQUERADE
COMMIT
# Completed on Mon Nov  9 16:23:08 2015
```

出力されたファイルを `/etc/iptables.rules` に移動し、そのファイルを起動時に読み込むようにします。

```
[FutonHead]$ sudo mv iptables.rules /etc/iptables.rules
$ sudo vim /etc/network/if-pre-up.d/iptables-restore
```

```bash:iptables-restore
#!/bin/bash
/sbin/iptables-restore < /etc/iptables.rules
exit 0
```

```
[FutonHead]$ sudo chmod 755 iptables-restore
```

これでマスカレードが設定されました。

以上の設定が終わったら、計算ノード側で

```
[Futon01]$ ping google.com
```

として、インターネットに接続できることを確認してください。

# /etc/hosts の設定

以上の設定が終わったら、各ノードの `/etc/hosts` にIPとノード名を紐付けしておきましょう。これが後々必要になります。

```bash:/etc/hosts
127.0.0.1       localhost
10.1.1.128      FutonHead
192.168.2.200   FutonHead FutonHead.nis
192.168.2.1     Futon01
192.168.2.2     Futon02
...

```

とりあえずこれでネットワーク周りの設定は完了です。次にストレージを共有するための NFS を設定します。（つづく）

`FutonHead.nis` というのは後々入れる nis のために書いています。


[^switch]: 「ルーター」「ハブ」「スイッチ」は機能が微妙に違います。今回使うのはスイッチです。