slurm.confを正確に書く
一言でいうと
slurm.confは、すべてのノードで同一でなければならない唯一の正本です。1台だけ違うと、そのノードが静かに外れます。
なぜ必要なのか
Slurmの設定ミスの特徴は、エラーが遅れて、思わぬところに現れることです。ノードがINVALやDOWNで外れ、ログには原因が1行出ているのに、それを見ないと何日も迷います。
どう動くのか
必須のキー
ClusterName=labhub-hpc
SlurmctldHost=ctl01
SlurmUser=slurm
SlurmdUser=root
StateSaveLocation=/var/spool/slurmctld
SlurmdSpoolDir=/var/spool/slurmd
SlurmctldPidFile=/run/slurmctld.pid
SlurmdPidFile=/run/slurmd.pid
AuthType=auth/munge
ClusterName: 複数のクラスターを1つのDBで管理するときの識別子です。小文字でなければなりません。SlurmctldHost: コントローラーのホスト名です。DNSかhostsで、すべてのノードから名前解決できる必要があります。SlurmUser: slurmctldを動かすアカウントです。通常はslurm専用のアカウントを使います。StateSaveLocation: キューとジョブの状態が保存される場所です。このディレクトリを失うと、実行中だったジョブの情報が消えます。HA構成では共有ストレージに置きます。
スケジューリングとリソース選択
SchedulerType=sched/backfill
SelectType=select/cons_tres
SelectTypeParameters=CR_Core_Memory
ProctrackType=proctrack/cgroup
TaskPlugin=task/cgroup,task/affinity
SelectType=select/cons_tres: リソースをノード単位ではなく、コア・メモリ・GRES単位に分けて割り当てます。GPUクラスターでは事実上必須です。古い名前はcons_resです。SelectTypeParameters=CR_Core_Memory: コアとメモリの両方を消費リソースとして扱います。メモリを外すと、1台のノードにメモリを超過するジョブが集中してOOMが起きます。ProctrackType=proctrack/cgroup: ジョブのプロセスをcgroupで追跡します。これがないと、ジョブが終わっても子プロセスが残ります。TaskPlugin=task/cgroup: リソースの分離をcgroupで強制します。要求していないGPUが見えないようにしているのは、このプラグインです。
ノードの定義
NodeName=gpu-node01 Sockets=2 CoresPerSocket=16 ThreadsPerCore=2 CPUs=64 RealMemory=257000 Gres=gpu:a100:8 State=UNKNOWN
ここには、最もよくある間違いが2つあります。
CPUsがSockets × CoresPerSocket × ThreadsPerCoreと異なっている。この場合、slurmctldがLow socket*core*thread countとしてノードをINVAL状態にします。RealMemoryを実際の物理メモリより大きくしている。ノードが報告する値より大きいと、Low RealMemoryでDOWNになります。逆に小さくしすぎると、メモリを無駄にします。OSが使う分を引いて設定するのが慣例です。256GBのノードなら、RealMemory=257000程度にします(MB単位)。
ノードの実際の値はslurmd -Cで確認できます。その出力をそのまま貼り付けるのが最も安全です。
パーティションの定義
PartitionName=batch Nodes=gpu-node[01-03] Default=YES MaxTime=24:00:00 State=UP
PartitionName=short Nodes=gpu-node[01-03] MaxTime=01:00:00 Priority=100 State=UP
Nodes=に書いたノードは、すべてNodeNameとして定義されている必要があります。存在しないノードを参照するとpartition ... has unknown node ...という警告が出て、そのノードは無視されます。Default=YESは、パーティション1つにだけ付けます。- 範囲表記
gpu-node[01-03]が使えます。
ログと状態
SlurmctldLogFile=/var/log/slurm/slurmctld.log
SlurmdLogFile=/var/log/slurm/slurmd.log
AccountingStorageType=accounting_storage/none
JobAcctGatherType=jobacct_gather/cgroup
ReturnToService=2
ReturnToService=2にすると、DOWNになったノードが有効な設定で再登録したときに自動で復帰します。既定値の0では、管理者が明示的にRESUMEする必要があります。
変更後
scontrol reconfigure # 대부분의 변경은 이것으로 반영
systemctl restart slurmctld # 일부 핵심 변경은 재기동 필요
scontrol show config | head -40
設定ファイルをすべてのノードに配布するのを忘れないでください。1台だけ違うと、そのノードが静かに外れます。そのため、ほとんどのクラスターは/etc/slurmを共有ストレージに置くか、構成管理で配布します。
現場での姿
slurmd -Cの出力をそのまま使わないことで起きる問題。手で計算してThreadsPerCoreを入れ忘れたり、ハイパースレッディングの数え方を間違えたりすると、ノードがINVALで外れます。そのノードでslurmd -Cを実行して出た行をそのまま貼り付けるのが、最も確実です。
次のラボですること
要件に合ったslurm.confを最初から作成し、mungeキーの権限を整え、整合性を検証するスクリプトを自分で作ります。採点ツールが、そのスクリプトを正常な設定と壊れた設定の両方に対して実行します。