kuroの覚え書き

96の個人的覚え書き

AlmaLinux8.7でサーバクラスタを構築する

さて、サーバ間でユーザとディレクトリを共有できるようになったので、次にジョブスケジューラを導入してサーバクラスタとしたい。
これまでCentOS7ではTORQUEを使ってきたのだが、どうも8系以降ではインストールができないらしい。有料のSGEという選択肢もあるが、今どきのスパコンでもTOP500でシェアを伸ばしているらしいSlurmを使うことにする。しかし日本語の情報はあまりないようだ。本家配布サイトのドキュメントは充実しているが、充実しすぎて難しい。とっつきにくい。

ヘッドノード:k1-inspur-a6
計算ノード:k2-inspur-a6, k3-inspur-a6

  • 共通ユーザーの準備とmunge keyの準備
[root@k1-inspur-a6 ~]# groupadd -g 5000 slurm
# useradd -M -d /var/lib/slurm -s /sbin/nologin -u 5000 -g slurm slurm
# groupadd -g 5001 munge
# useradd -M -d /var/lib/munge -s /bin/bash -u 5001 -g munge munge
# id munge
uid=5001(munge) gid=5001(munge) groups=5001(munge)
# id slurm
uid=5000(slurm) gid=5000(slurm) groups=5000(slurm)

# mkdir -p /var/lib/slurm
# mkdir -p /var/lib/slurm/spool
# mkdir -p /var/log/slurm
# chown -R slurm:slurm /var/lib/slurm
# chown -R slurm:slurm /var/log/slurm

# ssh -l root k2-inspur-a6 'mkdir -p /var/lib/slurm'
# ssh -l root k2-inspur-a6 'mkdir -p /var/lib/slurm/spool'
# ssh -l root k2-inspur-a6 'mkdir -p /var/log/slurm'
# ssh -l root k2-inspur-a6 'chown -R slurm:slurm /var/lib/slurm'
# ssh -l root k2-inspur-a6 'chown -R slurm:slurm /var/log/slurm'

#同じ操作をk3-inspur-a6でも行う

# mungeのインストール
# dnf install munge
・・・・
================================================================================
 パッケージ         Arch           バージョン           リポジトリー      サイズ
================================================================================
インストール:
 munge              x86_64         0.5.13-2.el8         appstream         121 k
依存関係のインストール:
 munge-libs         x86_64         0.5.13-2.el8         appstream          29 k
・・・・
## munge keyの生成
# /usr/sbin/create-munge-key 
Generating a pseudo-random key using /dev/urandom completed.

# systemctl enable --now munge.service
Created symlink /etc/systemd/system/multi-user.target.wants/munge.service → /usr/lib/systemd/system/munge.service.

## mungeを計算ノードにもインストール
# ssh -l root k2-inspur-a6 'dnf install munge -y'
・・・・
## munge keyを計算ノードにコピー
# scp /etc/munge/munge.key root@k2-inspur-a6:/etc/munge/munge.key
# ssh -l root k2-inspur-a6 'chown munge. /etc/munge/munge.key'

## 計算ノードでmungeを起動
# ssh -l root k2-inspur-a6 'systemctl enable --now munge'

Created symlink /etc/systemd/system/multi-user.target.wants/munge.service → /usr/lib/systemd/system/munge.service.

## 同じ操作をk3-inspur-a6でも行う
  • Slurmのインストール

PowerToolsリポジトリを有効化する必要がある。

# dnf config-manager --set-enabled powertools
# dnf repolist --all | grep PowerTools
powertools                     AlmaLinux 8 - PowerTools                   有効化
powertools-debuginfo           AlmaLinux 8 - PowerTools debuginfo         無効化
powertools-source              AlmaLinux 8 - PowerTools Source            無効化

## パッケージslurmはすべてのノードに必要
# dnf -y install slurm
・・・・
================================================================================
 パッケージ                   Arch     バージョン            リポジトリー サイズ
================================================================================
インストール:
 slurm                        x86_64   20.11.9-1.el8         epel         1.8 M
依存関係のインストール:
 Lmod                         x86_64   8.7.19-1.el8          epel         263 k
 freeipmi                     x86_64   1.6.8-1.el8           baseos       2.1 M
 hdf5                         x86_64   1.10.5-4.el8          epel         2.1 M
 hwloc-libs                   x86_64   2.2.0-3.el8           baseos       2.0 M
 infiniband-diags             x86_64   41.0-1.el8            baseos       322 k
 libaec                       x86_64   1.0.2-3.el8           powertools    39 k
 libgfortran                  x86_64   8.5.0-16.el8_7.alma   baseos       643 k
 libibumad                    x86_64   41.0-1.el8            baseos        32 k
 libjwt                       x86_64   1.12.1-7.el8          epel          28 k
 libquadmath                  x86_64   8.5.0-16.el8_7.alma   baseos       171 k
 lua-filesystem               x86_64   1.6.3-7.el8           powertools    35 k
 lua-posix                    x86_64   33.3.1-9.el8          powertools   176 k
 lua-term                     x86_64   0.07-9.el8            epel          16 k
 mariadb-connector-c          x86_64   3.1.11-2.el8_3        appstream    199 k
 mariadb-connector-c-config   noarch   3.1.11-2.el8_3        appstream     14 k
 munge                        x86_64   0.5.13-2.el8          appstream    121 k
 munge-libs                   x86_64   0.5.13-2.el8          appstream     29 k
 pmix                         x86_64   2.2.5-1.el8           appstream    739 k
 slurm-libs                   x86_64   20.11.9-1.el8         epel         1.0 M
 tcl                          x86_64   1:8.6.8-2.el8         baseos       1.1 M
・・・・
# ssh -l root k2-inspur-a6 'dnf install slurm -y'
# ssh -l root k3-inspur-a6 'dnf install slurm -y'

## 管理ノードにはslurm-slurmctldが必要
# dnf install slurm-slurmctld
・・・・
================================================================================
 パッケージ             Arch          バージョン              Repo        サイズ
================================================================================
インストール:
 slurm-slurmctld        x86_64        20.11.9-1.el8           epel        453 k
・・・・

## 計算ノードにはslurm-slurmdが必要
# dnf install slurm-slurmd
・・・・================================================================================
 パッケージ           Arch           バージョン              リポジトリー サイズ
================================================================================
インストール:
 slurm-slurmd         x86_64         20.11.9-1.el8           epel         196 k
・・・・

# ssh -l root k2-inspur-a6 'dnf install slurm-slurmd -y'
# ssh -l root k3-inspur-a6 'dnf install slurm-slurmd -y'

## 計算ノードにはslurm-pam_slurmも入れたほうがいい?
# dnf install slurm-pam_slurm
・・・・
================================================================================
 パッケージ             Arch          バージョン              Repo        サイズ
================================================================================
インストール:
 slurm-pam_slurm        x86_64        20.11.9-1.el8           epel         30 k
・・・・

# ssh -l root k2-inspur-a6 'dnf install slurm-pam_slurm -y'
# ssh -l root k3-inspur-a6 'dnf install slurm-pam_slurm -y'

## ジョブ投入ノードにはslurm-torque、slurm-openlavaを入れたほうがいい?
# dnf install slurm-torque
・・・・================================================================================
 パッケージ            Arch           バージョン             リポジトリー サイズ
================================================================================
インストール:
 slurm-torque          x86_64         20.11.9-1.el8          epel          67 k
依存関係のインストール:
 slurm-perlapi         x86_64         20.11.9-1.el8          epel         184 k
・・・・

# dnf install slurm-openlava
・・・・================================================================================
 パッケージ             Arch           バージョン            リポジトリー サイズ
================================================================================
インストール:
 slurm-openlava         x86_64         20.11.9-1.el8         epel          30 k
・・・・
  • 設定
# nano /etc/slurm/slurm.conf

#
# See the slurm.conf man page for more information.
#
ControlMachine=k1-inspur-a6
ControlAddr=10.0.1.90
#BackupController=
#BackupAddr=
#
AuthType=auth/munge
#CheckpointType=checkpoint/none
CryptoType=crypto/munge
#DisableRootJobs=NO
#EnforcePartLimits=NO
#Epilog=
#EpilogSlurmctld=
#FirstJobId=1
#MaxJobId=999999
#GresTypes=
#GroupUpdateForce=0
#GroupUpdateTime=600
#JobCheckpointDir=/var/slurm/checkpoint
#JobCredentialPrivateKey=
#JobCredentialPublicCertificate=
#JobFileAppend=0
#JobRequeue=1
#JobSubmitPlugins=
#KillOnBadExit=0
#LaunchType=launch/slurm
#Licenses=foo*4,bar
#MailProg=/bin/true
#MaxJobCount=5000
#MaxStepCount=40000
#MaxTasksPerNode=128
MpiDefault=pmix
#MpiParams=ports=#-#
#PluginDir=
#PlugStackConfig=
#PrivateData=jobs
ProctrackType=proctrack/cgroup
#Prolog=
#PrologFlags=
#PrologSlurmctld=
#PropagatePrioProcess=0
#PropagateResourceLimits=
#PropagateResourceLimitsExcept=
#RebootProgram=
ReturnToService=1
#SallocDefaultCommand=
SlurmctldPidFile=/var/run/slurm/slurmctld.pid
SlurmctldPort=6817
SlurmdPidFile=/var/run/slurm/slurmd.pid
SlurmdPort=6818
SlurmdSpoolDir=/var/spool/slurm/d
SlurmUser=root
#SlurmdUser=root
#SrunEpilog=
#SrunProlog=
StateSaveLocation=/var/spool/slurm/ctld
SwitchType=switch/none
#TaskEpilog=
TaskPlugin=task/none
#TaskPluginParam=
#TaskProlog=
#TopologyPlugin=topology/tree
#TmpFS=/tmp
#TrackWCKey=no
#TreeWidth=
#UnkillableStepProgram=
#UsePAM=0
#
#
# TIMERS
#BatchStartTimeout=10
#CompleteWait=0
#EpilogMsgTime=2000
#GetEnvTimeout=2
#HealthCheckInterval=0
#HealthCheckProgram=
InactiveLimit=0
KillWait=30
#MessageTimeout=10
#ResvOverRun=0
MinJobAge=300
#OverTimeLimit=0
SlurmctldTimeout=120
SlurmdTimeout=300
#UnkillableStepTimeout=60
#VSizeFactor=0
Waittime=0
#
#
# SCHEDULING
#DefMemPerCPU=0
#FastSchedule=1
#MaxMemPerCPU=0
#SchedulerTimeSlice=30
SchedulerType=sched/backfill
SelectType=select/cons_tres
SelectTypeParameters=CR_Core
#
#
# JOB PRIORITY
#PriorityFlags=
#PriorityType=priority/basic
#PriorityDecayHalfLife=
#PriorityCalcPeriod=
#PriorityFavorSmall=
#PriorityMaxAge=
#PriorityUsageResetPeriod=
#PriorityWeightAge=
#PriorityWeightFairshare=
#PriorityWeightJobSize=
#PriorityWeightPartition=
#PriorityWeightQOS=
#
#
# LOGGING AND ACCOUNTING
#AccountingStorageEnforce=0
#AccountingStorageHost=
#AccountingStorageLoc=
#AccountingStoragePass=
#AccountingStoragePort=
AccountingStorageType=accounting_storage/none
#AccountingStorageUser=
AccountingStoreJobComment=YES
ClusterName=cluster
#DebugFlags=
#JobCompHost=
#JobCompLoc=
#JobCompPass=
#JobCompPort=
JobCompType=jobcomp/none
#JobCompUser=
#JobContainerType=job_container/none
JobAcctGatherFrequency=30
JobAcctGatherType=jobacct_gather/cgroup
SlurmctldDebug=3
SlurmctldLogFile=/var/log/slurmctld.log
SlurmdDebug=3
SlurmdLogFile=/var/log/slurmd.log
#SlurmSchedLogFile=
#SlurmSchedLogLevel=
#
#
# POWER SAVE SUPPORT FOR IDLE NODES (optional)
#SuspendProgram=
#ResumeProgram=
#SuspendTimeout=
#ResumeTimeout=
#ResumeRate=
#SuspendExcNodes=
#SuspendExcParts=
#SuspendRate=
#SuspendTime=
#
#
# COMPUTE NODES
NodeName=k1-inspur-a6 CPUs=48 Sockets=1 CoresPerSocket=24 ThreadsPerCore=2 State=UNKNOWN
NodeName=k2-inspur-a6 CPUs=48 Sockets=1 CoresPerSocket=24 ThreadsPerCore=2 State=UNKNOWN
NodeName=k3-inspur-a6 CPUs=48 Sockets=1 CoresPerSocket=24 ThreadsPerCore=2 State=UNKNOWN
PartitionName=work Nodes=ALL OverSubscribe=FORCE Default=YES MaxTime=INFINITE State=UP

# scp /etc/slurm/slurm.conf k2-inspur-a6:/etc/slurm/
# scp /etc/slurm/slurm.conf k3-inspur-a6:/etc/slurm/
  • 起動

管理ノード(兼計算ノード)

# systemctl start slurmd slurmctld
# systemctl status slurmd
● slurmd.service - Slurm node daemon
   Loaded: loaded (/usr/lib/systemd/system/slurmd.service; disabled; vendor pre>
   Active: active (running) since Sun 2023-03-05 23:36:49 JST; 3s ago
 Main PID: 98292 (slurmd)
    Tasks: 1
   Memory: 1.4M
   CGroup: /system.slice/slurmd.service
           └─98292 /usr/sbin/slurmd -D

 3月 05 22:36:49 k1-inspur-a6.kuro.jp systemd[1]: Started Slurm node d>
lines 1-10/10 (END)

# systemctl status slurmctld
● slurmctld.service - Slurm controller daemon
   Loaded: loaded (/usr/lib/systemd/system/slurmctld.service; disabled; vendor >
   Active: active (running) since Sun 2023-03-05 22:38:23 JST; 55min ago
 Main PID: 96873 (slurmctld)
    Tasks: 7
   Memory: 3.8M
   CGroup: /system.slice/slurmctld.service
           └─96873 /usr/sbin/slurmctld -D

 3月 05 22:38:23 k1-inspur-a6.kuro.jp systemd[1]: Started Slurm contro>
lines 1-10/10 (END)

# firewall-cmd --add-port=6817-6818/tcp --zone=public --permanent
# firewall-cmd --reload

計算ノード

# systemctl start slurmd
# firewall-cmd --add-port=6818/tcp --zone=public --permanent
# firewall-cmd --reload

管理ノードで確認

# sinfo
PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST
work*        up   infinite      3   idle k1-inspur-a6,k2-inspur-a6,k3-inspur-a6
# sinfo -N -l
Mon Mar 06 00:23:42 2023
NODELIST       NODES PARTITION       STATE CPUS    S:C:T MEMORY TMP_DISK WEIGHT AVAIL_FE REASON              
k1-inspur-a6      1     work*        idle 48     1:24:2      1        0      1   (null) none                
k2-inspur-a6      1     work*        idle 48     1:24:2      1        0      1   (null) none                
k3-inspur-a6      1     work*        idle 48     1:24:2      1        0      1   (null) none

ノードの構成を確認

$ scontrol show node
NodeName=k1-inspur-a6 Arch=x86_64 CoresPerSocket=24 
   CPUAlloc=0 CPUTot=48 CPULoad=0.03
   AvailableFeatures=(null)
   ActiveFeatures=(null)
   Gres=(null)
   NodeAddr=k1-inspur-a6 NodeHostName=k1-inspur-a6 Version=20.11.9
   OS=Linux 4.18.0-425.13.1.el8_7.x86_64 #1 SMP Tue Feb 21 04:20:52 EST 2023 
   RealMemory=1 AllocMem=0 FreeMem=254216 Sockets=1 Boards=1
   State=IDLE ThreadsPerCore=2 TmpDisk=0 Weight=1 Owner=N/A MCS_label=N/A
   Partitions=work 
   BootTime=2023-03-01T17:38:17 SlurmdStartTime=2023-03-06T00:18:23
   CfgTRES=cpu=48,mem=1M,billing=48
   AllocTRES=
   CapWatts=n/a
   CurrentWatts=0 AveWatts=0
   ExtSensorsJoules=n/s ExtSensorsWatts=0 ExtSensorsTemp=n/s
   Comment=(null)

NodeName=k2-inspur-a6 Arch=x86_64 CoresPerSocket=24 
   CPUAlloc=0 CPUTot=48 CPULoad=0.01
   AvailableFeatures=(null)
   ActiveFeatures=(null)
   Gres=(null)
   NodeAddr=k2-inspur-a6 NodeHostName=k2-inspur-a6 Version=20.11.9
   OS=Linux 4.18.0-425.13.1.el8_7.x86_64 #1 SMP Tue Feb 21 04:20:52 EST 2023 
   RealMemory=1 AllocMem=0 FreeMem=255960 Sockets=1 Boards=1
   State=IDLE ThreadsPerCore=2 TmpDisk=0 Weight=1 Owner=N/A MCS_label=N/A
   Partitions=work 
   BootTime=2023-03-01T12:21:56 SlurmdStartTime=2023-03-06T00:18:01
   CfgTRES=cpu=48,mem=1M,billing=48
   AllocTRES=
   CapWatts=n/a
   CurrentWatts=0 AveWatts=0
   ExtSensorsJoules=n/s ExtSensorsWatts=0 ExtSensorsTemp=n/s
   Comment=(null)

NodeName=k3-inspur-a6 Arch=x86_64 CoresPerSocket=24 
   CPUAlloc=0 CPUTot=48 CPULoad=0.00
   AvailableFeatures=(null)
   ActiveFeatures=(null)
   Gres=(null)
   NodeAddr=k3-inspur-a6 NodeHostName=k3-inspur-a6 Version=20.11.9
   OS=Linux 4.18.0-425.13.1.el8_7.x86_64 #1 SMP Tue Feb 21 04:20:52 EST 2023 
   RealMemory=1 AllocMem=0 FreeMem=255896 Sockets=1 Boards=1
   State=IDLE ThreadsPerCore=2 TmpDisk=0 Weight=1 Owner=N/A MCS_label=N/A
   Partitions=work 
   BootTime=2023-03-01T18:01:07 SlurmdStartTime=2023-03-06T00:17:26
   CfgTRES=cpu=48,mem=1M,billing=48
   AllocTRES=
   CapWatts=n/a
   CurrentWatts=0 AveWatts=0
   ExtSensorsJoules=n/s ExtSensorsWatts=0 ExtSensorsTemp=n/s
   Comment=(null)

Slurmによるバッチファイルの実行方法はSGE/torqueと若干違っている。
まず投入コマンドがqsubではなくsbatchである。

$sbatch -a 0-9:1 test_batch.sh

のような書式が基本スタイルでqsubで-tで与えていたタスクIDが-aとなっている。(:1を2にしたら2ID番号ごとに飛び飛びに実行される)

#!/bin/sh
#SBATCH -c 8 #1タスクで使用するCPU
#SBATCH -J test230331 #ジョブにつけた名前
#SBATCH -o %x_%j.log #標準出力をファイルに書き出し。-eをつけないとエラーログも同じファイルに書き出す
#SBATCH -a 518  #タスクIDは中に書いておくことも可能

バッチファイルの頭にこのような感じで記述をしておくのはqsubと似たような感じ。
%xはジョブ名、%jはジョブID、%AはアレイジョブID、%aはアレイタスクIDに置換。
ジョブ名を設定していないとスクリプト名がそのまま使われる。


一度に投入できるタスクはデフォルトでは

$ scontrol show config | grep MaxArraySize
MaxArraySize            = 1001

となっており1001-1=1000タスクとなっている。/etc/slurm/slurm.confで書き換えることも可能だ。

ジョブの実行状況を確認するコマンドはqstatに対しsqueueとなっている。

アレイジョブ内で利用できる環境変数
SLURM_ARRAY_JOB_ID   アレイジョブのID
SLURM_ARRAY_TASK_ID   アレイジョブのタスクID
SLURM_ARRAY_TASK_COUNT   アレイジョブのタスク数
SLURM_ARRAY_TASK_MIN   アレイジョブの最初のタスクID
SLURM_ARRAY_TASK_MAX   アレイジョブの最後のタスクID
などなので特にタスクIDを使ってファイルを参照するとかに使用できる。

line=${SLURM_ARRAY_TASK_ID}

など。