さて、サーバ間でユーザとディレクトリを共有できるようになったので、次にジョブスケジューラを導入してサーバクラスタとしたい。
これまで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}
など。