AWS ParallelCluster のコンピュートノードのインスタンス ID からジョブ ID を特定する方法

2024.05.06

AWS ParallelCluster を使用してジョブを実行した後、EC2 インスタンスのパフォーマンスを確認するために CloudWatch をたびたび確認します。CloudWatch のメトリクスからは EC2 のインスタンス ID を確認できますが、どのインスタンスがどのジョブの実行に使用されたのかを特定するのは難しいです。

本記事では、EC2 のインスタンス ID から Slurm のジョブ ID を特定する 2 つの方法を紹介します。

背景

ジョブをサブミットすると、コンピュートノード(EC2 インスタンス)で処理が行われます。実行したアプリケーションの特性に合わせてインスタンスタイプを最適化するには、実行時の CPU 使用率やディスク I/O などを確認する必要があります。

しかし、CloudWatch のメトリクスからインスタンス ID は確認できます。ただし、どのインスタンスがどのジョブを実行したのかを特定するのは難しいです。

CPU 使用率を例に説明します。すべてのインスタンス ID にチェックを入れて、該当の時間帯に CPU 使用率が高いインスタンス ID をある程度絞り込めます。

1 台だけヒットすれば特定に至るのですが、今回のキャプチャの様に複数台実行していた場合はどのインスタンス ID がなんのジョブを実行していたか確認できないと困ります。そこで確認方法を 2 つ紹介します。

CloudWatch Logsを使用してジョブIDを特定する

CloudWatch のメトリクスを確認する際、マネージメントコンソールから直接確認できると便利です。

ParallelCluster のクラスター作成時に規定で作成される CloudWatch Logs のロググループ/aws/parallelcluster/[クラスター名]を開きます。CloudWatch のメトリクスから確認したインスタンス ID をログストリームから検索し、末尾に.slurmdのログストリームを開きます。

ログイベントのメッセージの中からジョブ ID を確認できます。

ジョブ ID からインスタンス ID の逆引き方法

また、ジョブ ID からインスタンス ID を逆引きも可能です。すべてのログストリームを検索し、"jobID [番号]" で検索します。

メッセージからジョブを実行した EC2 のインスタンス ID を確認できます。

ヘッドノードのSlurmログからジョブIDを特定する

ヘッドノードにログインし、/var/log/parallelcluster/slurm_resume.logの中から該当のインスタンス ID を検索します。

grep '[インスタンス ID]' /var/log/parallelcluster/slurm_resume.log

出力結果には、指定したインスタンス ID に関連するログエントリが表示されます。例えば、インスタンス ID i-036b02fc6b18107d7 はジョブ ID 17 の実行に使用されたことがわかります。ログエントリにはインスタンスの起動時刻や Slurm ノードの設定情報なども含まれており、ジョブの実行状況をより詳細に把握できます。

$ grep 'i-036b02fc6b18107d7' /var/log/parallelcluster/slurm_resume.log

2024-05-05 00:50:11,123 - 6763 - [slurm_plugin.fleet_manager:launch_ec2_instances] - INFO - JobID 17 - Launched the following instances (x1) ['i-036b02fc6b18107d7']
2024-05-05 00:50:12,055 - 6763 - [slurm_plugin.instance_manager:_update_slurm_node_addrs] - INFO - JobID 17 - Nodes are now configured with instances (x1) ["('p2-dy-m6id8xlarge-1', EC2Instance(id='i-036b02fc6b18107d7', private_ip='10.0.2.110', hostname='ip-10-0-2-110', all_private_ips={'10.0.2.110'}, launch_time=datetime.datetime(2024, 5, 5, 0, 50, 9, tzinfo=tzlocal()), slurm_node=None))"]

ジョブ ID からインスタンス ID の逆引き方法

また、ジョブ ID からインスタンス ID を逆引きも可能です。以下のコマンドで/var/log/parallelcluster/ディレクトリ内のすべてのファイルから、指定したジョブ ID に関連するログエントリを検索できます。

$ sudo find /var/log/parallelcluster/ -type f -print | sudo xargs grep 'JobID [番号]'

出力結果には、ジョブ ID に対応するインスタンス ID が含まれています。これにより、ジョブを実行したインスタンス ID を特定できます。

$ sudo find /var/log/parallelcluster/ -type f -print | sudo xargs grep 'JobID 17'

/var/log/parallelcluster/slurm_resume.log:2024-05-05 00:50:07,933 - 6763 - [slurm_plugin.instance_manager:_scaling_for_jobs] - INFO - JobID 17 - The nodes_resume list from Slurm Resume File is (x1) ['p2-dy-m6id8xlarge-1']
/var/log/parallelcluster/slurm_resume.log:2024-05-05 00:50:07,933 - 6763 - [slurm_plugin.instance_manager:_launch_instances] - INFO - JobID 17 - Launching all-or-nothing instances for nodes (x1) ['p2-dy-m6id8xlarge-1']
/var/log/parallelcluster/slurm_resume.log:2024-05-05 00:50:07,934 - 6763 - [slurm_plugin.fleet_manager:create_fleet] - INFO - JobID 17 - Launching instances with create_fleet API. Parameters: {'LaunchTemplateConfigs': [{'LaunchTemplateSpecification': {'LaunchTemplateName': 'apptainer-t3head-p2-m6id8xlarge', 'Version': '$Latest'}, 'Overrides': [{'InstanceType': 'm6id.8xlarge', 'SubnetId': 'subnet-0c82bb28e119e2aa8'}, {'InstanceType': 'm6id.8xlarge', 'SubnetId': 'subnet-0296a0c8515ed3bdc'}, {'InstanceType': 'm6id.8xlarge', 'SubnetId': 'subnet-0089ff187d1f54258'}]}], 'TargetCapacitySpecification': {'TotalTargetCapacity': 1, 'DefaultTargetCapacityType': 'spot'}, 'Type': 'instant', 'SpotOptions': {'SingleInstanceType': True, 'SingleAvailabilityZone': False, 'AllocationStrategy': 'capacity-optimized', 'MinTargetCapacity': 1}}
/var/log/parallelcluster/slurm_resume.log:2024-05-05 00:50:11,123 - 6763 - [slurm_plugin.fleet_manager:launch_ec2_instances] - INFO - JobID 17 - Launched the following instances (x1) ['i-036b02fc6b18107d7']
/var/log/parallelcluster/slurm_resume.log:2024-05-05 00:50:11,123 - 6763 - [slurm_plugin.instance_manager:_add_instances_for_nodes] - INFO - JobID 17 - Assigning nodes with all-or-nothing strategy
/var/log/parallelcluster/slurm_resume.log:2024-05-05 00:50:11,124 - 6763 - [slurm_plugin.instance_manager:_store_assigned_hostnames] - INFO - JobID 17 - Saving assigned hostnames in DynamoDB
/var/log/parallelcluster/slurm_resume.log:2024-05-05 00:50:11,213 - 6763 - [slurm_plugin.instance_manager:_update_dns_hostnames] - INFO - JobID 17 - Updating DNS records for Z057675628I43KT7H07Q0 - apptainer-t3head.pcluster.
/var/log/parallelcluster/slurm_resume.log:2024-05-05 00:50:12,055 - 6763 - [slurm_plugin.instance_manager:_update_slurm_node_addrs] - INFO - JobID 17 - Nodes are now configured with instances (x1) ["('p2-dy-m6id8xlarge-1', EC2Instance(id='i-036b02fc6b18107d7', private_ip='10.0.2.110', hostname='ip-10-0-2-110', all_private_ips={'10.0.2.110'}, launch_time=datetime.datetime(2024, 5, 5, 0, 50, 9, tzinfo=tzlocal()), slurm_node=None))"]
/var/log/parallelcluster/slurm_resume.log:2024-05-05 00:50:12,056 - 6763 - [slurm_plugin.instance_manager:_all_or_nothing_node_assignment] - INFO - JobID 17 - Successful launched and assigned all instances for nodes (x1) ['p2-dy-m6id8xlarge-1']

CloudTrail からジョブ ID は確認できるのか

CloudTrail のログには Slurm のジョブ ID までは記録されていませんでした。EC2 内のログ(Slurm のログ)を確認するか、CloudWatch Logs へ保存されているログを確認するしか方法はないようです。

RunInstances イベントを確認しました。

しかし、RunInstances イベントのログにはジョブ ID に関する情報は含まれていませんでした。

{
    "eventVersion": "1.09",
    "userIdentity": {
        "type": "AssumedRole",
        "principalId": "AROATXZ233RSHCRKIDAIR:i-0abb343155c40b7f7",
        "arn": "arn:aws:sts::123456789012:assumed-role/apptainer-t3head-RoleHeadNode-LM6gVKQDBnvi/i-0abb343155c40b7f7",
        "accountId": "123456789012",
        "sessionContext": {
            "sessionIssuer": {
                "type": "Role",
                "principalId": "AROATXZ233RSHCRKIDAIR",
                "arn": "arn:aws:iam::123456789012:role/parallelcluster/apptainer-t3head/apptainer-t3head-RoleHeadNode-LM6gVKQDBnvi",
                "accountId": "123456789012",
                "userName": "apptainer-t3head-RoleHeadNode-LM6gVKQDBnvi"
            },
            "attributes": {
                "creationDate": "2024-05-05T00:08:35Z",
                "mfaAuthenticated": "false"
            },
            "ec2RoleDelivery": "2.0"
        },
        "invokedBy": "ec2fleet.amazonaws.com"
    },
    "eventTime": "2024-05-05T00:50:09Z",
    "eventSource": "ec2.amazonaws.com",
    "eventName": "RunInstances",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "ec2fleet.amazonaws.com",
    "userAgent": "ec2fleet.amazonaws.com",
    "requestParameters": {
        "instancesSet": {
            "items": [
                {
                    "minCount": 1,
                    "maxCount": 1
                }
            ]
        },
        "instanceType": "m6id.8xlarge",
        "blockDeviceMapping": {},
        "availabilityZone": "ap-northeast-1c",
        "monitoring": {
            "enabled": false
        },
        "disableApiTermination": false,
        "disableApiStop": false,
        "clientToken": "fleet-e695b407-292f-ee94-26b0-878af7c3dbb7-0",
        "networkInterfaceSet": {
            "items": [
                {
                    "deviceIndex": 0,
                    "subnetId": "subnet-0296a0c8515ed3bdc",
                    "networkCardIndex": 0
                }
            ]
        },
        "tagSpecificationSet": {
            "items": [
                {
                    "resourceType": "instance",
                    "tags": [
                        {
                            "key": "aws:ec2:fleet-id",
                            "value": "fleet-e695b407-292f-ee94-26b0-878af7c3dbb7"
                        }
                    ]
                }
            ]
        },
        "launchTemplate": {
            "launchTemplateId": "lt-0cfc4f4aff2af14fd",
            "version": "1"
        },
        "instanceMarketOptions": {
            "marketType": "spot",
            "spotOptions": {
                "spotInstanceType": "one-time"
            }
        }
    },
    "responseElements": {
        "requestId": "47f38b86-1114-4b82-a6a8-74af72386243",
        "reservationId": "r-04ac251e43c1f6ccc",
        "ownerId": "123456789012",
        "groupSet": {},
        "instancesSet": {
            "items": [
                {
                    "instanceId": "i-036b02fc6b18107d7",
                    "imageId": "ami-02bacf12a711cb07c",
                    "bootMode": "uefi-preferred",
                    "currentInstanceBootMode": "uefi",
                    "instanceState": {
                        "code": 0,
                        "name": "pending"
                    },
                    "privateDnsName": "ip-10-0-2-110.ap-northeast-1.compute.internal",
                    "amiLaunchIndex": 0,
                    "productCodes": {},
                    "instanceType": "m6id.8xlarge",
                    "launchTime": 1714870209000,
                    "placement": {
                        "availabilityZone": "ap-northeast-1c",
                        "tenancy": "default"
                    },
                    "monitoring": {
                        "state": "disabled"
                    },
                    "subnetId": "subnet-0296a0c8515ed3bdc",
                    "vpcId": "vpc-0488d8abb33ada1dc",
                    "privateIpAddress": "10.0.2.110",
                    "stateReason": {
                        "code": "pending",
                        "message": "pending"
                    },
                    "architecture": "x86_64",
                    "rootDeviceType": "ebs",
                    "rootDeviceName": "/dev/sda1",
                    "blockDeviceMapping": {},
                    "virtualizationType": "hvm",
                    "hypervisor": "xen",
                    "spotInstanceRequestId": "sir-q416twbm",
                    "instanceLifecycle": "spot",
                    "tagSet": {
                        "items": [
                            {
                                "key": "aws:ec2:fleet-id",
                                "value": "fleet-e695b407-292f-ee94-26b0-878af7c3dbb7"
                            },
                            {
                                "key": "aws:ec2launchtemplate:id",
                                "value": "lt-0cfc4f4aff2af14fd"
                            },
                            {
                                "key": "aws:ec2launchtemplate:version",
                                "value": "1"
                            },
                            {
                                "key": "parallelcluster:version",
                                "value": "3.9.1"
                            },
                            {
                                "key": "parallelcluster:compute-resource-name",
                                "value": "m6id8xlarge"
                            },
                            {
                                "key": "parallelcluster:node-type",
                                "value": "Compute"
                            },
                            {
                                "key": "Name",
                                "value": "Compute"
                            },
                            {
                                "key": "parallelcluster:cluster-name",
                                "value": "apptainer-t3head"
                            },
                            {
                                "key": "parallelcluster:attributes",
                                "value": "ubuntu2204, slurm, 3.9.1, NONE"
                            },
                            {
                                "key": "parallelcluster:filesystem",
                                "value": "efs=2, multiebs=0, raid=0, fsx=0"
                            },
                            {
                                "key": "parallelcluster:networking",
                                "value": "EFA=NONE"
                            },
                            {
                                "key": "parallelcluster:queue-name",
                                "value": "p2"
                            }
                        ]
                    },
                    "clientToken": "fleet-e695b407-292f-ee94-26b0-878af7c3dbb7-0",
                    "groupSet": {
                        "items": [
                            {
                                "groupId": "sg-00b82642f532d9398",
                                "groupName": "apptainer-t3head-ComputeSecurityGroup-SvATKOcaz7rX"
                            }
                        ]
                    },
                    "sourceDestCheck": true,
                    "networkInterfaceSet": {
                        "items": [
                            {
                                "networkInterfaceId": "eni-035c22ae637f9f8ae",
                                "subnetId": "subnet-0296a0c8515ed3bdc",
                                "vpcId": "vpc-0488d8abb33ada1dc",
                                "ownerId": "123456789012",
                                "status": "in-use",
                                "macAddress": "0a:0b:1a:27:e6:29",
                                "privateIpAddress": "10.0.2.110",
                                "privateDnsName": "ip-10-0-2-110.ap-northeast-1.compute.internal",
                                "sourceDestCheck": true,
                                "interfaceType": "interface",
                                "groupSet": {
                                    "items": [
                                        {
                                            "groupId": "sg-00b82642f532d9398",
                                            "groupName": "apptainer-t3head-ComputeSecurityGroup-SvATKOcaz7rX"
                                        }
                                    ]
                                },
                                "attachment": {
                                    "attachmentId": "eni-attach-034eecc7ce2fea2ee",
                                    "deviceIndex": 0,
                                    "networkCardIndex": 0,
                                    "status": "attaching",
                                    "attachTime": 1714870209000,
                                    "deleteOnTermination": true
                                },
                                "privateIpAddressesSet": {
                                    "item": [
                                        {
                                            "privateIpAddress": "10.0.2.110",
                                            "privateDnsName": "ip-10-0-2-110.ap-northeast-1.compute.internal",
                                            "primary": true
                                        }
                                    ]
                                },
                                "ipv6AddressesSet": {},
                                "tagSet": {}
                            }
                        ]
                    },
                    "iamInstanceProfile": {
                        "arn": "arn:aws:iam::123456789012:instance-profile/parallelcluster/apptainer-t3head/apptainer-t3head-ComputeFleetQueuesNestedStackQueuesNestedStackResource4C142E85-1NF-InstanceProfileC5fd961c9f737a95-Evkc7a3sPrDa",
                        "id": "AIPATXZ233RSGF54T4RGA"
                    },
                    "ebsOptimized": true,
                    "enaSupport": true,
                    "cpuOptions": {
                        "coreCount": 16,
                        "threadsPerCore": 2
                    },
                    "capacityReservationSpecification": {
                        "capacityReservationPreference": "open"
                    },
                    "enclaveOptions": {
                        "enabled": false
                    },
                    "metadataOptions": {
                        "state": "pending",
                        "httpTokens": "required",
                        "httpPutResponseHopLimit": 1,
                        "httpEndpoint": "enabled",
                        "httpProtocolIpv4": "enabled",
                        "httpProtocolIpv6": "disabled",
                        "instanceMetadataTags": "disabled"
                    },
                    "maintenanceOptions": {
                        "autoRecovery": "default"
                    },
                    "privateDnsNameOptions": {
                        "hostnameType": "ip-name",
                        "enableResourceNameDnsARecord": false,
                        "enableResourceNameDnsAAAARecord": false
                    }
                }
            ]
        },
        "requesterId": "216214693835"
    },
    "requestID": "47f38b86-1114-4b82-a6a8-74af72386243",
    "eventID": "dd7732de-da87-4176-affe-e76c9ea39bd9",
    "readOnly": false,
    "eventType": "AwsApiCall",
    "managementEvent": true,
    "recipientAccountId": "123456789012",
    "eventCategory": "Management"
}

まとめ

本記事では、AWS ParallelCluster を使用してジョブを実行した後、EC2 インスタンス ID から Slurm のジョブ ID を特定する 2 つの方法を紹介しました。

  1. CloudWatch Logs を使用する方法
  2. ヘッドノードの Slurm ログを使用する方法

これらの方法を活用することで、ジョブ実行中のコンピュートノード(EC2 インスタンス)のパフォーマンス分析に取りかかれます。

おわりに

検証のために複数のコンピュートノードで個別に処理していました。しかし、実行が終わってからメトリクスを確認しようとしたところ、どのインスタンスがどのジョブで実行していたのかわからなくなってしまいました。ちなみにコンピュートノードの EC2 は実行が終わったら削除されてしまうため、EC2 のダッシュボードからは追えません。ログを漁ってたら見つかったので確認方法をまとめておきました。