Epilogスクリプトについて追加
| 登録日 | :2025/03/08 08:52 |
|---|---|
| カテゴリ | :SLURM |
Epilogスクリプトでジョブタイプ(インタラクティブ実行 vs バッチ処理)を判別し、適切なプロセスクリーンアップを行うスクリプトは以下のように実装できます。SLURMの環境変数と条件分岐を活用します。
#!/bin/bash
# SLURM Epilogスクリプト(/opt/slurm/etc/scripts/epilog.d/20_clean_processes.sh)
# ログ設定
LOG_FILE="/var/log/slurm/epilog_clean.log"
echo "[$(date)] Epilog started for job: $SLURM_JOB_ID" >> $LOG_FILE
# ジョブタイプ判別
if [[ "$SLURM_JOB_NAME" == "interactive" ]]; then
# インタラクティブジョブ(srun/salloc): ユーザーの全プロセスを削除
echo "Interactive job detected. Cleaning all user processes..." >> $LOG_FILE
pkill -9 -u $SLURM_JOB_USER
pgrep -u $SLURM_JOB_USER | xargs -r kill -9
else
# バッチジョブ(sbatch): SLURMジョブIDに関連するプロセスのみ削除
echo "Batch job detected. Cleaning job-related processes..." >> $LOG_FILE
# SLURMジョブIDに関連するプロセスの特定と削除
ps aux | awk -v jobid="$SLURM_JOB_ID" \
'$0 ~ jobid && $1 == ENVIRON["SLURM_JOB_USER"] {print $2}' | \
xargs -r kill -9
# scontrol listpidsで管理プロセスを削除(SLURM 23.02以降)
if command -v scontrol &> /dev/null; then
scontrol listpids $SLURM_JOB_ID | \
awk '/^[0-9]+/{print $1}' | \
xargs -r kill -9
fi
fi
# クリーンアップ完了ログ
echo "[$(date)] Cleanup completed for job: $SLURM_JOB_ID" >> $LOG_FILE
実装手順
スクリプト配置:
sudo mkdir -p /opt/slurm/etc/scripts/epilog.d
sudo nano /opt/slurm/etc/scripts/epilog.d/20_clean_processes.sh
権限設定:
sudo chmod 755 /opt/slurm/etc/scripts/epilog.d/20_clean_processes.sh
sudo chown slurm:slurm /opt/slurm/etc/scripts/epilog.d/20_clean_processes.sh
slurm.conf設定:
Epilog=/opt/slurm/etc/scripts/epilog.d/*
PrologFlags=Alloc
sudoers設定(必要な場合):
# /etc/sudoers.d/slurm_epilog
slurm ALL=(ALL) NOPASSWD: /usr/bin/pkill
slurm ALL=(ALL) NOPASSWD: /usr/bin/pgrep
動作説明
インタラクティブジョブ時(srun/salloc)
判別方法: $SLURM_JOB_NAMEが"interactive"の場合
処理内容:
pkill -9 -u $USERでユーザー全プロセスを強制終了
pgrepで残存プロセスを検出し追加削除
バッチジョブ時(sbatch)
判別方法: 上記以外の場合
処理内容:
ps auxでジョブIDを含むコマンドラインのプロセスを検出
scontrol listpids(SLURM 23.02以降)で管理プロセスを取得
検出したPIDを強制終了
検証方法
テストケース1: インタラクティブジョブ
salloc -N 1 --job-name=interactive
# 別ターミナルでプロセス起動
ssh node1 "sleep 1000" &
# ジョブ終了後、プロセスが削除されていることを確認
テストケース2: バッチジョブ
sbatch --wrap="sleep 1000"
# ジョブ終了後、関連プロセスのみ削除されることを確認
注意事項
セキュリティ:
Epilogスクリプトはroot権限で実行されるため、権限昇格のリスクを排除する設計が必要
kill -9は最終手段として使用し、可能な限りSIGTERM(kill -15)を優先
パフォーマンス:
大規模クラスタではプロセス検出処理に時間がかかるため、xargs -rで空入力時のエラーを防止
/var/log/slurm/ディレクトリのログローテーション設定を推奨
SLURMバージョン:
scontrol listpidsはSLURM 23.02以降で利用可能
旧バージョンではsshpd.shなどの代替スクリプトが必要8
この実装により、ジョブタイプに応じた適切なプロセスクリーンアップが自動化されます。
Appendix
ジョブタイプの判別方法で、BatchFlagを使うスクリプト
※バッチジョブのは、BatchFlag=1となる。
※インタラクティブジョブはBatchFlag=0となる。
#!/bin/bash
# Epilogスクリプト内での実装例
# ジョブ情報を取得
# JOB_INFO=$(scontrol show job $SLURM_JOB_ID)
JOB_INFO=$(sudo scontrol show job $SLURM_JOB_ID)
# BatchFlagの値を抽出
BATCH_FLAG=$(echo "$JOB_INFO" | grep -oP 'BatchFlag=\K\d+')
if [[ "$BATCH_FLAG" == "1" ]]; then
# バッチジョブの場合: ジョブIDに関連するプロセスのみ削除
echo "Batch job detected. Cleaning job-related processes..." >> /var/log/epilog.log
pkill -9 -f $SLURM_JOB_ID
else
# インタラクティブジョブの場合: ユーザ全プロセスを削除
echo "Interactive job detected. Cleaning all user processes..." >> /var/log/epilog.log
pkill -9 -u $SLURM_JOB_USER
fi
動作確認方法
バッチジョブ(BatchFlag=1)の場合
sbatch --wrap="sleep 60"
# Epilogログ確認:
# "Batch job detected. Cleaning job-related processes..."
インタラクティブジョブ(BatchFlag=0)の場合
salloc -N 1
# 別ターミナルでプロセス起動
ssh node1 "sleep 1000" &
exit
# Epilogログ確認:
# "Interactive job detected. Cleaning all user processes..."
制約事項
ジョブ終了後の情報取得:
ジョブが完全に終了した後ではscontrol show jobが情報を返さないため、Epilogスクリプトの実行タイミングが重要です17。
クラスタ設定依存:
BatchFlagはsbatchで投入されたジョブでのみ1が設定されます8。
salloc/srunで開始されたジョブは0になります。
パフォーマンス影響:
大規模クラスタでscontrolコマンドを頻繁に実行すると、slurmctldに負荷がかかる可能性があります。
代替方法(環境変数を利用)
SLURM_SCRIPT_CONTEXT環境変数で実行コンテキストを判別可能13:
#!/bin/bash
case $SLURM_SCRIPT_CONTEXT in
epilog_slurmctld)
echo "Controller-level cleanup" ;;
epilog_slurmd)
if [[ $(sudo scontrol show job $SLURM_JOB_ID | grep -c 'BatchFlag=1') -gt 0 ]]; then
# バッチジョブ処理
else
# インタラクティブ処理
fi ;;
esac
Appendix2
Epilogスクリプトはジョブが完全に終了する前の段階で実行されるため、scontrol show jobコマンドでジョブ情報を取得可能です。Slurmの動作仕様と検索結果47から、以下のポイントが明らかです:
Epilogスクリプトの実行タイミング
ジョブ終了直後の処理:
Epilogスクリプトはジョブ終了直後(リソース解放前)に実行されます。
この時点ではジョブ情報がSlurmにまだ保持されているため、scontrol show jobで情報取得が可能です14。
具体的な実行順序:
flowchart LR
ジョブ終了 --> Epilog実行 --> リソース解放 --> ジョブ情報削除
Epilogは「ジョブ終了」と「リソース解放」の間に位置します47。
実装上の注意点
情報取得可能な期間:
# Epilogスクリプト内で有効な操作例
JOB_INFO=$(scontrol show job $SLURM_JOB_ID) # ← 正常に動作
この時点ではジョブ情報が残存しているため、BatchFlagなどの情報取得が可能3。
ジョブ情報消失後の操作:
# ジョブ完全終了後(例:ユーザー手動実行時)
scontrol show job 完了済み_JOB_ID # ← "Invalid job id"エラー
リソース解放後は情報が削除されるため、Epilog外での操作は不可4。
補足情報(検索結果から)
AWS ParallelClusterのケース2:
Epilogスクリプトの実行時間はジョブ実行時間に含まれるため、BatchStartTimeout設定(デフォルト3分)に注意が必要。
複数ノード対応7:
# マルチノードジョブの場合のEpilog処理例
srun -N $SLURM_JOB_NUM_NODES /path/to/cleanup.sh
全ノードでEpilogスクリプトが並列実行されるため、分散処理が必要。
これらの仕様を理解した上で、Epilogスクリプト内でscontrolを活用した柔軟なクリーンアップ処理を実装できます。