AWS PCS が EC2 インスタンスの置き換えなしのコンピュートノード再起動機能をサポートしました

AWS PCS が EC2 インスタンスの置き換えなしのコンピュートノード再起動機能をサポートしました

2025.10.24

はじめに

2025 年 10 月、AWS Parallel Computing Service (PCS) で Slurm のコンピュートノード再起動機能がサポートされました。

https://aws.amazon.com/jp/about-aws/whats-new/2025/10/aws-pcs-slurm-node-reboot/

EC2 インスタンスを置換せずにコンピュートノードを再起動できます。Slurm のネイティブコマンドを使用したノード管理ができます。

PCS再起動.png

Slurm ノード再起動機能とは

AWS PCS では、Slurm の scontrol reboot コマンドを使用してコンピュートノードを再起動できるようになりました。

従来、EC2 コンソールや AWS CLI、自動パッチなどで再起動すると、AWS PCS はインスタンスを正常ではない状態とみなして新しいインスタンスに置換していました。今回のアップデートにより、インスタンス置換を伴わない再起動が可能になります。

メリット

Slurm ノード再起動機能には、以下のメリットがあります。

  • キャパシティの保持
    • キャパシティが少ないインスタンスを他の顧客に取られることなく維持できる
  • コスト削減
    • インスタンス置換にかかる時間の短縮
  • リカバリ時間の短縮
    • インスタンス置換と比較するとコンピュートノードが利用可能になるまでが早くなる
  • 運用の柔軟性
    • メモリリークのクリア、一時ファイルの削除、劣化状態からのノードリカバリが可能

制限事項

Slurm ノード再起動機能には制限があります。Slurm Admin ユーザー(root ユーザー)のみが scontrol reboot コマンドを実行できます。また、サポートされるコマンドは scontrol reboot のみです。

ジョブ実行中の再起動について

再起動時のジョブの扱いは、指定するオプションによって異なります。

デフォルトの動作

オプションを指定しない場合、ジョブが正常に完了してから再起動します。

ASAP オプション使用時

ASAP オプションを使用するとノードがドレイン状態になり、新しいジョブの投入が防止されます。現在実行中のジョブが完了した後に再起動が発生します。

すぐに再起動したい場合

すぐに再起動したい場合は、2 つの方法があります。

1 つ目は、ジョブをキャンセルしてから再起動する方法です。

scancel <job_id> でジョブをキャンセルしてから、scontrol reboot ASAP <nodename> で即座に再起動します。実行中のジョブは終了するため、ノードリカバリ後に再投入が必要です。

2 つ目は、ドレインしてリキューする方法です。

scontrol reboot ASAP <nodename> で再起動を開始してから、scontrol requeue <job_id> でジョブをリキューします。ジョブはキャンセルではなく待機状態に戻ります。この方法は影響が少ないです。

試してみた

AWS PCS でコンピュートノード再起動機能を試してみました。

検証環境

本記事の検証には、以下の構成で AWS PCS クラスターを構築しました。

項目 設定値
リージョン 東京リージョン(ap-northeast-1)
Slurm バージョン 25.05.3
ログインノード t3.micro × 1 台
コンピュートノード m7i.large × 最大 4 台
共有ストレージ Amazon EFS

構築に使用した CloudFormation テンプレートです。

CloudFormation テンプレート
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Simple AWS PCS cluster for verification - 1 login node (t3.micro) and up to 4 compute nodes (m7i.large) with EFS storage'

Parameters:
  ClusterName:
    Type: String
    Default: 'simple-pcs-cluster'
    Description: 'Name of the PCS cluster'
  AMIID:
    Type: AWS::EC2::Image::Id
    Default: 'ami-056a2dabd78ff3886'
  SlurmVersion:
    Type: String
    Default: '25.05'
    Description: 'Slurm version for the PCS cluster'
    AllowedValues:
      - '25.05'
      - '24.11'

Resources:
  # VPC
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: '10.0.0.0/16'
      EnableDnsHostnames: true
      EnableDnsSupport: true
      Tags:
        - Key: Name
          Value: !Sub '${ClusterName}-vpc'

  # Internet Gateway
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Sub '${ClusterName}-igw'

  InternetGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      InternetGatewayId: !Ref InternetGateway
      VpcId: !Ref VPC

  # Public Subnet
  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [0, !GetAZs '']
      CidrBlock: '10.0.1.0/24'
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub '${ClusterName}-public-subnet-1'

  PublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [1, !GetAZs '']
      CidrBlock: '10.0.2.0/24'
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub '${ClusterName}-public-subnet-2'

  PublicSubnet3:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [2, !GetAZs '']
      CidrBlock: '10.0.3.0/24'
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub '${ClusterName}-public-subnet-3'

  # Private Subnet
  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [0, !GetAZs '']
      CidrBlock: '10.0.11.0/24'
      Tags:
        - Key: Name
          Value: !Sub '${ClusterName}-private-subnet-1'

  PrivateSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [1, !GetAZs '']
      CidrBlock: '10.0.12.0/24'
      Tags:
        - Key: Name
          Value: !Sub '${ClusterName}-private-subnet-2'

  PrivateSubnet3:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [2, !GetAZs '']
      CidrBlock: '10.0.13.0/24'
      Tags:
        - Key: Name
          Value: !Sub '${ClusterName}-private-subnet-3'

  # Isolated Subnet
  IsolatedSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [0, !GetAZs '']
      CidrBlock: '10.0.21.0/24'
      Tags:
        - Key: Name
          Value: !Sub '${ClusterName}-isolated-subnet-1'

  IsolatedSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [1, !GetAZs '']
      CidrBlock: '10.0.22.0/24'
      Tags:
        - Key: Name
          Value: !Sub '${ClusterName}-isolated-subnet-2'

  IsolatedSubnet3:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [2, !GetAZs '']
      CidrBlock: '10.0.23.0/24'
      Tags:
        - Key: Name
          Value: !Sub '${ClusterName}-isolated-subnet-3'

  # NAT Gateway
  NatGateway1EIP:
    Type: AWS::EC2::EIP
    DependsOn: InternetGatewayAttachment
    Properties:
      Domain: vpc

  NatGateway1:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt NatGateway1EIP.AllocationId
      SubnetId: !Ref PublicSubnet1

  # Route Tables
  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub '${ClusterName}-public-routes'

  DefaultPublicRoute:
    Type: AWS::EC2::Route
    DependsOn: InternetGatewayAttachment
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: '0.0.0.0/0'
      GatewayId: !Ref InternetGateway

  PublicSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PublicRouteTable
      SubnetId: !Ref PublicSubnet1

  PublicSubnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PublicRouteTable
      SubnetId: !Ref PublicSubnet2

  PublicSubnet3RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PublicRouteTable
      SubnetId: !Ref PublicSubnet3

  PrivateRouteTable1:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub '${ClusterName}-private-routes-1'

  DefaultPrivateRoute1:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable1
      DestinationCidrBlock: '0.0.0.0/0'
      NatGatewayId: !Ref NatGateway1

  PrivateSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PrivateRouteTable1
      SubnetId: !Ref PrivateSubnet1

  PrivateSubnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PrivateRouteTable1
      SubnetId: !Ref PrivateSubnet2

  PrivateSubnet3RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PrivateRouteTable1
      SubnetId: !Ref PrivateSubnet3

  # Security Groups
  LoginSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: !Sub '${ClusterName}-login-sg'
      GroupDescription: 'Security group for PCS login nodes'
      VpcId: !Ref VPC
      SecurityGroupEgress:
        - IpProtocol: -1
          CidrIp: 0.0.0.0/0
          Description: 'Allow all outbound traffic'
      Tags:
        - Key: Name
          Value: !Sub '${ClusterName}-login-sg'

  ComputeSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: !Sub '${ClusterName}-compute-sg'
      GroupDescription: 'Security group for PCS compute nodes'
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 10.0.0.0/16
          Description: 'SSH access from VPC for PCS requirement'
      SecurityGroupEgress:
        - IpProtocol: -1
          CidrIp: 0.0.0.0/0
          Description: 'Allow all outbound traffic'
      Tags:
        - Key: Name
          Value: !Sub '${ClusterName}-compute-sg'

  # Allow all traffic from login to compute
  ComputeSecurityGroupIngressFromLogin:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      GroupId: !Ref ComputeSecurityGroup
      IpProtocol: -1
      SourceSecurityGroupId: !Ref LoginSecurityGroup
      Description: 'Allow all traffic from login nodes'

  # Allow all traffic from compute to login
  LoginSecurityGroupIngressFromCompute:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      GroupId: !Ref LoginSecurityGroup
      IpProtocol: -1
      SourceSecurityGroupId: !Ref ComputeSecurityGroup
      Description: 'Allow all traffic from compute nodes'

  # Self-referencing rules for login nodes
  LoginSecurityGroupIngressSelfRef:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      GroupId: !Ref LoginSecurityGroup
      IpProtocol: -1
      SourceSecurityGroupId: !Ref LoginSecurityGroup
      Description: 'Allow all traffic within login nodes'

  # Self-referencing rules for compute nodes
  ComputeSecurityGroupIngressSelfRef:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      GroupId: !Ref ComputeSecurityGroup
      IpProtocol: -1
      SourceSecurityGroupId: !Ref ComputeSecurityGroup
      Description: 'Allow all traffic within compute nodes'

  EFSSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: !Sub '${ClusterName}-efs-sg'
      GroupDescription: 'Security group for EFS'
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 2049
          ToPort: 2049
          SourceSecurityGroupId: !Ref LoginSecurityGroup
        - IpProtocol: tcp
          FromPort: 2049
          ToPort: 2049
          SourceSecurityGroupId: !Ref ComputeSecurityGroup
      Tags:
        - Key: Name
          Value: !Sub '${ClusterName}-efs-sg'

  # EFS
  EFSFileSystem:
    Type: AWS::EFS::FileSystem
    Properties:
      PerformanceMode: generalPurpose
      ThroughputMode: bursting
      Encrypted: true
      FileSystemTags:
        - Key: Name
          Value: !Sub '${ClusterName}-efs'

  EFSMountTarget1:
    Type: AWS::EFS::MountTarget
    Properties:
      FileSystemId: !Ref EFSFileSystem
      SubnetId: !Ref PrivateSubnet1
      SecurityGroups:
        - !Ref EFSSecurityGroup

  EFSMountTarget2:
    Type: AWS::EFS::MountTarget
    Properties:
      FileSystemId: !Ref EFSFileSystem
      SubnetId: !Ref PrivateSubnet2
      SecurityGroups:
        - !Ref EFSSecurityGroup

  EFSMountTarget3:
    Type: AWS::EFS::MountTarget
    Properties:
      FileSystemId: !Ref EFSFileSystem
      SubnetId: !Ref PrivateSubnet3
      SecurityGroups:
        - !Ref EFSSecurityGroup

  # IAM Role for PCS Instance
  PCSInstanceRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub 'AWSPCS-${AWS::StackName}-${AWS::Region}'
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: ec2.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
      Policies:
        - PolicyName: PCSComputeNodePolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - pcs:RegisterComputeNodeGroupInstance
                Resource: '*'

  PCSInstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Roles:
        - !Ref PCSInstanceRole

  # Launch Template for Login Nodes
  LoginLaunchTemplate:
    Type: AWS::EC2::LaunchTemplate
    Properties:
      LaunchTemplateName: !Sub '${ClusterName}-login-launch-template'
      LaunchTemplateData:
        ImageId: !Ref AMIID
        SecurityGroupIds:
          - !Ref LoginSecurityGroup
        IamInstanceProfile:
          Arn: !GetAtt PCSInstanceProfile.Arn
        UserData:
          Fn::Base64: !Sub |
            MIME-Version: 1.0
            Content-Type: multipart/mixed; boundary="==BOUNDARY=="

            --==BOUNDARY==
            Content-Type: text/x-shellscript; charset="us-ascii"

            #!/bin/bash
            yum update -y
            yum install -y amazon-efs-utils
            mkdir -p /shared
            echo "${EFSFileSystem}.efs.${AWS::Region}.amazonaws.com:/ /shared efs defaults,_netdev" >> /etc/fstab
            mount -a
            chown ec2-user:ec2-user /shared
            chmod 755 /shared

            # Add Slurm commands to PATH for all users
            echo 'export PATH=/opt/slurm/bin:$PATH' >> /etc/profile.d/slurm.sh
            chmod +x /etc/profile.d/slurm.sh

            # Add to ec2-user's bashrc for immediate availability
            echo 'export PATH=/opt/slurm/bin:$PATH' >> /home/ec2-user/.bashrc
            chown ec2-user:ec2-user /home/ec2-user/.bashrc

            --==BOUNDARY==--
        MetadataOptions:
          HttpTokens: required
          HttpPutResponseHopLimit: 2
          HttpEndpoint: enabled

  # Launch Template for Compute Nodes
  ComputeLaunchTemplate:
    Type: AWS::EC2::LaunchTemplate
    Properties:
      LaunchTemplateName: !Sub '${ClusterName}-compute-launch-template'
      LaunchTemplateData:
        ImageId: !Ref AMIID
        SecurityGroupIds:
          - !Ref ComputeSecurityGroup
        IamInstanceProfile:
          Arn: !GetAtt PCSInstanceProfile.Arn
        UserData:
          Fn::Base64: !Sub |
            MIME-Version: 1.0
            Content-Type: multipart/mixed; boundary="==BOUNDARY=="

            --==BOUNDARY==
            Content-Type: text/x-shellscript; charset="us-ascii"

            #!/bin/bash
            yum update -y
            yum install -y amazon-efs-utils
            mkdir -p /shared
            echo "${EFSFileSystem}.efs.${AWS::Region}.amazonaws.com:/ /shared efs defaults,_netdev" >> /etc/fstab
            mount -a
            chown ec2-user:ec2-user /shared
            chmod 755 /shared

            # Add Slurm commands to PATH for all users
            echo 'export PATH=/opt/slurm/bin:$PATH' >> /etc/profile.d/slurm.sh
            chmod +x /etc/profile.d/slurm.sh

            # Add to ec2-user's bashrc for immediate availability
            echo 'export PATH=/opt/slurm/bin:$PATH' >> /home/ec2-user/.bashrc
            chown ec2-user:ec2-user /home/ec2-user/.bashrc

            --==BOUNDARY==--
        MetadataOptions:
          HttpTokens: required
          HttpPutResponseHopLimit: 2
          HttpEndpoint: enabled

  # PCS Cluster
  PCSCluster:
    Type: AWS::PCS::Cluster
    Properties:
      Name: !Ref ClusterName
      Size: SMALL
      Scheduler:
        Type: SLURM
        Version: !Ref SlurmVersion
      Networking:
        SubnetIds:
          - !Ref PrivateSubnet1
        SecurityGroupIds:
          - !Ref LoginSecurityGroup
          - !Ref ComputeSecurityGroup

  # Login Node Group
  LoginNodeGroup:
    Type: AWS::PCS::ComputeNodeGroup
    Properties:
      ClusterId: !GetAtt PCSCluster.Id
      Name: login
      ScalingConfiguration:
        MinInstanceCount: 1
        MaxInstanceCount: 1
      IamInstanceProfileArn: !GetAtt PCSInstanceProfile.Arn
      CustomLaunchTemplate:
        TemplateId: !Ref LoginLaunchTemplate
        Version: 1
      SubnetIds:
        - !Ref PublicSubnet1
      AmiId: !Ref AMIID
      InstanceConfigs:
        - InstanceType: 't3.micro'

  # Compute Node Group
  ComputeNodeGroup:
    Type: AWS::PCS::ComputeNodeGroup
    Properties:
      ClusterId: !GetAtt PCSCluster.Id
      Name: compute
      ScalingConfiguration:
        MinInstanceCount: 0
        MaxInstanceCount: 4
      IamInstanceProfileArn: !GetAtt PCSInstanceProfile.Arn
      CustomLaunchTemplate:
        TemplateId: !Ref ComputeLaunchTemplate
        Version: 1
      SubnetIds:
        - !Ref PrivateSubnet1
      AmiId: !Ref AMIID
      InstanceConfigs:
        - InstanceType: 'm7i.large'

  # Queue
  ComputeQueue:
    Type: AWS::PCS::Queue
    Properties:
      ClusterId: !GetAtt PCSCluster.Id
      Name: compute-queue
      ComputeNodeGroupConfigurations:
        - ComputeNodeGroupId: !GetAtt ComputeNodeGroup.Id

Outputs:
  ClusterId:
    Description: 'The ID of the PCS cluster'
    Value: !GetAtt PCSCluster.Id
    Export:
      Name: !Sub '${AWS::StackName}-ClusterId'

  VPCId:
    Description: 'The ID of the VPC'
    Value: !Ref VPC
    Export:
      Name: !Sub '${AWS::StackName}-VPCId'

  EFSFileSystemId:
    Description: 'The ID of the EFS file system'
    Value: !Ref EFSFileSystem
    Export:
      Name: !Sub '${AWS::StackName}-EFSFileSystemId'

  PCSConsoleUrl:
    Description: 'URL to access the cluster in the PCS console'
    Value: !Sub 'https://${AWS::Region}.console.aws.amazon.com/pcs/home?region=${AWS::Region}#/clusters/${PCSCluster.Id}'
    Export:
      Name: !Sub '${AWS::StackName}-PCSConsoleUrl'

  EC2ConsoleUrl:
    Description: 'URL to access login node instances via Session Manager'
    Value: !Sub 'https://${AWS::Region}.console.aws.amazon.com/ec2/home?region=${AWS::Region}#Instances:instanceState=running;tag:aws:pcs:compute-node-group-id=${LoginNodeGroup.Id}'
    Export:
      Name: !Sub '${AWS::StackName}-EC2ConsoleUrl'

  PCSInstanceRoleArn:
    Description: 'ARN of the PCS Instance Role with vended log delivery permissions'
    Value: !GetAtt PCSInstanceRole.Arn
    Export:
      Name: !Sub '${AWS::StackName}-PCSInstanceRoleArn'

単一ノードの再起動

単一のコンピュートノードを再起動する基本的な手順を確認します。

ノードの確認

まず、sinfo コマンドで現在のノード状態を確認します。

$ sinfo
PARTITION     AVAIL  TIMELIMIT  NODES  STATE NODELIST
compute-queue    up   infinite      4   idle compute-[1-4]

4 台のコンピュートノードがアイドル状態です。

テストジョブの実行

テストジョブを投入してノードを起動します。

$ sbatch test.sh

$ sinfo
PARTITION     AVAIL  TIMELIMIT  NODES  STATE NODELIST
compute-queue    up   infinite      3  idle~ compute-[2-4]
compute-queue    up   infinite      1  alloc compute-1

$ squeue
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
                 2 compute-q  test.sh ec2-user  R       0:07      1 compute-1

compute-1 でジョブが実行中です。EC2 コンソールでもインスタンスが起動していることを確認できます。

EC2 コンソールでインスタンスが起動している様子

ジョブ完了後の再起動

ジョブが完了し、compute-1 がidle状態に戻りました。

$ sinfo
PARTITION     AVAIL  TIMELIMIT  NODES  STATE NODELIST
compute-queue    up   infinite      3  idle~ compute-[2-4]
compute-queue    up   infinite      1   idle compute-1

scontrol reboot コマンドで再起動します。

$ sudo /opt/slurm/bin/scontrol reboot compute-1

再起動の進行状況確認

sinfo コマンドで確認すると、ノードのステータスが boot^ になっています。

$ sinfo
PARTITION     AVAIL  TIMELIMIT  NODES  STATE NODELIST
compute-queue    up   infinite      1  boot^ compute-1
compute-queue    up   infinite      3  idle~ compute-[2-4]

scontrol show node コマンドで詳細を確認すると、State は DOWN+CLOUD+DRAIN+REBOOT_ISSUED になっており、再起動が発行されたことがわかります。

$ scontrol show node compute-1
NodeName=compute-1 Arch=x86_64 CoresPerSocket=1
   CPUAlloc=0 CPUEfctv=1 CPUTot=1 CPULoad=0.31
   AvailableFeatures=compute
   ActiveFeatures=compute
   Gres=(null)
   NodeAddr=10.0.11.58 NodeHostName=ip-10-0-11-58 Version=25.05.3
   OS=Linux 5.10.244-240.970.amzn2.x86_64 #1 SMP Tue Oct 7 09:40:03 UTC 2025
   RealMemory=7782 AllocMem=0 FreeMem=7339 Sockets=1 Boards=1
   State=DOWN+CLOUD+DRAIN+REBOOT_ISSUED ThreadsPerCore=1 TmpDisk=0 Weight=1 Owner=N/A MCS_label=N/A
   NextState=UNDRAIN
   Partitions=compute-queue
   BootTime=2025-10-24T04:47:52 SlurmdStartTime=2025-10-24T04:48:03
   LastBusyTime=2025-10-24T04:48:02 ResumeAfterTime=None
   CfgTRES=cpu=1,mem=7782M,billing=1
   AllocTRES=
   CurrentWatts=0 AveWatts=0
   Reason=reboot requested : reboot issued [slurm@2025-10-24T04:49:09]
   InstanceId=[2025-10-24T04:39:40.143+00:00] InstanceType=-

再起動完了の確認

しばらくすると idle 状態に戻りました。

$ sinfo
PARTITION     AVAIL  TIMELIMIT  NODES  STATE NODELIST
compute-queue    up   infinite      3  idle~ compute-[2-4]
compute-queue    up   infinite      1   idle compute-1

EC2 コンソールで確認すると、インスタンスの置き換えは発生していません。同じインスタンス ID で再起動が完了しています。

再起動後も同じインスタンス ID が維持されていることを示す EC2 コンソール画面

複数ノードの ASAP 再起動とジョブ実行中の挙動

複数のコンピュートノードを ASAP オプションで再起動し、ジョブ実行中の挙動を確認します。

ジョブ実行中のノード状態

4 台のコンピュートノードでジョブが実行されています。

$ squeue
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
                 5 compute-q  test.sh ec2-user  R       0:02      1 compute-2
                 6 compute-q  test.sh ec2-user  R       0:02      1 compute-3
                 7 compute-q  test.sh ec2-user  R       0:02      1 compute-4
                 8 compute-q  test.sh ec2-user  R       1:01      1 compute-1

複数ノードの同時再起動

ASAP オプションを使用して、4 台すべてを同時に再起動します。

$ sudo /opt/slurm/bin/scontrol reboot ASAP compute-1,compute-2,compute-3,compute-4

ジョブ実行中のため、ノードの State は REBOOT_REQUESTED となり、再起動リクエストを受け取った状態になります。

$ scontrol show node compute-1
NodeName=compute-1 Arch=x86_64 CoresPerSocket=1
   CPUAlloc=1 CPUEfctv=1 CPUTot=1 CPULoad=0.10
   AvailableFeatures=compute
   ActiveFeatures=compute
   Gres=(null)
   NodeAddr=10.0.11.195 NodeHostName=ip-10-0-11-195 Version=25.05.3
   OS=Linux 5.10.244-240.965.amzn2.x86_64 #1 SMP Sat Sep 20 21:53:12 UTC 2025
   RealMemory=7782 AllocMem=0 FreeMem=5976 Sockets=1 Boards=1
   State=ALLOCATED+CLOUD+REBOOT_REQUESTED ThreadsPerCore=1 TmpDisk=0 Weight=1 Owner=N/A MCS_label=N/A
   Partitions=compute-queue
   BootTime=2025-10-24T05:26:06 SlurmdStartTime=2025-10-24T05:31:01
   LastBusyTime=2025-10-24T05:36:18 ResumeAfterTime=None
   CfgTRES=cpu=1,mem=7782M,billing=1
   AllocTRES=cpu=1
   CurrentWatts=0 AveWatts=0
   Reason=reboot requested [root@2025-10-24T05:38:33]
   InstanceId=[2025-10-24T05:27:09.792+00:00] InstanceType=-

新規ジョブ投入時の挙動

この状態で新しいジョブを投入してみます。

$ squeue
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
                 9 compute-q  test.sh ec2-user PD       0:00      1 (Resources)
                 5 compute-q  test.sh ec2-user  R       1:27      1 compute-2
                 6 compute-q  test.sh ec2-user  R       1:27      1 compute-3
                 7 compute-q  test.sh ec2-user  R       1:27      1 compute-4
                 8 compute-q  test.sh ec2-user  R       2:26      1 compute-1

新しいジョブ(Job ID: 9)は Pending 状態で受け付けられました。

再起動の進行とジョブの実行

しばらくすると、compute-1 から compute-3 が再起動中(boot^)、compute-4 がドレイン中(drng@)となり、compute-4 で新しいジョブが実行されています。

$ sinfo
PARTITION     AVAIL  TIMELIMIT  NODES  STATE NODELIST
compute-queue    up   infinite      3  boot^ compute-[1-3]
compute-queue    up   infinite      1  drng@ compute-4

$ squeue
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
                 9 compute-q  test.sh ec2-user  R       0:15      1 compute-4

ASAP オプションを使用すると、ジョブ 9 は再起動後に実行されるものかと想定していました。どうやらジョブをサブミットするタイミングが早かったのかもしれません。ドレイン中のステータスを確認してからジョブをサブミットすれば、ジョブの実行はされなかったものと思われます。

まとめ

AWS PCS で Slurm ノード再起動機能がサポートされ、インスタンス置換を伴わないノード再起動が可能になりました。

この機能により、以下が実現できます。

  • キャパシティに懸念のあるインスタンスの維持
  • 不要なインスタンス置換にかかる時間の節約(コスト削減)

おわりに

GPU インスタンスをオンデマンド利用しているときには助かる再起動方法でした。最近ですとオンデマンド起動でもキャパシティ不足を引くことが多いため、せっかく掴めたリソースを停止して解放してしまうと、新規に起動できる保証もなかったので、なにか問題を感じて再起動したいときにはとてもありがたい機能でした。

参考

この記事をシェアする

FacebookHatena blogX

関連記事