ことはじめ
HPCの研究室に所属している割にはHPCっぽいことができていなくて不満なので、自分でHPCぽいことをやることにした。自分のいう「HPCぽさ」ってのは、大規模なデータ分析とか難しい処理を複数ノードを使って効率よくやることとか、まあとりあえずクラスタが好きなんすよ。
ってことでとりあえず手始めにラズパイでHadoopクラスタを構築する。その後kubernetesクラスタや、slurmクラスタも試してみる。 やることは全部で5つある。3つめと4つ目ははHadoopクラスタの構築のためではなく、MPIを使った実行も可能にするためである。勉強にはなる。
1. ラズパイのルータ化
2. クラスタネットワークに属しているノードのIPアドレスを固定
3. ノード間をシームレスで移動できるようにkeychain loginを追加
4. nfsを使ってノード間で共有ディレクトリを作る
5. hadoopの導入
ラズパイのルータ化(やることその1)
大元のLanにはsoftbankのルータを使っているが、このネットワークにラズパイクラスタを置きたくない。なので、ラズパイ一台をルータ兼マスターノードにして新しいネットワーク(172.20.2.0/24)を構築する。
ネットワークの構成
192.168.3.0/24がメインのネットワークで、この中にルータ兼マスターノードをつくる。マスターノードは2つのnicを持つが、 192.168.3.0/24側は、192.168.3.4 新しいネットワーク側(172.20.2.0/24)は172.20.2.1。 そして172.20.2.0/24の中にラズパイクラスタをいっぱい配置する。
必要な道具
ラズパイはether net ポートが1つしかない。そのためラズパイで外部からアクセス可能なLanを作るためにはもう一つ物理的なLanポートが必要になる。これには usb -> ether net変換アダプタを使う。 ifconfigの結果は次のような感じになる。 eth0がもとからついているポートでeth1が追加されたやつ。
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.3.4 netmask 255.255.255.0 broadcast 192.168.3.255
inet6 fe80::dea6:32ff:fefa:54df prefixlen 64 scopeid 0x20<link>
inet6 2400:2413:121:fd00:dea6:32ff:fefa:54df prefixlen 64 scopeid 0x0<global>
ether dc:a6:32:fa:54:df txqueuelen 1000 (Ethernet)
RX packets 841 bytes 96345 (96.3 KB)
RX errors 0 dropped 281 overruns 0 frame 0
TX packets 472 bytes 90115 (90.1 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth1: flags=4098<BROADCAST,MULTICAST> mtu 1500
ether 18:c2:bf:e9:3b:8d txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth0がメインネットワーク側。eth1がクラスタネットワーク側。以下、新しいネットワークを作るための設定
ipフォワーディングの有効化
/etc/sysctl.conf
#...中略
net.ipv4.ip_forward=1
#...以下略
設定の反映
sudo sysctl -p
eth1(cluster network)を固定する。
/etc/dhcpcd.conf
interface eth1
static ip_address=172.20.2.1/24
static routers=0.0.0.0
static domain_name_servers=0.0.0.0
DHCPサーバの導入
sudo apt install -y isc-dhcp-server
dhcpサーバの設定
/etc/dhcp/dhcpd.confにおいて、
#...中略
#コメントアウト
#option domain-name "example.org";
#コメントアウト
#option domain-name-servers ns1.example.org, ns2.example.org;
#有効化
authoritative;
#追記
subnet 172.20.2.0 netmask 255.255.255.0 {
range 172.20.2.2 172.20.2.99;
option routers 172.20.2.1;
option domain-name-servers 172.20.2.1;
option broadcast-address 172.20.2.255;
ignore declines;
}
/etc/default/isc-dhcp-server
#...中略
#ターゲットインターフェイスを指定
INTERFACESv4="eth1"
#...略
dhcp serverのデーモン化
sudo systemctl start isc-dhcp-server
sudo systemctl enable isc-dhcp-server
注意:3回目のクラスタ構築の時に、何回やってもisc-dhcp-serverが起動しなかったんだよね。マジでなんでや?ってずっと思ってたんだけど、どうやらethernetではethernetケーブルが接続されてから初めて、nicがオンになるみたいで。つまり、イーサネットケーブルをlanポートに指したらうまくいきます。 ifconfig でもちゃんとeth0に192.168.3.1が割り当てられました。
iptablesコマンドでeth1とeth0のパケットフォワーディニングを有効化させる。これがいわゆるNATだね。
iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
iptables -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
以上の設定を /etc/rc.local に書き込んでマスターノードが再起動されても設定が反映されるようにする。ちなみにrc.localは
Linuxが起動する過程で実行されるシェルスクリプト
スレーブノード側でnicの情報を/etc/network/interfacesに書き込んでipを固定などする(やることその2)
auto eth0
allow-hotplug eth0
iface eth0 inet static
address 172.20.2.10
netmask 255.255.255.0
gateway 172.20.2.1
dns-nameservers 8.8.8.8
以上でipアドレスも固定される。
新たに得られた知見
dhcpサーバが管理しているネットワーク内でも/etc/network/interfacesにipアドレスを書き込むとstatic ipになる。
参考にしたサイト
これ めちゃめちゃ詳しく書いてある。
まず大事な概念としてnicがあるよね。network interfce card。文字通りネットワークのインターフェース。
ifconfig
でデバイスに存在するnicの一覧が見られる。仮想的なnicも存在する。
マスターノードからスレーブノードへの移動をシームレスにする
ssh-keygen -t rsa
このコマンドで秘密鍵と公開鍵のペアができる。
ssh-copy-id username@ip_address
で作った公開鍵を任意のホストに任意のユーザの ./ssh/authorized_keysに転送できる。 以後、公開鍵を持っているホストにsshするときはパスワードではなく鍵のパスフレーズでログインできるようになる。 (ちなみに、ここでパスフレーズをなしにすると、パスフレーズも打たなくてよくなるので、以下の設定が無駄になる) しかし、パスフレーズを打つのも面倒な人向けに、いいコマンドがある
sudo apt-get install keychain
でインストールし、
.bashrcに次のスクリプトを追記
# Logic for keychain
/usr/bin/keychain $HOME/.ssh/id_rsa
source $HOME/.keychain/$HOSTNAME-sh
これは、内部的には ssh-addで秘密鍵とパスフレーズを登録し、ssh-agentが自動でパスフレーズを入力してくれているだけ。
マスターノードにスレーブノードからマウント可能なディレクトリを作る
これは学ぶことが多いですね。 まあ、かんたんに言うと、nfsがかんたんに作れるんですよって話。はい。なんかわざわざnfsとか買っている人いるけど、実はnfsって 知識さえあれば誰でも作れるんだよね。これは驚きだよね。まあ、先に進みましょう。
- 必要なツールのインストール
sudo apt-get install nfs-common nfs-kernel-server
- エクスポートディレクトリの作成
sudo mkdir /cluster_common
- エクスポートディレクトリをnfs-kernel-serverに知らせるため、/etc/exportsを編集 の前に、sudo systemctl enable rpcbind
をしておくこと!!いや、最近はいらないらしい。というのもrpcは脆弱性が見つかっているらしくてね。 まあ参考文献は
# 中略
# cluster_common
/cluster_common 172.20.2.0/24(rw,sync)
- nfs-kernel-serverのデーモン化&リスタート
sudo systemctl enable nfs-kernel-server
sudo systemctl reload nfs-kernel-server
- ファイアウォールが有効化されている場合は、nfs用のポート(2049)を開ける
sudo ufw allow nfs
sudo ufw reload
- スレーブノード側でエクスポートされたディレクトリをマウントする(のまえに、スレーブ側でもマウントポイント作ってね)
sudo mount 172.20.2.1:/cluster_common /cluster_common
- 自動マウントのため,fstabファイルを編集する必要がある。
172.20.2.1:/cluster_common /cluster_common nfs defaults,rw,exec 0 0: