作れるの?
作れます。
経緯的なものを書くと、学生の頃下のRaspberry piで作ってる記事を読んだのがきっかけでした。
RaspberryPiでスパコンを作ろう
今見るとCPUのクロック数700MHzの頃ですね・・・
より高性能になったのとラズパイ自体の値段が上がってしまいちょっと手が出しずらくなっていました。
ところが、とあるところでこんなものが出てきました。
AMDチップ搭載のシンクライアント端末「t420 Thin Client」が1,500円!中古品セール
最初はシンクライアント端末でも作ろうかと、思ってたんですがこれは好機だなとということで、
合計で22台買ってきてしまいました・・・(内1台は物理的なLinux環境として使ってます)
PCコンフル店員さん変な人来たなと思ってただろうな・・・
スペック的なことを書くとHP t420 Thin Clientのスペックはこんな感じ
CPU:AMD GX-209JA
メモリー:2GB
有線LAN:1000BASE-T/100BASE-TX/10BASE-T
ちなみに仮想化技術も組み込み向けのCPUながら有効にできます。
CPUの詳細スペックは下のページにある(多分これ)
AMD G-Series GX-209HA Embedded processor - GE209HISJ23HM
今回はOSとしてはノードはUbuntuServerを使用して、管理系にはRaspberrypi 4で管理します。
注意点
CPUアーキテクチャは揃えよう
最初Raspberrpiでプログラムをコンパイルして配下のノードに計算させるつもりでいましたが、
実際に構築してテストプログラムをノードに投げたところ、実行できない事態が発生しました。
クロスコンパイラでやろうと思ったのですが、クロスコンパイラはやめたほうがいい記事を見つけコンパイル用のノードマシンを作成することになりました。
LANケーブルも揃えよう
LANケーブルのカテゴリーも揃えましょう。
今回はカテ6で全部揃えてます
セットアップ台数が多いとめちゃくちゃ大変
デプロイシェルとかあると楽になります。
できる人はAnsibleでやってしまってもいいかも。
今回は一例でセットアップシェルを載せておきます。
システムの構成
各役割
-
RaspberryPi:nihonkaihaed
ルータ機能を持たせている。
管理機能としてCockpitとPrometheus+Grafanaで監視と管理を持たせて、
ジョブの投入はこのマシンから行う.
各ノードへのSSHもここから行う。 -
コンパイル用のNord:nihokai-nordmaster
OpenMPIのプログラムをコンパイルするユニット -
NordUnit:nihonkai-nordunitxx
計算用のUnit
やること
最低限やることとして必要なことは以下の通り
- hostsの記載
IPでもできますが、ホスト名でできた方が楽 - SSHの公開鍵認証
これはRaspberrypiとNordUnit間で相互で鍵が必要です。 - NFSサーバの作成
コンパイルファイルやソースコードを格納するのに必要 - OpenMPIのインストール
上の作業がないとできないです。
環境によってやらなくてもいいこと
-
ルータの作成
これはネットワークの分離が必要な場合にやる -
CockPitとPrometheus+Grafanaで監視と管理
できればやった方が管理としては楽 -
OpenLDAP
場合によっては必要かもしれないが自分の場合は特に必要なかった -
WOLの設定
さすがにすべて手作業スイッチ入れるのは面倒なので有効にした
ルータ作成
過去自分の記事をもとに作成。
addr d8:3a:dd:17:d5:04
iw phy phy0 interface add ap0 type __ap
ip link set ap0 address ff:ff:ff:ff:ff:ff
vim /etc/udev/rules.d/99-ap0.rules
SUBSYSTEM=="ieee80211", ACTION=="add|change", ATTR{macaddress}=="d8:3a:dd:17:d5:04", KERNEL=="phy0", \
RUN+="/sbin/iw phy phy0 interface add ap0 type __ap", \
RUN+="/bin/ip link set ap0 address ff:ff:ff:ff:ff:ff"
Nord側のインターフェース
4: eth1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
link/ether ac:15:a2:80:cb:a9 brd ff:ff:ff:ff:ff:ff
# DHCPサーバ設定(dnsmasq)
vim /etc/dnsmasq.conf
# eth1設定(USBNIC)
# クラスター計算機側
# IPのレンジ 192.168.1.10 ~ 192.168.1.110
# サブネット 255.255.255.0 (/24)
interface=eth1
dhcp-range=192.168.1.10,192.168.1.110,255.255.255.0,12h
# ap0設定(WiFIの設定だがほぼダミー設定)
# IPのレンジ 192.168.11.10 ~ 192.168.11.110
# サブネット 255.255.255.0 (/24)
interface=ap0
dhcp-range=192.168.11.10,192.168.11.110,255.255.255.0,12h
vim /etc/dhcpcd.conf
# DHCPクライアント設定 eth1
# クラスター計算機側
# nohook wpa_supplicantオプション有効
# IPv6拒否設定有効
# eth1のIPは192.168.1.1/24
interface eth1
static ip_address=192.168.1.1/24
nohook wpa_supplicant
noipv6
# DHCPクライアント設定 Wi-Fi
# ap0のIPは192.168.11.1/24
# こっちにもIPv6拒否設定入れておく
interface ap0
static ip_address=192.168.11.1/24
nohook wpa_supplicant
noipv6
vim /etc/hostapd/hostapd.conf
ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
interface=ap0
driver=nl80211
ssid=nihonkai
hw_mode=g
country_code=JP
channel=11
ieee80211d=1
wmm_enabled=0
macaddr_acl=0
auth_algs=1
wpa=2
wpa_passphrase=XXXXX
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 ! -d 192.168.1.0/24 -j MASQUERADE
iptables -t nat -A POSTROUTING -s 192.168.11.0/24 ! -d 192.168.11.0/24 -j MASQUERADE
hostsの設定
SSHやOpneMPIのホストファイルの作成の時楽になります。
書き方とかは他の方の記事を参考にしてください。
今回の場合こんな感じ(10台分)
root@nihonkaihaed:/shere# cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
127.0.1.1 nihonkaihaed
192.168.1.1 nihonkaihaed
192.168.1.50 nihonkai-nordmaster
192.168.1.11 nihonkai-nordunit1
192.168.1.12 nihonkai-nordunit2
192.168.1.13 nihonkai-nordunit3
192.168.1.14 nihonkai-nordunit4
192.168.1.15 nihonkai-nordunit5
192.168.1.16 nihonkai-nordunit6
192.168.1.17 nihonkai-nordunit7
192.168.1.18 nihonkai-nordunit8
root@nihonkaihaed:/shere#
SSHの設定
sshd.configの設定は、rootログイン許可とパスワード認証と鍵認証を有効にするぐらい
# 抜粋
PermitRootLogin yes
PubkeyAuthentication yes
鍵作成と鍵交換はこんな感じで実施する
# sshの鍵作成
keyname=`uname -n`
ssh-keygen
cat ~/.ssh/$keyname.key >> ~/.ssh/authorized_keys
scp -p /root/.ssh/$keyname.key root@192.168.1.1:/root/.ssh
ssh-copy-id -i ~/.ssh/$keyname.key.pub root@nihonkaihaed
# haedUnitの鍵転送
ssh-copy-id -i /root/.ssh/headkey.pub $1
scp -p /root/.ssh/headkey root@$1:/root/.ssh
# haedUnitへの接続の.ssh/config作成(NordUnit側)
cat <<EOF > /root/.ssh/config
Host nihonkaihaed
HostName nihonkaihaed
User root
IdentityFile ~/.ssh/headkey
StrictHostKeyChecking no
EOF
haedUnitの接続の.ssh/configはこんな感じ
Host nihonkaihead
HostName nihonkaihaed
User root
IdentityFile ~/.ssh/headkey
StrictHostKeyChecking no
Host nihonkai-nordunit1
HostName nihonkai-nordunit1
User root
IdentityFile ~/.ssh/nihonkai-nordunit1.key
StrictHostKeyChecking no
Host nihonkai-nordunit2
HostName nihonkai-nordunit2
User root
IdentityFile ~/.ssh/nihonkai-nordunit2.key
StrictHostKeyChecking no
Host nihonkai-nordunit3
HostName nihonkai-nordunit3
User root
IdentityFile ~/.ssh/nihonkai-nordunit3.key
StrictHostKeyChecking no
Host nihonkai-nordunit4
HostName nihonkai-nordunit1
User root
IdentityFile ~/.ssh/nihonkai-nordunit1.key
StrictHostKeyChecking no
Host nihonkai-nordunit5
HostName nihonkai-nordunit5
User root
IdentityFile ~/.ssh/nihonkai-nordunit5.key
StrictHostKeyChecking no
Host nihonkai-nordunit6
HostName nihonkai-nordunit6
User root
IdentityFile ~/.ssh/nihonkai-nordunit6.key
StrictHostKeyChecking no
Host nihonkai-nordunit7
HostName nihonkai-nordunit7
User root
IdentityFile ~/.ssh/nihonkai-nordunit7.key
StrictHostKeyChecking no
Host nihonkai-nordunit8
HostName nihonkai-nordunit8
User root
IdentityFile ~/.ssh/nihonkai-nordunit8.key
StrictHostKeyChecking no
必要なソフトウエアのインストールとセットアップ
cockpit
apt -y install cockpit
systemctl enable cockpit.socket
prometheus prometheus-node-exporter
apt -y install prometheus prometheus-node-exporter
wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -
echo "deb https://packages.grafana.com/oss/deb stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.liapt-get install -y grafanast
apt install -y grafana
systemctl enable grafana-server
PrometheusとCockpitを共存させる場合でPrometheus側のポートを9090から9093に変更する場合は以下のように変更する
vi /lib/systemd/system/prometheus.service
[Unit]
Description=Monitoring system and time series database
Documentation=https://prometheus.io/docs/introduction/overview/ man:prometheus(1)
After=time-sync.target
[Service]
Restart=on-failure
User=prometheus
EnvironmentFile=/etc/default/prometheus
# 元あるExecStartはコメントアウトさせる
# ExecStart=/usr/bin/prometheus $ARGS
# 下記のExecStartに変更する
ExecStart=/usr/bin/prometheus --config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/var/lib/prometheus/data --web.listen-address=:9093
ExecReload=/bin/kill -HUP $MAINPID
TimeoutStopSec=20s
SendSIGKILL=no
# systemd hardening-options
AmbientCapabilities=
CapabilityBoundingSet=
DeviceAllow=/dev/null rw
DevicePolicy=strict
LimitMEMLOCK=0
LimitNOFILE=32768
LockPersonality=true
MemoryDenyWriteExecute=true
NoNewPrivileges=true
PrivateDevices=true
PrivateTmp=true
PrivateUsers=true
ProtectControlGroups=true
ProtectHome=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectSystem=full
RemoveIPC=true
RestrictNamespaces=true
RestrictRealtime=true
SystemCallArchitectures=native
[Install]
WantedBy=multi-user.target
/etc/prometheus/prometheus.ymlも変更箇所あり
root@nihonkaihaed:~# cat /etc/prometheus/prometheus.yml
# Sample config for Prometheus.
global:
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
# scrape_timeout is set to the global default (10s).
# Attach these labels to any time series or alerts when communicating with
# external systems (federation, remote storage, Alertmanager).
external_labels:
monitor: 'example'
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets: ['localhost:9093']
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
# - "first_rules.yml"
# - "second_rules.yml"
# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
# The job name is added as a label job=<job_name> to any timeseries scraped from this config.
- job_name: 'prometheus'
# Override the global default and scrape targets from this job every 5 seconds.
scrape_interval: 5s
scrape_timeout: 5s
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
# ここのポート番号は9090となっているので9093に変更する
static_configs:
- targets: ['localhost:9093']
- job_name: node
# If prometheus-node-exporter is installed, grab stats about the local
# machine by default.
static_configs:
- targets: ['localhost:9100']
systemctl daemon-reload
systemctl restart prometheus
prometheus-node-exporter
apt -y install prometheus-node-exporter
監視ノード追加
vi /etc/prometheus/prometheus.yml
- job_name: NihonKai-NordUnit1
static_configs:
- targets: ['nihonkai-nordunit1:9100', 'nihonkai-nordunit2:9100', 'nihonkai-nordunit3:9100', 'nihonkai-nordunit4:9100', 'nihonkai-nordunit5:9100', 'nihonkai-nordunit6:9100', 'nihonkai-nordunit7:9100', 'nihonkai-nordunit8:9100']
systemctl restart prometheus
systemctl status prometheus
systemctl start grafana-server
NFSサーバ設定
必ずNordUnitからファイル作成実行ができるようにするのと、
共有ディレクトリはサーバーとNordUnitで必ず一致させる必要がある。
apt -y install nfs-kernel-server
vi /etc/exports
# 読み書きのほか、サブツリーのチェックを無効とし、root を anonymous UID/GID にマッピングしない
/shere 192.168.1.0/255.255.255.0(rw,async,no_subtree_check,no_root_squash)
mkdir /shere
systemctl restart nfs-server
NFSマウント
上で書いた通り、共有ディレクトリはサーバーとNordUnitで必ず一致させる必要がある。
apt -y install nfs-common
mkdir /shere
df -Th
echo "192.168.1.1:/shere /shere nfs defaults 0 0" >> /etc/fstab
tail /etc/fstab
mount -t nfs 192.168.1.1:/shere /shere
df -Th
OpenLDAPサーバ設定
こちらはほぼメモ
LADP
vi /root/ldap.conf/add_ou.ldif
dn: ou=people,dc=nihonkai,dc=local
objectClass: organizationalUnit
ou: people
dn: ou=groups,dc=nihonkai,dc=local
objectClass: organizationalUnit
ou: groups
ldapadd -x -D cn=admin,dc=nihonkai,dc=local -W -f add_ou.ldif
{SSHA}7+EBN1NjmRN08tJsevsyBoCwlTbIgoM+
ldap.conf# ldapadd -x -D cn=admin,dc=nihonkai,dc=local -W -f add_u11000.ldif
vi /root/ldap.conf/add_u11000.ldif
dn: cn=u11000,ou=groups,dc=nihonkai,dc=local
objectClass: posixGroup
cn: u11000
gidNumber: 11000
dn: uid=u11000,ou=people,dc=nihonkai,dc=local
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
cn: Nord Kanri
sn: Nord
displayName: Nord Kanri
givenName: Kanri
title: NordUser
uid: u11000
userPassword: {SSHA}7+EBN1NjmRN08tJsevsyBoCwlTbIgoM+
gidNumber: 11000
homeDirectory: /home/u11000
uidNumber: 11000
gecos: Nord Kanri
loginShell: /bin/bash
shadowExpire: -1
shadowInactive: 99999
shadowMax: 99999
shadowMin: 0
shadowWarning: 14
ldapsearch -x -LLL -D cn=admin,dc=nihonkai,dc=local -b dc=nihonkai,dc=local -W
OpneLDAPのクライアント
mkdir /home/u11000
apt -y install libnss-ldapd libpam-ldapd ldap-utils
su - u11000 -c "who"
Openmpi
apt -y install openmpi-bin libopenmpi-dev
mpicc -v
WOL
apt -y install ethtool
# 受け付ける側の設定としては以下の通り
BIOS、UEFI側でWOLに関する機能を有効にする
ethtool enp1s0 | grep "Wake-on" # dとなっていること
vi /etc/netplan/00-installer-config.yaml
# This is the network config written by 'subiquity'
network:
ethernets:
enp1s0: # NIC名の下に記載する
wakeonlan: true
addresses:
- 192.168.1.50/24
nameservers:
addresses:
- 192.168.1.1
search: []
routes:
- to: default
via: 192.168.1.1
version: 2
netplan apply
ethtool enp1s0 | grep "Wake-on" # gとなっていること
OpneMPIでのコンパイルと実行
ここまで来たらOpneMPIでプログラムをコンパイルして実行ができます。
プログラムを作成する際はNFSのディレクトリで作成します
#include <stdio.h>
#include "mpi.h"
int main( int argc, char *argv[] )
{
int rank, size, len;
char name[MPI_MAX_PROCESSOR_NAME];
MPI_Init( &argc, &argv );
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
MPI_Comm_size( MPI_COMM_WORLD, &size );
MPI_Get_processor_name( name, &len );
name[len] = '\0';
printf( "Hello world: rank %d of %d running on %s\n", rank, size, name );
MPI_Finalize();
return 0;
}
上のファイルができたらコンパイルして実行しましょう。
mpicc -o hello hello.c
mpirun --allow-run-as-root -n 2 ./hello
ホストファイルを作成しての実行は下のようにする
vi host1-8
nihonkai-nordunit1 slots=2
nihonkai-nordunit2 slots=2
nihonkai-nordunit3 slots=2
nihonkai-nordunit4 slots=2
nihonkai-nordunit5 slots=2
nihonkai-nordunit6 slots=2
nihonkai-nordunit7 slots=2
nihonkai-nordunit8 slots=2
mpirun --allow-run-as-root -n 8 --hostfile host1-8 ./hello
これで作成して実行できたら完了になります。
セットアップシェル例
#! /bin/bash
# 初期のアップデート
# do-release-upgradeで再起動が走るのでこのシェルは簡単にここまで
apt update -y && apt upgrade -y
apt autoremove
do-release-upgrade
#! /bin/bash
# 初期システム設定
# 日本語設定とhostsにホスト名追加
apt -y install language-pack-ja-base language-pack-ja
localectl set-locale LANG=ja_JP.UTF-8 LANGUAGE="ja_JP:ja"
source /etc/default/locale
echo $LANG
# タイムゾーンの修正
timedatectl set-timezone Asia/Tokyo
timedatectl
# hostsにホスト名追加
echo "192.168.1.1 nihonkaihaed" >> /etc/hosts
echo "192.168.1.50 nihonkai-nordmaster" >> /etc/hosts
echo "192.168.1.11 nihonkai-nordunit1" >> /etc/hosts
echo "192.168.1.12 nihonkai-nordunit2" >> /etc/hosts
echo "192.168.1.13 nihonkai-nordunit3" >> /etc/hosts
echo "192.168.1.14 nihonkai-nordunit4" >> /etc/hosts
echo "192.168.1.15 nihonkai-nordunit5" >> /etc/hosts
echo "192.168.1.16 nihonkai-nordunit6" >> /etc/hosts
echo "192.168.1.17 nihonkai-nordunit7" >> /etc/hosts
echo "192.168.1.18 nihonkai-nordunit8" >> /etc/hosts
cat /etc/hosts
#! /bin/bash
# sshの鍵作成
keyname=`uname -n`
ssh-keygen
cat ~/.ssh/$keyname.key >> ~/.ssh/authorized_keys
scp -p /root/.ssh/$keyname.key root@192.168.1.1:/root/.ssh
ssh-copy-id -i ~/.ssh/$keyname.key.pub root@nihonkaihaed
cat <<EOF > /root/.ssh/config
Host nihonkaihaed
HostName nihonkaihaed
User root
IdentityFile ~/.ssh/headkey
StrictHostKeyChecking no
EOF
#! /bin/bash
# haedUnitの鍵転送
ssh-copy-id -i /root/.ssh/headkey.pub $1
scp -p /root/.ssh/headkey root@$1:/root/.ssh
echo "Please ssh to $1"
echo "Add the following to your .ssh/config"
echo "Host $1"
echo " HostName $1"
echo " User root"
echo " IdentityFile ~/.ssh/$1.key"
echo " StrictHostKeyChecking no"
root@nihonkaihaed:/shere#
#! /bin/bash
# 必要なソフトウエアのインストールとセットアップ
# もしかしたら追加するかも
# cockpit
echo ""
echo "Install cockpit"
apt -y install cockpit
systemctl enable cockpit.socket
# prometheus-node-exporter
echo ""
echo "Install prometheus-node-exporter"
apt -y install prometheus-node-exporter
# NFSマウント
echo ""
echo "NFS Utils"
apt -y install nfs-common
mkdir /shere
df -Th
echo "192.168.1.1:/shere /shere nfs defaults 0 0" >> /etc/fstab
tail /etc/fstab
mount -t nfs 192.168.1.1:/shere /shere
df -Th
# OpneLdap
echo ""
echo "Install OpenLdap Cliant"
echo "Ldap URI is 192.168.1.1 and dc=nihonkai,dc=local"
mkdir /home/u11000
apt -y install libnss-ldapd libpam-ldapd ldap-utils
su - u11000 -c "who"
# Openmpi
echo ""
echo "Install Opnempi"
apt -y install openmpi-bin libopenmpi-dev
mpicc -v
name=`uname -n`
echo ""
echo "Add the hostname to the prometheus Target section : $name"
echo "Please add this host to the cockpit on the HeadUnit side. : $name"
参考サイト
順不同
インストール時のIPアドレス固定方法
構築
カーネルパニック
dpkg --configure -aとapt update -y && apt upgrade -yやったら回避した
システムアップデート
WOL
NFS
キーペア接続
Prometheus Grafana構築
Ldap