

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 关于如何使用的教程 AWS ParallelCluster
<a name="tutorials-v3"></a>

以下教程向您展示了如何开始使用 AWS ParallelCluster 版本 3，并为一些常见任务提供了最佳实践指导。

使用 AWS ParallelCluster 命令行界面 (CLI) 或 API 时，您只需为创建或更新 AWS ParallelCluster 映像和集群时创建的 AWS 资源付费。有关更多信息，请参阅 [AWS 使用的服务 AWS ParallelCluster](aws-services-v3.md)。

**Topics**
+ [

# 在上运行你的第一份作业 AWS ParallelCluster
](tutorials-running-your-first-job-on-version-3.md)
+ [

# 构建自定义 AWS ParallelCluster AMI
](building-custom-ami-v3.md)
+ [

# 集成 Active Directory
](tutorials_05_multi-user-ad.md)
+ [

# 使用密 AWS KMS 钥配置共享存储加密
](tutorials_04_encrypted_kms_fs-v3.md)
+ [

# 在多队列模式集群中运行作业
](multi-queue-tutorial-v3.md)
+ [

# 使用 AWS ParallelCluster API
](tutorials_06_API_use.md)
+ [

# 使用创建集群 Slurm 会计
](tutorials_07_slurm-accounting-v3.md)
+ [

# 使用外部集群创建集群 Slurmdbd 会计
](external-slurmdb-accounting.md)
+ [

# 恢复到以前的 S AWS ystems Manager 文档版本
](tutorials_08_ssm-document-version-rev-v3.md)
+ [

# 使用创建集群 CloudFormation
](tutorials_09_cfn-custom-resource-v3.md)
+ [

# 使用 Terraform 部署 ParallelCluster API
](tutorial-deploy-terraform.md)
+ [

# 使用 Terraform 创建集群
](tutorial-create-cluster-terraform.md)
+ [

# 使用 Terraform 创建自定义 AMI
](tutorial-create-ami-terraform.md)
+ [

# AWS ParallelCluster 用户界面与身份中心集成
](tutorials_10_pcui-aws-ic-integration-v3.md)
+ [使用 Pyxis 运行容器化作业](tutorials_11_running-containerized-jobs-with-pyxis.md)
+ [

# 创建具有启用 EFA 的 Lustre FSx 的集群
](tutorial-efa-enabled-fsx-lustre.md)
+ [

# 使用 p6e-gb200 实例支持 nvidia-imex
](support-nvidia-imex-p6e-gb200-instance.md)
+ [

# 使用启动模板覆盖自定义计算节点网络接口
](tutorial-network-customization-v3.md)

# 在上运行你的第一份作业 AWS ParallelCluster
<a name="tutorials-running-your-first-job-on-version-3"></a>

本教程将引导你完成在上面运行第一个 Hello World 作业 AWS ParallelCluster

使用 AWS ParallelCluster 命令行界面 (CLI) 或 API 时，您只需为创建或更新 AWS ParallelCluster 映像和集群时创建的 AWS 资源付费。有关更多信息，请参阅 [AWS 使用的服务 AWS ParallelCluster](aws-services-v3.md)。

**先决条件**
+ AWS ParallelCluster [已安装](install-v3-parallelcluster.md)。
+  AWS CLI [已安装并配置。](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ 您有一个 [Amazon EC2 密钥对](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html)。
+ 您拥有具有运行 [`pcluster`](pcluster-v3.md) CLI 所需的[权限](iam-roles-in-parallelcluster-v3.md#iam-roles-in-parallelcluster-v3-example-user-policies)的 IAM 角色。

## 验证安装
<a name="tutorial-1stjob-verify-install"></a>

 首先，我们验证安装和配置 AWS ParallelCluster 是否正确，包括 Node.js 依赖项。

```
$ node --version
v16.8.0
$ pcluster version
{
  "version": "3.15.0"
}
```

这将返回的正在运行的版本 AWS ParallelCluster。

## 创建您的第一个集群
<a name="tutorial-1stjob-first-cluster"></a>

现在应该创建您的第一个集群了。由于本教程的工作负载不是性能密集型的，因此，我们可以使用 `t2.micro` 的默认实例大小。（对于生产工作负载，您需要选择最适合您的需求的实例大小。） 我们将您的集群命名为 `hello-world`。

```
$ pcluster create-cluster \
    --cluster-name hello-world \
    --cluster-configuration hello-world.yaml
```

**注意**  
必须 AWS 区域 为大多数`pcluster`命令指定要使用的。如果未在 `AWS_DEFAULT_REGION` 环境变量或 `~/.aws/config` 文件 `[default]` 部分的 `region` 设置中指定，则必须在 `pcluster` 命令行中提供 `--region` 参数。

如果输出为您提供有关配置的消息，您将需要运行以下命令来配置 AWS ParallelCluster：

```
$ pcluster configure --config hello-world.yaml
```

 如果 [`pcluster create-cluster`](pcluster.create-cluster-v3.md) 命令成功，则将显示类似于以下内容的输出：

```
{
  "cluster": {
    "clusterName": "hello-world",
    "cloudformationStackStatus": "CREATE_IN_PROGRESS",
    "cloudformationStackArn": "arn:aws:cloudformation:xxx:stack/xxx",
    "region": "...",
    "version": "...",
    "clusterStatus": "CREATE_IN_PROGRESS"
  }
}
```

 您可以使用以下命令监控集群的创建：

```
$ pcluster describe-cluster --cluster-name hello-world
```

 正在创建集群时，`clusterStatus` 会报告“`CREATE_IN_PROGRESS`”。成功创建集群后，`clusterStatus` 将转变为“`CREATE_COMPLETE`”。输出还为我们提供头节点的 `publicIpAddress` 和 `privateIpAddress`。

## 登录到头节点
<a name="tutorial-1stjob-logging-in-head-node"></a>

 使用您的 OpenSSH pem 文件登录到头节点。

```
$ pcluster ssh --cluster-name hello-world -i /path/to/keyfile.pem
```

 登录后，请运行命令 `sinfo` 以验证您的计算节点是否已设置和配置。

```
$ sinfo
PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST
queue1*      up   infinite     10  idle~ queue1-dy-queue1t2micro-[1-10]
```

 输出显示我们的集群中有一个队列，最多包含十个节点。

## 使用 Slurm 运行首个作业
<a name="tutorial-1stjob-first-slurm-job"></a>

接下来，我们将创建一个作业，该作业睡眠一小段时间，然后输出它自己的主机名。使用以下内容创建名为 `hellojob.sh` 的文件。

```
#!/bin/bash
sleep 30
echo "Hello World from $(hostname)"
```

 接下来，使用 `sbatch` 提交作业，并验证其是否运行。

```
$ sbatch hellojob.sh
Submitted batch job 2
```

 现在，您可以查看您的队列并检查该作业的状态。新 Amazon EC2 实例的预置在后台启动。您可以使用 `sinfo` 命令监控集群实例的状态。

```
$ squeue
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
                 2    queue1 hellojob ec2-user CF       3:30      1 queue1-dy-queue1t2micro-1
```

 输出显示作业已提交给 `queue1`。请等候 30 秒，以便作业完成，然后再次运行 `squeue`。

```
$ squeue
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
```

 现在，队列中没有作业，我们可以检查当前目录中的输出。

```
$ ls -l
total 8
-rw-rw-r-- 1 ec2-user ec2-user 57 Sep  1 14:25 hellojob.sh
-rw-rw-r-- 1 ec2-user ec2-user 43 Sep  1 14:30 slurm-2.out
```

 在输出中，我们看到一个“`out`”文件。我们可以查看作业的输出：

```
$ cat slurm-2.out
Hello World from queue1-dy-queue1t2micro-1
```

输出还显示我们的作业已在实例 `queue1-dy-queue1t2micro-1` 上成功运行。

在刚创建的集群中，只有主目录在集群的所有节点之间共享。

要了解有关创建和使用集群的更多信息，请参阅[最佳实践](best-practices-v3.md)。

如果您的应用程序需要共享软件、库或数据，请考虑以下选项：
+ 如中所述，构建包含您的软件的 AWS ParallelCluster 已启用的自定义 AMI [构建自定义 AWS ParallelCluster AMI](building-custom-ami-v3.md)。
+ 使用 AWS ParallelCluster 配置文件中的[StorageSettings](SharedStorage-v3.md)选项来指定共享文件系统并将已安装的软件存储在指定的装载位置。
+ 使用[自定义引导操作](custom-bootstrap-actions-v3.md)自动执行集群中每个节点的引导过程。

# 构建自定义 AWS ParallelCluster AMI
<a name="building-custom-ami-v3"></a>

使用 AWS ParallelCluster 命令行界面 (CLI) 或 API 时，您只需为创建或更新 AWS ParallelCluster 映像和集群时创建的 AWS 资源付费。有关更多信息，请参阅 [AWS 使用的服务 AWS ParallelCluster](aws-services-v3.md)。

**重要**  
如果构建自定义 AMI，则必须重复执行用于随每个新的 AWS ParallelCluster 版本创建自定义 AMI 的步骤。

在进一步阅读之前，我们建议您首先查看[自定义引导操作](custom-bootstrap-actions-v3.md)一节。确定未来 AWS ParallelCluster 版本是否可以脚本化并支持您要进行的修改。

尽管通常构建自定义 AMI 并不理想，但在某些特定场景中，需要 AWS ParallelCluster 为其构建自定义 AMI。本教程介绍如何为这些场景构建自定义 AMI。

**先决条件**
+ AWS ParallelCluster [已安装](install-v3-parallelcluster.md)。
+  AWS CLI [已安装并配置。](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ 您有一个 [Amazon EC2 密钥对](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html)。
+ 您拥有具有运行 [`pcluster`](pcluster-v3.md) CLI 和构建映像所需的[权限](iam-roles-in-parallelcluster-v3.md#iam-roles-in-parallelcluster-v3-example-user-policies)的 IAM 角色。

## 如何自定义 AWS ParallelCluster AMI
<a name="how-to-customize-the-aws-parallelcluster-ami-v3"></a>

有两种方法可以构建自定义 AWS ParallelCluster AMI。这两种方法之一是使用 CLI 构建新 AM AWS ParallelCluster I。另一种方法需要进行手动修改以构建可在您的 AWS 账户下使用的新 AMI。

## 构建自定义 AWS ParallelCluster AMI
<a name="build-a-custom-aws-parallelcluster-ami-v3"></a>

如果您有自定义 AMI 和软件，则可以在其 AWS ParallelCluster 上应用所需的更改。 AWS ParallelCluster 依靠 EC2 Image Builder 服务进行自定义构建 AMIs。有关更多信息，请参阅 [Image Builder User Guide](https://docs.aws.amazon.com/imagebuilder/latest/userguide/what-is-image-builder.html)。

关键点：
+ 该过程需要 1 小时左右的时间。如果在构建时需要安装其他[`Build`](Build-v3.md)/[`Components`](Build-v3.md#Build-v3-Components)，则此时间可能会有所不同。
+ AMI 标有主要组件的版本。其中包括内核、调度器和 [EFA](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa.html) 驱动程序。还会在 AMI 描述中报告一部分组件版本。
+ 从 AWS ParallelCluster 3.0.0 开始，可以使用一组新的 CLI 命令来管理映像的生命周期。这包括 [`build-image`](pcluster.build-image-v3.md)、[`list-images`](pcluster.list-images-v3.md)、[`describe-image`](pcluster.describe-image-v3.md) 和 [`delete-image`](pcluster.delete-image-v3.md)。
+ 这种方法是可重复的。您可以重新运行它以保持 AMIs 更新（例如，操作系统更新），然后在更新现有集群时使用它们。

**注意**  
如果你 AWS 在中国分区中使用这种方法，你可能会遇到网络错误。例如，当`pcluster build-image`命令从操作系统存储库 GitHub 或从操作系统存储库下载软件包时，您可能会看到这些错误。如果发生这种情况，我们建议使用以下替代方法之一：  
按照[修改 AWS ParallelCluster AMI](#modify-an-aws-parallelcluster-ami-v3) 方法绕过此命令。
在另一个分区和区域（例如）中构建映像`us-east-1`，然后 store/restore 将其移动到中国区域。有关更多信息，请参阅《Amazon EC2 用户指南》**中的[使用 S3 存储和还原 AMI](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ami-store-restore.html)。

步骤：

1. 配置您的 AWS 账户 证书，以便 AWS ParallelCluster 客户端可以代表您调用 AWS API 操作。有关所需权限的列表，请参阅[AWS Identity and Access Management 中的权限 AWS ParallelCluster](iam-roles-in-parallelcluster-v3.md)。

1. 创建基本的*构建映像* 配置文件。为此，请指定用于构建映像以及 [`ParentImage`](Build-v3.md#yaml-build-image-Build-ParentImage) 的 [`InstanceType`](Build-v3.md#yaml-build-image-Build-InstanceType)。这些步骤用作创建 AMI 的起点。有关可选构建参数的更多信息，请参阅[映像配置](image-builder-configuration-file-v3.md)。

   ```
   Build:
    InstanceType: <BUILD_INSTANCE_TYPE>
    ParentImage: <BASE_AMI_ID>
   ```

1. 使用 CLI 命令[`pcluster build-image`](pcluster.build-image-v3.md)从您作为基础提供的 AMI 开始构建 AMI。 AWS ParallelCluster 

   ```
   $ pcluster build-image --image-id IMAGE_ID --image-configuration IMAGE_CONFIG.yaml --region REGION
       {
    "image": {
      "imageId": "IMAGE_ID",
      "imageBuildStatus": "BUILD_IN_PROGRESS",
      "cloudformationStackStatus": "CREATE_IN_PROGRESS",
      "cloudformationStackArn": "arn:aws:cloudformation:us-east-1:123456789012:stack/IMAGE_ID/abcd1234-ef56-gh78-ij90-1234abcd5678",
      "region": "us-east-1",
      "version": "3.15.0"
    }
   }
   ```
**警告**  
`pcluster build-image` 使用默认 VPC。如果您使用 AWS Control Tower 或 AWS 着陆区删除默认 VPC，则必须在映像配置文件中指定子网 ID。有关更多信息，请参阅 [`SubnetId`](HeadNode-v3.md#yaml-HeadNode-Networking-SubnetId)。

   有关其他参数的列表，请参阅 [`pcluster build-image`](pcluster.build-image-v3.md) 命令参考页面。前面命令的结果如下所述：
   + 堆 CloudFormation 栈是根据映像配置创建的。该堆栈包括构建所需的所有 EC2 Image Builder 资源。
   + 创建的资源包括可以向其添加自定义 Image Builder AWS ParallelCluster 组件的官方 Image Builder 组件。有关更多信息，请参阅 *EC2 Image Builder 用户指南中的使用 Image Builder* [创建自定义组件](https://docs.aws.amazon.com/imagebuilder/latest/userguide/create-component.html)。
   + EC2 Image Builder 启动构建实例、应用说明 AWS ParallelCluster 书、安装 AWS ParallelCluster 软件堆栈并执行必要的配置任务。 AWS ParallelCluster 这本食谱用于构建和引导 AWS ParallelCluster。
   + 停止该实例，并在其基础上创建新的 AMI。
   + 从新创建的 AMI 启动另一个实例。在测试阶段，EC2 Image Builder 会运行 Image Builder 组件中定义的测试。
   + 如果构建成功，则会删除堆栈。如果构建失败，则会保留堆栈以供检查。

1. 您可以通过运行以下命令来监控构建过程的状态。构建完成后，您可以运行该 AMI 以便检索响应中给出的 AMI ID。

   ```
   $ pcluster describe-image --image-id IMAGE_ID --region REGION
       
   # BEFORE COMPLETE
   {
    "imageConfiguration": {
      "url": "https://parallelcluster-1234abcd5678efgh-v1-do-not-delete.s3.amazonaws.com/parallelcluster/3.15.0/images/IMAGE_ID-abcd1234efgh5678/configs/image-config.yaml?...",
    },
    "imageId": "IMAGE_ID",
    "imagebuilderImageStatus": "BUILDING",
    "imageBuildStatus": "BUILD_IN_PROGRESS",
    "cloudformationStackStatus": "CREATE_IN_PROGRESS",
    "cloudformationStackArn": "arn:aws:cloudformation:us-east-1:123456789012:stack/IMAGE_ID/abcd1234-ef56-gh78-ij90-1234abcd5678",
    "region": "us-east-1",
    "version": "3.15.0",
    "cloudformationStackTags": [
      {
        "value": "3.15.0",
        "key": "parallelcluster:version"
      },
      {
        "value": "IMAGE_ID",
        "key": "parallelcluster:image_name"
      },
      ...
    ],
    "imageBuildLogsArn": "arn:aws:logs:us-east-1:123456789012:log-group:/aws/imagebuilder/ParallelClusterImage-IMAGE_ID",
    "cloudformationStackCreationTime": "2022-04-05T21:36:26.176Z"
   }
   
   # AFTER COMPLETE
   {
    "imageConfiguration": {
      "url": "https://parallelcluster-1234abcd5678efgh-v1-do-not-delete.s3.us-east-1.amazonaws.com/parallelcluster/3.15.0/images/IMAGE_ID-abcd1234efgh5678/configs/image-config.yaml?Signature=..."
    },
    "imageId": "IMAGE_ID",
    "imageBuildStatus": "BUILD_COMPLETE",
    "region": "us-east-1",
    "ec2AmiInfo": {
        "amiName": "IMAGE_ID 2022-04-05T21-39-24.020Z",
        "amiId": "ami-1234stuv5678wxyz",
        "description": "AWS ParallelCluster AMI for alinux2, kernel-4.14.238-182.422.amzn2.x86_64, lustre-2.10.8-5.amzn2.x86_64, efa-1.13.0-1.amzn2.x86_64, dcv-2021.1.10598-1.el7.x86_64, slurm-20-11-8-1",
        "state": "AVAILABLE",
        "tags": [
         {
           "value": "2021.3.11591-1.el7.x86_64",
           "key": "parallelcluster:dcv_version"
         },
         ...
        ],
      "architecture": "x86_64"
    },
    "version": "3.15.0"      
   }
   ```

1. 要创建集群，请在集群配置内的 [`CustomAmi`](Scheduling-v3.md#yaml-Scheduling-SlurmQueues-Image-CustomAmi) 字段中输入该 AMI ID。

**对 AMI 创建过程进行故障排除和监控**

映像创建将在大约一个小时后完成。您可以通过运行 [`pcluster describe-image`](pcluster.describe-image-v3.md) 命令或日志检索命令来监控该过程。

```
$ pcluster describe-image --image-id IMAGE_ID --region REGION
```

该[`build-image`](pcluster.build-image-v3.md)命令使用构建映像所需的所有 Amazon EC2 资源创建一个 CloudFormation 堆栈，并启动 EC2 Image Builder 流程。

运行该[`build-image`](pcluster.build-image-v3.md)命令后，可以使用来检索 CloudFormation 堆栈事件[`pcluster get-image-stack-events`](pcluster.get-image-stack-events-v3.md)。您可以使用 `--query` 参数来筛选结果，以查看最新事件。有关更多信息，请参阅《*AWS Command Line Interface 用户指南》*中的[筛选 AWS CLI 输出](https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-filter.html)。

```
$ pcluster get-image-stack-events --image-id IMAGE_ID --region REGION --query "events[0]"
{
 "eventId": "ParallelClusterImage-CREATE_IN_PROGRESS-2022-04-05T21:39:24.725Z",
 "physicalResourceId": "arn:aws:imagebuilder:us-east-1:123456789012:image/parallelclusterimage-IMAGE_ID/3.15.0/1",
 "resourceStatus": "CREATE_IN_PROGRESS",
 "resourceStatusReason": "Resource creation Initiated",
 "resourceProperties": "{\"InfrastructureConfigurationArn\":\"arn:aws:imagebuilder:us-east-1:123456789012:infrastructure-configuration/parallelclusterimage-abcd1234-ef56-gh78-ij90-1234abcd5678\",\"ImageRecipeArn\":\"arn:aws:imagebuilder:us-east-1:123456789012:image-recipe/parallelclusterimage-IMAGE_ID/3.15.0\",\"DistributionConfigurationArn\":\"arn:aws:imagebuilder:us-east-1:123456789012:distribution-configuration/parallelclusterimage-abcd1234-ef56-gh78-ij90-1234abcd5678\",\"Tags\":{\"parallelcluster:image_name\":\"IMAGE_ID\",\"parallelcluster:image_id\":\"IMAGE_ID\"}}",
 "stackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/IMAGE_ID/abcd1234-ef56-gh78-ij90-1234abcd5678",
 "stackName": "IMAGE_ID",
 "logicalResourceId": "ParallelClusterImage",
 "resourceType": "AWS::ImageBuilder::Image",
 "timestamp": "2022-04-05T21:39:24.725Z"
}
```

大约 15 分钟后，堆栈事件将出现在与 Image Builder 创建相关的日志事件条目中。您现在可以使用 [`pcluster list-image-log-streams`](pcluster.list-image-log-streams-v3.md) 和 [`pcluster get-image-log-events`](pcluster.get-image-log-events-v3.md) 命令列出映像日志流并监控 Image Builder 步骤。

```
$ pcluster list-image-log-streams --image-id IMAGE_ID --region REGION \
    --query 'logStreams[*].logStreamName'

 "3.15.0/1"
]

$ pcluster get-image-log-events --image-id IMAGE_ID --region REGION \
--log-stream-name 3.15.0/1 --limit 3
{
 "nextToken": "f/36295977202298886557255241372854078762600452615936671762",
 "prevToken": "b/36295977196879805474012299949460899222346900769983430672",
 "events": [
   {
     "message": "ExecuteBash: FINISHED EXECUTION",
     "timestamp": "2022-04-05T22:13:26.633Z"
   },
   {
     "message": "Document arn:aws:imagebuilder:us-east-1:123456789012:component/parallelclusterimage-test-abcd1234-ef56-gh78-ij90-1234abcd5678/3.15.0/1",
     "timestamp": "2022-04-05T22:13:26.741Z"
   },
   {
     "message": "TOE has completed execution successfully",
     "timestamp": "2022-04-05T22:13:26.819Z"
   }
 ]
}
```

继续使用 [`describe-image`](pcluster.describe-image-v3.md) 命令进行检查，直到看到 `BUILD_COMPLETE` 状态。

```
$ pcluster describe-image --image-id IMAGE_ID --region REGION
{
 "imageConfiguration": {
   "url": "https://parallelcluster-1234abcd5678efgh-v1-do-not-delete.s3.us-east-1.amazonaws.com/parallelcluster/3.15.0/images/IMAGE_ID-abcd1234efgh5678/configs/image-config.yaml?Signature=..."
 },
 "imageId": "IMAGE_ID",
 "imageBuildStatus": "BUILD_COMPLETE",
 "region": "us-east-1",
 "ec2AmiInfo": {
     "amiName": "IMAGE_ID 2022-04-05T21-39-24.020Z",
     "amiId": "ami-1234stuv5678wxyz",
     "description": "AWS ParallelCluster AMI for alinux2, kernel-4.14.238-182.422.amzn2.x86_64, lustre-2.10.8-5.amzn2.x86_64, efa-1.13.0-1.amzn2.x86_64, dcv-2021.1.10598-1.el7.x86_64, slurm-20-11-8-1",
     "state": "AVAILABLE",
     "tags": [
      {
        "value": "2021.3.11591-1.el7.x86_64",
        "key": "parallelcluster:dcv_version"
      },
      ...
     ],
   "architecture": "x86_64"
 },
 "version": "3.15.0"      
}
```

如果您需要排查自定义 AMI 创建问题，请按照以下步骤所述创建映像日志存档。

可以将日志存档到 Amazon S3 存储桶或本地文件中，具体取决于 `--output` 参数。

```
$ pcluster export-image-logs --image-id IMAGE_ID --region REGION \
--bucket BUCKET_NAME --bucket-prefix BUCKET_FOLDER
{
 "url": "https://BUCKET_NAME.s3.us-east-1.amazonaws.com/BUCKET-FOLDER/IMAGE_ID-logs-202209071136.tar.gz?AWSAccessKeyId=..."
}

$ pcluster export-image-logs --image-id IMAGE_ID \
--region REGION --bucket BUCKET_NAME --bucket-prefix BUCKET_FOLDER --output-file /tmp/archive.tar.gz
{
 "path": "/tmp/archive.tar.gz"
}
```

该档案包含与 Image Builder 进程和 CloudFormation 堆栈事件相关的 CloudWatch 日志流。该命令的运行可能需要几分钟才能完成。

 **管理自定义 AMIs** 

从 AWS ParallelCluster 3.0.0 开始，CLI 中添加了一组用于构建、监控和管理映像生命周期的新命令。有关这些命令的更多信息，请参阅 [pcluster 命令](pcluster-v3.md)。

## 修改 AWS ParallelCluster AMI
<a name="modify-an-aws-parallelcluster-ami-v3"></a>

此方法包括通过在官方 AWS ParallelCluster AMI 上添加自定义来修改官方 AMI。基础版 AWS ParallelCluster AMIs 已更新为新版本。它们 AMIs 具有安装和配置后运行所需 AWS ParallelCluster 的所有组件。您可以以其中一个 AMI 作为起点。

关键点：
+ 此方法比 [`build-image`](pcluster.build-image-v3.md) 命令快。但它是一个手动过程，不会自动重复。
+ 使用此方法，您无权使用通过 CLI 提供的日志检索和映像生命周期管理命令。

步骤：

------
#### [ New Amazon EC2 console ]

1. 找到与您使用的具体内容相对应 AWS 区域 的 AMI。要找到它，请使用带有`--region`参数的[`pcluster list-official-images`](pcluster.list-official-images-v3.md)命令来选择特定的 AWS 区域 和`--os`和`--architecture`参数，筛选出具有您要使用的操作系统和架构的所需 AMI。从输出中检索 Amazon EC2 映像 ID。

1. 登录 AWS 管理控制台 并打开 Amazon EC2 控制台，网址为[https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/)。

1. 在导航窗格中，选择 “**图像**”，然后**AMIs**。搜索检索到的 EC2 映像 ID，选择 AMI，然后选择**从 AMI 启动实例**。

1. 向下滚动并选择您的**实例类型**。

1. 选择您的**密钥对**，然后选择**启动实例**。

1. 使用操作系统用户和您的 SSH 密钥登录您的实例。

1. 手动自定义实例以满足您的要求。

1. 运行以下命令以准备实例来创建 AMI。

   ```
   sudo /usr/local/sbin/ami_cleanup.sh
   ```

1. 在控制台中，选择**实例状态**和**停止实例**。

   导航到**实例**，选择新实例，然后依次选择**实例状态**和**停止实例**。

1. 使用 Amazon EC2 控制台或 AWS CLI [创建映像从实例创建](https://docs.aws.amazon.com/cli/latest/reference/ec2/create-image.html)新 AMI。

**在 Amazon EC2 控制台中**

   1. 在导航窗格中选择**实例**。

   1. 选择您创建和修改的实例。

   1. 在**操作**中，依次选择**映像**和**创建映像**。

   1. 选择**创建映像**。

1. 在集群配置内的 [`CustomAmi`](Scheduling-v3.md#yaml-Scheduling-SlurmQueues-Image-CustomAmi) 字段中输入新 AMI ID，并创建集群。

------
#### [ Old Amazon EC2 console ]

1. 找到与您使用的具体内容相对应 AWS 区域 的 AWS ParallelCluster AMI。要找到它，你可以使用带有`--region`参数的[`pcluster list-official-images`](pcluster.list-official-images-v3.md)命令来选择特定的 AWS 区域 和`--os`和`--architecture`参数，然后根据你想要使用的操作系统和架构筛选出所需的 AMI。您可以从输出中检索 Amazon EC2 映像 ID。

1. 登录 AWS 管理控制台 并打开 Amazon EC2 控制台，网址为[https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/)。

1. 在导航窗格中，选择 “**图像**”，然后**AMIs**。针对**公有映像**设置筛选器并搜索检索到的 EC2 映像 ID，选择 AMI，然后选择**启动**。

1. 选择您的实例类型，然后选择**下一步：配置实例详细信息**或**查看并启动**以启动您的实例。

1. 选择**启动**，选择您的**密钥对**，然后选择**启动实例**。

1. 使用操作系统用户和您的 SSH 密钥登录您的实例。有关更多信息，请导航至**实例**，选择新实例，然后选择**连接**。

1. 手动自定义实例以满足您的要求。

1. 运行以下命令以准备实例来创建 AMI：

   ```
   sudo /usr/local/sbin/ami_cleanup.sh
   ```

1. 在 Amazon EC2 控制台中，从导航窗格中选择**实例**，选择您的新实例，然后依次选择**操作**、**实例状态**和**停止**。

1. 使用 Amazon EC2 控制台或 AWS CLI [创建映像从实例创建](https://docs.aws.amazon.com/cli/latest/reference/ec2/create-image.html)新 AMI。

**在 Amazon EC2 控制台中**

   1. 在导航窗格中选择**实例**。

   1. 选择您创建和修改的实例。

   1. 在**操作**中，依次选择**映像**和**创建映像**。

   1. 选择**创建映像**。

1. 在集群配置内的 [`CustomAmi`](Scheduling-v3.md#yaml-Scheduling-SlurmQueues-Image-CustomAmi) 字段中输入新 AMI ID，并创建集群。

------

# 集成 Active Directory
<a name="tutorials_05_multi-user-ad"></a>

在本教程中，您将创建一个多用户环境。此环境包括与 AWS Managed Microsoft AD （A AWS ParallelCluster ctive Directory）集成的环境`corp.example.com`。您将配置一个 `Admin` 用户来管理目录，一个 `ReadOnly` 用户来读取目录，以及一个 `user000` 用户来登录到集群。您可以使用自动路径或手动路径来创建联网资源、Active Directory（AD）和用于配置 AD 的 Amazon EC2 实例。无论采用何种路径，您创建的基础架构都已预先配置为 AWS ParallelCluster 使用以下方法之一进行集成：
+ 具有证书验证功能的 LDAPS（最安全的选项，建议使用）
+ 没有证书验证功能的 LDAPS
+ LDAP

LDAP 本身*不* 提供加密。为确保安全传输潜在敏感信息，我们强烈建议您在与集成的集群中使用 LDAPS（基于 TLS/SSL 的 LDAP）。 ADs有关更多信息，请参阅《 Directory Service *管理*指南》 AWS Managed Microsoft AD中的[使用启用服务器端 LDAPS](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_ldap_server_side.html)。

创建这些资源后，继续配置和创建与 Active Directory (AD) 集成的集群。创建集群之后，以您创建的用户身份登录。有关在本教程中创建的配置的更多信息，请参阅[集群的多用户访问](multi-user-v3.md)和 [`DirectoryService`](DirectoryService-v3.md) 配置部分。

本教程介绍如何创建支持多用户访问集群的环境。本教程不介绍如何创建和使用 Directory Service 广告。本教程 AWS Managed Microsoft AD 中提供的设置步骤仅用于测试目的。它们*不能* 取代 *Directory Service Administration Guide* 的 [AWS Managed Microsoft AD](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/directory_microsoft_ad.html) 和 [Simple AD](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/directory_simple_ad.html) 章节中所述的官方文档和最佳实践。

**注意**  
目录用户密码根据目录密码策略属性定义过期。要使用重置目录密码 AWS ParallelCluster，请参阅[如何重置用户密码和过期的密码](troubleshooting-v3-multi-user.md#troubleshooting-v3-multi-user-reset-passwd)。

**注意**  
目录域控制器 IP 地址可能会因域控制器更改和目录维护而更改。如果您选择自动快速创建方法来创建目录基础架构，则当目录 IP 地址更改时，必须手动使目录控制器前面的负载均衡器保持一致。使用快速创建方法时，目录 IP 地址不会自动与负载均衡器保持一致。

使用 AWS ParallelCluster 命令行界面 (CLI) 或 API 时，您只需为创建或更新 AWS ParallelCluster 映像和集群时创建的 AWS 资源付费。有关更多信息，请参阅 [AWS 使用的服务 AWS ParallelCluster](aws-services-v3.md)。

**先决条件**
+ AWS ParallelCluster [已安装](install-v3-parallelcluster.md)。
+  AWS CLI [已安装并配置。](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ 您有一个 [Amazon EC2 密钥对](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html)。
+ 您拥有具有运行 [`pcluster`](pcluster-v3.md) CLI 所需的[权限](iam-roles-in-parallelcluster-v3.md#iam-roles-in-parallelcluster-v3-example-user-policies)的 IAM 角色。

在学习本教程时，请用自己的名字替换`inputs highlighted in red`（例如`region-id`和`d-abcdef01234567890`）和 IDs。`0123456789012`用你的 AWS 账户 号码替换。

# 创建 AD 基础设施
<a name="tutorials_05_multi-user-ad-step1"></a>

选择 “*自动*” 选项卡，使用 CloudFormation 快速创建模板创建 Active Directory (AD) 基础架构。

选择*手动*选项卡可手动创建 AD 基础架构。

## 自动
<a name="tutorials_05_multi-user-ad-step1-automated"></a>

1. 登录到 AWS 管理控制台。

1. 打开[CloudFormation 快速创建（区域 us-east-1](https://us-east-1.console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/create/review?stackName=pcluster-ad&templateURL=https://us-east-1-aws-parallelcluster.s3.amazonaws.com/templates/1-click/ad-integration.yaml)），在控制台中创建以下资源： CloudFormation 
   + 具有两个子网的 VPC 和公有访问路由（如果未指定 VPC）。
   + 一个 AWS Managed Microsoft AD。
   + 已加入 AD 并可用于管理目录的 Amazon EC2 实例。

1. 在**快速创建堆栈**页面的**参数**部分，输入以下参数的密码：
   + **AdminPassword**
   + **ReadOnlyPassword**
   + **UserPassword**

   记下这些密码。本教程后面将会用到这些密码。

1. 对于 **DomainName**，输入 **corp.example.com**。

1. 在**密钥对**中，输入 Amazon EC2 密钥对的名称。

1. 在页面底部选中各个框以确认各项访问功能。

1. 选择**创建堆栈**。

1.  CloudFormation 堆栈达到`CREATE_COMPLETE`状态后，选择堆栈的 “**输出**” 选项卡。记下输出资源名称， IDs 因为您需要在以后的步骤中使用它们。输出提供了创建集群所需的信息。  
![\[显示在 AWS 管理控制台中创建的堆栈输出的示意图。\]](http://docs.aws.amazon.com/zh_cn/parallelcluster/latest/ug/images/ad-cfn.png)

1. 要完成练习[（可选）管理 AD 用户和组](tutorials_05_multi-user-ad-step2.md)，您需要目录 ID。选择**资源**并向下滚动，记下目录 ID。

1. 继续[（可选）管理 AD 用户和组](tutorials_05_multi-user-ad-step2.md)或[创建集群](tutorials_05_multi-user-ad-step3.md)。

## 手动
<a name="tutorials_05_multi-user-ad-step1-manual"></a>

为目录服务创建在不同可用区中具有两个子网的 VPC 以及 AWS Managed Microsoft AD。

### 创建 AD
<a name="tutorials_05_multi-user-ad-step1-manual-ad"></a>

**注意**  
目录和域名是 `corp.example.com`。短名称是 `CORP`。
在脚本中更改 `Admin` 密码。
创建 Active Directory (AD) 至少需要 15 分钟。

使用以下 Python 脚本在您的本地 AWS 区域创建 VPC、子网和 AD 资源。将此文件另存为 `ad.py` 并运行。

```
import boto3
import time
from pprint import pprint

vpc_name = "PclusterVPC"
ad_domain = "corp.example.com"
admin_password = "asdfASDF1234"

ec2 = boto3.client("ec2")
ds = boto3.client("ds")
region = boto3.Session().region_name

# Create the VPC, Subnets, IGW, Routes
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]
vpc_id = vpc["VpcId"]
time.sleep(30)
ec2.create_tags(Resources=[vpc_id], Tags=[{"Key": "Name", "Value": vpc_name}])
subnet1 = ec2.create_subnet(VpcId=vpc_id, CidrBlock="10.0.0.0/17", AvailabilityZone=f"{region}a")["Subnet"]
subnet1_id = subnet1["SubnetId"]
time.sleep(30)
ec2.create_tags(Resources=[subnet1_id], Tags=[{"Key": "Name", "Value": f"{vpc_name}/subnet1"}])
ec2.modify_subnet_attribute(SubnetId=subnet1_id, MapPublicIpOnLaunch={"Value": True})
subnet2 = ec2.create_subnet(VpcId=vpc_id, CidrBlock="10.0.128.0/17", AvailabilityZone=f"{region}b")["Subnet"]
subnet2_id = subnet2["SubnetId"]
time.sleep(30)
ec2.create_tags(Resources=[subnet2_id], Tags=[{"Key": "Name", "Value": f"{vpc_name}/subnet2"}])
ec2.modify_subnet_attribute(SubnetId=subnet2_id, MapPublicIpOnLaunch={"Value": True})
igw = ec2.create_internet_gateway()["InternetGateway"]
ec2.attach_internet_gateway(InternetGatewayId=igw["InternetGatewayId"], VpcId=vpc_id)
route_table = ec2.describe_route_tables(Filters=[{"Name": "vpc-id", "Values": [vpc_id]}])["RouteTables"][0]
ec2.create_route(RouteTableId=route_table["RouteTableId"], DestinationCidrBlock="0.0.0.0/0", GatewayId=igw["InternetGatewayId"])
ec2.modify_vpc_attribute(VpcId=vpc_id, EnableDnsSupport={"Value": True})
ec2.modify_vpc_attribute(VpcId=vpc_id, EnableDnsHostnames={"Value": True})

# Create the Active Directory
ad = ds.create_microsoft_ad(
    Name=ad_domain,
    Password=admin_password,
    Description="ParallelCluster AD",
    VpcSettings={"VpcId": vpc_id, "SubnetIds": [subnet1_id, subnet2_id]},
    Edition="Standard",
)
directory_id = ad["DirectoryId"]

# Wait for completion
print("Waiting for the directory to be created...")
directories = ds.describe_directories(DirectoryIds=[directory_id])["DirectoryDescriptions"]
directory = directories[0]
while directory["Stage"] in {"Requested", "Creating"}:
    time.sleep(3)
    directories = ds.describe_directories(DirectoryIds=[directory_id])["DirectoryDescriptions"]
    directory = directories[0]
    
dns_ip_addrs = directory["DnsIpAddrs"]

pprint({"directory_id": directory_id,
        "vpc_id": vpc_id,
        "subnet1_id": subnet1_id,
        "subnet2_id": subnet2_id,
        "dns_ip_addrs": dns_ip_addrs})
```

下面是该 Python 脚本的示例输出。

```
{
  "directory_id": "d-abcdef01234567890",
  "dns_ip_addrs": ["192.0.2.254", "203.0.113.237"],
  "subnet1_id": "subnet-021345abcdef6789",
  "subnet2_id": "subnet-1234567890abcdef0",
  "vpc_id": "vpc-021345abcdef6789"
}
```

记下输出资源名称和 IDs。您将在后面的步骤中用到它们。

脚本完成后，继续执行下一步。

### 创建 Amazon EC2 实例
<a name="tutorials_05_multi-user-ad-step1-manual-instance"></a>

------
#### [ New Amazon EC2 console ]

1. 登录到 AWS 管理控制台。

1. 如果您没有附加步骤 4 中列出的策略的角色，请打开 IAM 控制台，网址为[https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)。否则，请跳至步骤 5。

1. 创建`ResetUserPassword`政策，将红色突出显示的内容替换为您的 AWS 区域 ID、账户 ID 和您为创建 AD 而运行的脚本输出中的目录 ID。

   ResetUserPassword

   ```
   {
          "Statement": [
           {
               "Action": [
                   "ds:ResetUserPassword"
               ],
               "Resource": "arn:aws:ds:region-id:123456789012:directory/d-abcdef01234567890",
               "Effect": "Allow"
           }
       ]
   }
   ```

1. 创建附加了以下策略的 IAM 角色。
   + AWS 托管策略 [Amazon SSMManaged InstanceCore](https://console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore)
   + AWS 托管策略 [Amazon SSMDirectory ServiceAccess](https://console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/AmazonSSMDirectoryServiceAccess)
   + ResetUserPassword 政策

1. 打开位于 [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/) 的 Amazon EC2 控制台。

1. 在 **Amazon EC2 控制面板**上，选择**启动实例**。

1. 在**应用程序和操作系统映像**中，选择最近的 Amazon Linux 2 AMI。

1. 对于**实例类型**，选择 t2.micro。

1. 对于**密钥对**，选择一个密钥对。

1. 对于**网络设置**，选择**编辑**。

1. 对于 **VPC**，选择目录 VPC。

1. 向下滚动并选择**高级详细信息**。

1. 在**高级详细信息**中的**域加入目录**中，选择 **corp.example.com**。

1. 对于 **IAM 实例配置文件**，选择您在步骤 1 中创建的角色或附加了步骤 4 中所列策略的角色。

1. 在**摘要**中，选择**启动实例**。

1. 记下实例 ID（例如 i-1234567890abcdef0），然后等待实例完成启动。

1. 在实例启动后，继续进行下一步操作。

------
#### [ Old Amazon EC2 console ]

1. 登录到 AWS 管理控制台。

1. 如果您没有附加步骤 4 中列出的策略的角色，请打开 IAM 控制台，网址为[https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)。否则，请跳至步骤 5。

1. 创建 `ResetUserPassword` 策略。将红色突出显示的内容替换为您的 AWS 区域 ID、 AWS 账户 ID 和您为创建 Active Directory (AD) 而运行的脚本输出中的目录 ID。

   ResetUserPassword

   ```
   {
           "Statement": [
               {
                   "Action": [
                       "ds:ResetUserPassword"
                   ],
                   "Resource": "arn:aws:ds:region-id:123456789012:directory/d-abcdef01234567890",
                   "Effect": "Allow"
               }
           ]
        }
   ```

1. 创建附加了以下策略的 IAM 角色。
   + AWS 托管策略 [Amazon SSMManaged InstanceCore](https://console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore)
   + AWS 托管策略 [Amazon SSMDirectory ServiceAccess](https://console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/AmazonSSMDirectoryServiceAccess)
   + ResetUserPassword 策略

1. 打开位于 [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/) 的 Amazon EC2 控制台。

1. 在 **Amazon EC2 控制面板**上，选择**启动实例**。

1. 在**应用程序和操作系统映像**中，选择最近的 Amazon Linux 2 AMI。

1. 对于**实例类型**，选择 t2.micro。

1. 对于**密钥对**，选择一个密钥对。

1. 在**网络设置**中，选择**编辑**。

1. 对于**网络设置**中的 **VPC**，选择目录 VPC。

1. 向下滚动并选择**高级详细信息**。

1. 在**高级详细信息**中的**域加入目录**中，选择 **corp.example.com**。

1. 对于**高级详细信息**中的**实例配置文件**，选择您在步骤 1 中创建的角色或附加了步骤 4 中所列策略的角色。

1. 在**摘要**中，选择**启动实例**。

1. 记下实例 ID（例如 i-1234567890abcdef0），然后等待实例完成启动。

1. 在实例启动后，继续进行下一步操作。

------

### 将您的实例加入到 AD
<a name="tutorials_05_multi-user-ad-step1-manual-join"></a>

1. 

**以 `admin` 身份连接到您的实例并加入 AD 领域。**

   运行以下命令连接到实例。

   ```
   $ INSTANCE_ID="i-1234567890abcdef0"
   ```

   ```
   $ PUBLIC_IP=$(aws ec2 describe-instances \
   --instance-ids $INSTANCE_ID \
   --query "Reservations[0].Instances[0].PublicIpAddress" \
   --output text)
   ```

   ```
   $ ssh -i ~/.ssh/keys/keypair.pem ec2-user@$PUBLIC_IP
   ```

1. 

**安装必要的软件并加入该领域。**

   ```
   $ sudo yum -y install sssd realmd oddjob oddjob-mkhomedir adcli samba-common samba-common-tools krb5-workstation openldap-clients policycoreutils-python
   ```

1. 

**将管理员密码替换为您的 `admin` 密码。**

   ```
   $ ADMIN_PW="asdfASDF1234"
   ```

   ```
   $ echo $ADMIN_PW | sudo realm join -U Admin corp.example.com
   Password for Admin:
   ```

   如果上述操作成功，您就加入到了该领域，并可以继续下一步操作。

### 向 AD 中添加用户
<a name="tutorials_05_multi-user-ad-step1-manual-join-add-users"></a>

1. 

**创建 ReadOnlyUser 和其他用户。**

   在此步骤中，您将使用在前一步中安装的 [adcli](https://www.mankier.com/package/adcli) 和 [openldap-clients](https://www.mankier.com/package/openldap-clients) 工具。

   ```
   $ echo $ADMIN_PW | adcli create-user -x -U Admin --domain=corp.example.com --display-name=ReadOnlyUser ReadOnlyUser
   ```

   ```
   $ echo $ADMIN_PW | adcli create-user -x -U Admin --domain=corp.example.com --display-name=user000 user000
   ```

1. **验证是否创建了用户：**

   目录 DNS IP 地址是 Python 脚本的输出。

   ```
   $ DIRECTORY_IP="192.0.2.254"
   ```

   ```
   $ ldapsearch -x -h $DIRECTORY_IP -D Admin -w $ADMIN_PW -b "cn=ReadOnlyUser,ou=Users,ou=CORP,dc=corp,dc=example,dc=com"
   ```

   ```
   $ ldapsearch -x -h $DIRECTORY_IP -D Admin -w $ADMIN_PW -b "cn=user000,ou=Users,ou=CORP,dc=corp,dc=example,dc=com"
   ```

   默认情况下，当您使用 `ad-cli` 创建用户时，该用户将处于禁用状态。

1. 

****在本地计算机上重置并激活用户密码：****

   注销 Amazon EC2 实例。
**注意**  
`ro-p@ssw0rd`是的密码`ReadOnlyUser`，从中检索 AWS Secrets Manager。
`user-p@ssw0rd` 是集群用户的密码，在您连接 (`ssh`) 到集群时提供。

   `directory-id` 是 Python 脚本的输出。

   ```
   $ DIRECTORY_ID="d-abcdef01234567890"
   ```

   ```
   $ aws ds reset-user-password \
   --directory-id $DIRECTORY_ID \
   --user-name "ReadOnlyUser" \
   --new-password "ro-p@ssw0rd" \
   --region "region-id"
   ```

   ```
   $ aws ds reset-user-password \
   --directory-id $DIRECTORY_ID \
   --user-name "user000" \
   --new-password "user-p@ssw0rd" \
   --region "region-id"
   ```

1. **将密码添加到 Secrets Manager 密钥中。**

   现在，您已经创建`ReadOnlyUser`并设置了密码，请将其存储在 AWS ParallelCluster 用于验证登录名的密钥中。

   使用 Secrets Manager 创建新密钥以将 `ReadOnlyUser` 的密码作为值。密钥值格式必须仅为纯文本（而不是 JSON 格式）。记下密钥的 ARN，以在后面的步骤中使用。

   ```
   $ aws secretsmanager create-secret --name "ADSecretPassword" \
   --region region_id \
   --secret-string "ro-p@ssw0rd" \
   --query ARN \
   --output text
   arn:aws:secretsmanager:region-id:123456789012:secret:ADSecretPassword-1234
   ```

### 具有证书验证功能的 LDAPS（推荐）的设置
<a name="tutorials_05_multi-user-ad-step1-manual-ldaps"></a>

记下资源 IDs。您将在后面的步骤中用到它们。

1. 

**在本地生成域证书。**

   ```
   $ PRIVATE_KEY="corp-example-com.key"
   CERTIFICATE="corp-example-com.crt"
   printf ".\n.\n.\n.\n.\ncorp.example.com\n.\n" | openssl req -x509 -sha256 -nodes -newkey rsa:2048 -keyout $PRIVATE_KEY -days 365 -out $CERTIFICATE
   ```

1. 

**将证书存储到 Secrets Manager，以便以后可以从集群内进行检索。**

   ```
   $ aws secretsmanager create-secret --name example-cert \
     --secret-string file://$CERTIFICATE \
     --region region-id
   {
     "ARN": "arn:aws:secretsmanager:region-id:123456789012:secret:example-cert-123abc",
     "Name": "example-cert",
     "VersionId": "14866070-092a-4d5a-bcdd-9219d0566b9c"
   }
   ```

1. 将以下策略添加到您为将 Amazon EC2 实例加入 AD 域而创建的 IAM 角色。

   `PutDomainCertificateSecrets`

   ```
   {
       "Statement": [
           {
               "Action": [
                   "secretsmanager:PutSecretValue"
               ],
               "Resource": [
                   "arn:aws:secretsmanager:region-id:123456789012:secret:example-cert-123abc"
               ],
               "Effect": "Allow"
           }
       ]
   }
   ```

1. 

**将证书导入 AWS Certificate Manager (ACM)。**

   ```
   $ aws acm import-certificate --certificate fileb://$CERTIFICATE \
     --private-key fileb://$PRIVATE_KEY \
     --region region-id
   {
     "CertificateArn": "arn:aws:acm:region-id:123456789012:certificate/343db133-490f-4077-b8d4-3da5bfd89e72"
   }
   ```

1. 

**创建放置在 Active Directory 端点前面的负载均衡器。**

   ```
   $ aws elbv2 create-load-balancer --name CorpExampleCom-NLB \
     --type network \
     --scheme internal \
     --subnets subnet-1234567890abcdef0 subnet-021345abcdef6789 \
     --region region-id
   {
     "LoadBalancers": [
       {
         "LoadBalancerArn": "arn:aws:elasticloadbalancing:region-id:123456789012:loadbalancer/net/CorpExampleCom-NLB/3afe296bf4ba80d4",
         "DNSName": "CorpExampleCom-NLB-3afe296bf4ba80d4.elb.region-id.amazonaws.com",
         "CanonicalHostedZoneId": "Z2IFOLAFXWLO4F",
         "CreatedTime": "2022-05-05T12:56:55.988000+00:00",
         "LoadBalancerName": "CorpExampleCom-NLB",
         "Scheme": "internal",
         "VpcId": "vpc-021345abcdef6789",
         "State": {
           "Code": "provisioning"
          },
          "Type": "network",
          "AvailabilityZones": [
            {
              "ZoneName": "region-idb",
              "SubnetId": "subnet-021345abcdef6789",
              "LoadBalancerAddresses": []
            },
            {
              "ZoneName": "region-ida",
              "SubnetId": "subnet-1234567890abcdef0",
              "LoadBalancerAddresses": []
            }
          ],
          "IpAddressType": "ipv4"
       }   
     ]
   }
   ```

1. 

**创建以 Active Directory 端点为目标的目标组。**

   ```
   $ aws elbv2 create-target-group --name CorpExampleCom-Targets --protocol TCP \
     --port 389 \
     --target-type ip \
     --vpc-id vpc-021345abcdef6789 \
     --region region-id
   {
     "TargetGroups": [
       {
         "TargetGroupArn": "arn:aws:elasticloadbalancing:region-id:123456789012:targetgroup/CorpExampleCom-Targets/44577c583b695e81",
         "TargetGroupName": "CorpExampleCom-Targets",
         "Protocol": "TCP",
         "Port": 389,
         "VpcId": "vpc-021345abcdef6789",
         "HealthCheckProtocol": "TCP",
         "HealthCheckPort": "traffic-port",
         "HealthCheckEnabled": true,
         "HealthCheckIntervalSeconds": 30,
         "HealthCheckTimeoutSeconds": 10,
         "HealthyThresholdCount": 3,
         "UnhealthyThresholdCount": 3,
         "TargetType": "ip",
         "IpAddressType": "ipv4"
       }
     ]
   }
   ```

1. 

**将 Active Directory (AD) 端点注册到目标组。**

   ```
   $ aws elbv2 register-targets --target-group-arn arn:aws:elasticloadbalancing:region-id:123456789012:targetgroup/CorpExampleCom-Targets/44577c583b695e81 \
     --targets Id=192.0.2.254,Port=389 Id=203.0.113.237,Port=389 \
     --region region-id
   ```

1. 

**对证书创建 LB 侦听器。**

   ```
   $ aws elbv2 create-listener --load-balancer-arn arn:aws:elasticloadbalancing:region-id:123456789012:loadbalancer/net/CorpExampleCom-NLB/3afe296bf4ba80d4 \
     --protocol TLS \
     --port 636 \
     --default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:region-id:123456789012:targetgroup/CorpExampleCom-Targets/44577c583b695e81 \
     --ssl-policy ELBSecurityPolicy-TLS-1-2-2017-01 \
     --certificates CertificateArn=arn:aws:acm:region-id:123456789012:certificate/343db133-490f-4077-b8d4-3da5bfd89e72 \
     --region region-id
     "Listeners": [
     {
       "ListenerArn": "arn:aws:elasticloadbalancing:region-id:123456789012:listener/net/CorpExampleCom-NLB/3afe296bf4ba80d4/a8f9d97318743d4b",
       "LoadBalancerArn": "arn:aws:elasticloadbalancing:region-id:123456789012:loadbalancer/net/CorpExampleCom-NLB/3afe296bf4ba80d4",
       "Port": 636,
       "Protocol": "TLS",
       "Certificates": [
         {
           "CertificateArn": "arn:aws:acm:region-id:123456789012:certificate/343db133-490f-4077-b8d4-3da5bfd89e72"
          }
        ],
        "SslPolicy": "ELBSecurityPolicy-TLS-1-2-2017-01",
        "DefaultActions": [
          {
            "Type": "forward",
            "TargetGroupArn": "arn:aws:elasticloadbalancing:region-id:123456789012:targetgroup/CorpExampleCom-Targets/44577c583b695e81",
            "ForwardConfig": {
              "TargetGroups": [
                {
                   "TargetGroupArn": "arn:aws:elasticloadbalancing:region-id:123456789012:targetgroup/CorpExampleCom-Targets/44577c583b695e81"
                 }
               ]
             }
           }
         ]
       }
     ]
   }
   ```

1. 

**创建托管区以便可以在集群 VPC 内发现该域。**

   ```
   $ aws route53 create-hosted-zone --name corp.example.com \
     --vpc VPCRegion=region-id,VPCId=vpc-021345abcdef6789 \
     --caller-reference "ParallelCluster AD Tutorial"
   {
     "Location": "https://route53.amazonaws.com/2013-04-01/hostedzone/Z09020002B5MZQNXMSJUB",
     "HostedZone": {
       "Id": "/hostedzone/Z09020002B5MZQNXMSJUB",
       "Name": "corp.example.com.",
       "CallerReference": "ParallelCluster AD Tutorial",
       "Config": {
            "PrivateZone": true
       },
       "ResourceRecordSetCount": 2
     },
     "ChangeInfo": {
       "Id": "/change/C05533343BF3IKSORW1TQ",
       "Status": "PENDING",
       "SubmittedAt": "2022-05-05T13:21:53.863000+00:00"
     },
     "VPC": {
       "VPCRegion": "region-id",
       "VPCId": "vpc-021345abcdef6789"
     }
   }
   ```

1. 

**创建名为 `recordset-change.json` 并包含以下内容的文件。`HostedZoneId` 是负载均衡器的规范托管区 ID。**

   ```
   {
     "Changes": [
       {
         "Action": "CREATE",
         "ResourceRecordSet": {
           "Name": "corp.example.com",
           "Type": "A",
           "Region": "region-id",
           "SetIdentifier": "example-active-directory",
           "AliasTarget": {
             "HostedZoneId": "Z2IFOLAFXWLO4F",
             "DNSName": "CorpExampleCom-NLB-3afe296bf4ba80d4.elb.region-id.amazonaws.com",
             "EvaluateTargetHealth": true
           }
         }
       }
     ]
   }
   ```

1. 

**将记录集更改提交到托管区，这次使用托管区 ID。**

   ```
   $ aws route53 change-resource-record-sets --hosted-zone-id Z09020002B5MZQNXMSJUB \
     --change-batch file://recordset-change.json
   {
     "ChangeInfo": {
       "Id": "/change/C0137926I56R3GC7XW2Y",
       "Status": "PENDING",
       "SubmittedAt": "2022-05-05T13:40:36.553000+00:00"
     }
   }
   ```

1. 

**创建包含以下内容的策略文档 `policy.json`。**

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Action": [
                   "secretsmanager:GetSecretValue"
               ],
               "Resource": [
                   "arn:aws:secretsmanager:us-east-1:123456789012:secret:example-cert-abc123"
               ],
               "Effect": "Allow"
           }
       ]
   }
   ```

------

1. 

**创建名为 `policy.json` 并包含以下内容的策略文档。**

   ```
   $ aws iam create-policy --policy-name ReadCertExample \
     --policy-document file://policy.json
   {
     "Policy": {
       "PolicyName": "ReadCertExample",
       "PolicyId": "ANPAUUXUVBC42VZSI4LDY",
       "Arn": "arn:aws:iam::123456789012:policy/ReadCertExample-efg456",
       "Path": "/",
       "DefaultVersionId": "v1",
       "AttachmentCount": 0,
       "PermissionsBoundaryUsageCount": 0,
       "IsAttachable": true,
       "CreateDate": "2022-05-05T13:42:18+00:00",
       "UpdateDate": "2022-05-05T13:42:18+00:00"
     }
   }
   ```

1. 继续按照 [（可选）管理 AD 用户和组](tutorials_05_multi-user-ad-step2.md) 或 [创建集群](tutorials_05_multi-user-ad-step3.md) 中的步骤操作。

# （可选）管理 AD 用户和组
<a name="tutorials_05_multi-user-ad-step2"></a>

在此步骤中，您将管理已加入 Active Directory（AD）域的 Amazon EC2 Amazon Linux 2 实例中的用户和组。

如果您使用的是*自动* 方法，请重启并登录到在自动操作过程中创建并加入 AD 的实例。

如果您使用的是*手动* 方法，请重启并登录到您在前面的步骤中创建并加入 AD 的实例。

在这些步骤中，您将使用前一步在实例中安装的 [adcli](https://www.mankier.com/package/adcli) 和 [openldap-clients](https://www.mankier.com/package/openldap-clients) 工具。

**登录到已加入 AD 域的 Amazon EC2 实例**

1. 从 Amazon EC2 控制台中，选择在之前的步骤中创建的无标题 Amazon EC2 实例。该实例的状态可能是**已停止**。

1. 如果实例状态为**已停止**，请选择**实例状态**，然后选择**启动实例**。

1. 状态检查通过后，选择该实例，然后选择**连接**并 SSH 登录到该实例。

**登录到已加入 AD 的 Amazon EC2 Amazon Linux 2 实例后管理用户和组**

当您使用 ` -U "Admin"` 选项运行 `adcli` 命令时，系统会提示您输入 AD `Admin` 密码。您可以将 AD `Admin` 密码作为 `ldapsearch` 命令的一部分。

1. 

**创建用户。**

   ```
   $ adcli create-user "clusteruser" --domain "corp.example.com" -U "Admin"
   ```

1. 

**设置用户密码。**

   ```
   $ aws --region "region-id" ds reset-user-password --directory-id "d-abcdef01234567890" --user-name "clusteruser" --new-password "new-p@ssw0rd"
   ```

1. 

**创建组。**

   ```
   $ adcli create-group "clusterteam" --domain "corp.example.com" -U "Admin"
   ```

1. 

**将用户添加到组。**

   ```
   $ adcli add-member "clusterteam" "clusteruser" --domain "corp.example.com" -U "Admin"
   ```

1. 

**描述用户和组。**

   描述所有用户。

   ```
   $ ldapsearch "(&(objectClass=user))" -x -h "192.0.2.254" -b "DC=corp,DC=example,DC=com" -D "CN=Admin,OU=Users,OU=CORP,DC=corp,DC=example,DC=com" -w "p@ssw0rd"
   ```

   描述特定用户。

   ```
   $ ldapsearch "(&(objectClass=user)(cn=clusteruser))" -x -h "192.0.2.254" -b "DC=corp,DC=example,DC=com" -D "CN=Admin,OU=Users,OU=CORP,DC=corp,DC=example,DC=com" -w "p@ssw0rd"
   ```

   使用名称模式描述所有用户。

   ```
   $ ldapsearch "(&(objectClass=user)(cn=user*))" -x -h "192.0.2.254" -b "DC=corp,DC=example,DC=com" -D "CN=Admin,OU=Users,OU=CORP,DC=corp,DC=example,DC=com" -w "p@ssw0rd"
   ```

   描述属于特定组的所有用户。

   ```
   $ ldapsearch "(&(objectClass=user)(memberOf=CN=clusterteam,OU=Users,OU=CORP,DC=corp,DC=example,DC=com))" -x -h "192.0.2.254" -b "DC=corp,DC=example,DC=com" -D "CN=Admin,OU=Users,OU=CORP,DC=corp,DC=example,DC=com" -w "p@ssw0rd"
   ```

   描述所有组

   ```
   $ ldapsearch "objectClass=group" -x -h "192.0.2.254" -b "DC=corp,DC=example,DC=com" -D "CN=Admin,OU=Users,OU=CORP,DC=corp,DC=example,DC=com" -w "p@ssw0rd"
   ```

   描述特定组

   ```
   $ ldapsearch "(&(objectClass=group)(cn=clusterteam))" -x -h "192.0.2.254" -b "DC=corp,DC=example,DC=com" -D "CN=Admin,OU=Users,OU=CORP,DC=corp,DC=example,DC=com" -w "p@ssw0rd"
   ```

1. 

**从组中删除用户。**

   ```
   $ adcli remove-member "clusterteam" "clusteruser" --domain "corp.example.com" -U "Admin"
   ```

1. 

**删除用户。**

   ```
   $ adcli delete-user "clusteruser" --domain "corp.example.com" -U "Admin"
   ```

1. 

**删除组。**

   ```
   $ adcli delete-group "clusterteam" --domain "corp.example.com" -U "Admin"
   ```

# 创建集群
<a name="tutorials_05_multi-user-ad-step3"></a>

如果您尚未退出 Amazon EC2 实例，请立即退出。

设置该环境是为了创建可以针对 Active Directory (AD) 对用户进行身份验证的集群。

创建简单的集群配置并提供与连接到 AD 相关的设置。想要了解更多信息，请参阅[`DirectoryService`](DirectoryService-v3.md)部分。

选择以下集群配置之一，然后将其复制到名为 `ldaps_config.yaml`、`ldaps_nocert_config.yaml` 或 `ldap_config.yaml` 的文件中。

建议您选择具有证书验证功能的 LDAPS 配置。如果选择此配置，则还必须将引导脚本复制到名为 `active-directory.head.post.sh` 的文件中。此外，您必须将其存储在配置文件中指示的 Amazon S3 存储桶中。

## 具有证书验证功能的 LDAPS 配置（推荐）
<a name="tutorials_05_multi-user-ad-step3-ldaps"></a>

**注意**  
`KeyName`：您的一个 Amazon EC2 密钥对。
`SubnetId / SubnetIds`： CloudFormation 快速创建堆栈（自动教程）或 python 脚本（手动教程）输出中 IDs 提供的子网之一。
`Region`：您在其中创建 AD 基础架构的区域。
`DomainAddr`：此 IP 地址是您的 AD 服务的 DNS 地址之一。
`PasswordSecretArn`：包含 `DomainReadOnlyUser` 密码的密钥的 Amazon 资源名称 (ARN)。
`BucketName`：保存引导脚本的存储桶的名称。
`AdditionalPolicies`/`Policy`：读取域名认证政策的亚马逊资源名称 (ARN)。 ReadCertExample
`CustomActions`/`OnNodeConfigured`/`Args`：保存域名认证策略的密钥的 Amazon 资源名称 (ARN)。
为了提高安全性，我们建议使用 `HeadNode`/`Ssh`/`AllowedIps` 配置来限制对头节点的 SSH 访问。  
请注意，中指定的证书`LdapTlsCaCert`必须可供所有群集节点访问。

**硬性要求**  
中指定的证书`LdapTlsCaCert`必须可供所有群集节点访问。  
无法访问证书的节点将无法解析目录中的用户。

```
Region: region-id
Image:
  Os: alinux2
HeadNode: 
  InstanceType: t2.micro
  Networking:
    SubnetId: subnet-abcdef01234567890
  Ssh:
    KeyName: keypair
  Iam:
    AdditionalIamPolicies:
      - Policy: arn:aws:iam::123456789012:policy/ReadCertExample
    S3Access:
      - BucketName: amzn-s3-demo-bucket
        EnableWriteAccess: false
        KeyName: bootstrap/active-directory/active-directory.head.post.sh
  CustomActions:
    OnNodeConfigured:
      Script: s3://amzn-s3-demo-bucket/bootstrap/active-directory/active-directory.head.post.sh
      Args:
        - arn:aws:secretsmanager:region-id:123456789012:secret:example-cert-123abc
        - /opt/parallelcluster/shared/directory_service/domain-certificate.crt
Scheduling:
  Scheduler: slurm
  SlurmQueues:
    - Name: queue0
      ComputeResources:
        - Name: queue0-t2-micro
          InstanceType: t2.micro
          MinCount: 1
          MaxCount: 10         
      Networking:
        SubnetIds:
          - subnet-abcdef01234567890
DirectoryService:
  DomainName: corp.example.com
  DomainAddr: ldaps://corp.example.com
  PasswordSecretArn: arn:aws:secretsmanager:region-id:123456789012:secret:ADSecretPassword-1234
  DomainReadOnlyUser: cn=ReadOnlyUser,ou=Users,ou=CORP,dc=corp,dc=example,dc=com
  LdapTlsCaCert: /opt/parallelcluster/shared/directory_service/domain-certificate.crt
  LdapTlsReqCert: hard
```

**引导脚本**

创建引导程序文件后，在将其上传到 S3 存储桶之前，请运行`chmod +x active-directory.head.post.sh`以授予 AWS ParallelCluster 运行权限。

```
#!/bin/bash
set -e

CERTIFICATE_SECRET_ARN="$1"
CERTIFICATE_PATH="$2"

[[ -z $CERTIFICATE_SECRET_ARN ]] && echo "[ERROR] Missing CERTIFICATE_SECRET_ARN" && exit 1
[[ -z $CERTIFICATE_PATH ]] && echo "[ERROR] Missing CERTIFICATE_PATH" && exit 1

source /etc/parallelcluster/cfnconfig
REGION="${cfn_region:?}"

mkdir -p $(dirname $CERTIFICATE_PATH)
aws secretsmanager get-secret-value --region $REGION --secret-id $CERTIFICATE_SECRET_ARN --query SecretString --output text > $CERTIFICATE_PATH
```

## 没有证书验证功能的 LDAPS 配置
<a name="tutorials_05_multi-user-ad-step3-ldaps-no-cert"></a>

**注意**  
`KeyName`：您的一个 Amazon EC2 密钥对。
`SubnetId / SubnetIds`： CloudFormation 快速创建堆栈（自动教程）或 python 脚本（手动教程）输出中的子网 IDs 之一。
`Region`：您在其中创建 AD 基础架构的区域。
`DomainAddr`：此 IP 地址是您的 AD 服务的 DNS 地址之一。
`PasswordSecretArn`：包含 `DomainReadOnlyUser` 密码的密钥的 Amazon 资源名称 (ARN)。
为了更好的安全状况，我们建议使用 HeadNode /Ssh/ AllowedIps 配置来限制对头节点的 SSH 访问。

```
Region: region-id
Image:
  Os: alinux2
HeadNode: 
  InstanceType: t2.micro
  Networking:
    SubnetId: subnet-abcdef01234567890
  Ssh:
    KeyName: keypair
Scheduling:
  Scheduler: slurm
  SlurmQueues:
    - Name: queue0
      ComputeResources:
        - Name: queue0-t2-micro
          InstanceType: t2.micro
          MinCount: 1
          MaxCount: 10         
      Networking:
        SubnetIds:
          - subnet-abcdef01234567890
DirectoryService:
  DomainName: corp.example.com
  DomainAddr: ldaps://corp.example.com
  PasswordSecretArn: arn:aws:secretsmanager:region-id:123456789012:secret:ADSecretPassword-1234
  DomainReadOnlyUser: cn=ReadOnlyUser,ou=Users,ou=CORP,dc=corp,dc=example,dc=com
  LdapTlsReqCert: never
```

## LDAP 配置
<a name="tutorials_05_multi-user-ad-step3-ldap"></a>

**注意**  
`KeyName`：您的一个 Amazon EC2 密钥对。
`SubnetId / SubnetIds`： CloudFormation 快速创建堆栈（自动教程）或 python 脚本（手动教程）输出中 IDs 提供的子网之一。
`Region`：您在其中创建 AD 基础架构的区域。
`DomainAddr`：此 IP 地址是您的 AD 服务的 DNS 地址之一。
`PasswordSecretArn`：包含 `DomainReadOnlyUser` 密码的密钥的 Amazon 资源名称 (ARN)。
为了更好的安全状况，我们建议使用 HeadNode /Ssh/ AllowedIps 配置来限制对头节点的 SSH 访问。

```
Region: region-id
Image:
  Os: alinux2
HeadNode: 
  InstanceType: t2.micro
  Networking:
    SubnetId: subnet-abcdef01234567890
  Ssh:
    KeyName: keypair
Scheduling:
  Scheduler: slurm
  SlurmQueues:
    - Name: queue0
      ComputeResources:
        - Name: queue0-t2-micro
          InstanceType: t2.micro
          MinCount: 1
          MaxCount: 10         
      Networking:
        SubnetIds:
          - subnet-abcdef01234567890
DirectoryService:
  DomainName: dc=corp,dc=example,dc=com
  DomainAddr: ldap://192.0.2.254,ldap://203.0.113.237
  PasswordSecretArn: arn:aws:secretsmanager:region-id:123456789012:secret:ADSecretPassword-1234
  DomainReadOnlyUser: cn=ReadOnlyUser,ou=Users,ou=CORP,dc=corp,dc=example,dc=com
  AdditionalSssdConfigs:
    ldap_auth_disable_tls_never_use_in_production: True
```

使用以下命令创建集群。

```
$ pcluster create-cluster --cluster-name "ad-cluster" --cluster-configuration "./ldaps_config.yaml"
{
  "cluster": {
    "clusterName": "pcluster",
    "cloudformationStackStatus": "CREATE_IN_PROGRESS",
    "cloudformationStackArn": "arn:aws:cloudformation:region-id:123456789012:stack/ad-cluster/1234567-abcd-0123-def0-abcdef0123456",
    "region": "region-id",
    "version": 3.15.0,
    "clusterStatus": "CREATE_IN_PROGRESS"
  }
}
```

# 以用户身份连接到集群
<a name="tutorials_05_multi-user-ad-step4"></a>

您可以使用以下命令确定集群的状态。

```
$ pcluster describe-cluster -n ad-cluster --region "region-id" --query "clusterStatus"
```

输出如下所示。

```
"CREATE_IN_PROGRESS" / "CREATE_COMPLETE"
```

达到 `"CREATE_COMPLETE"` 状态后，使用创建的用户名和密码登录。

```
$ HEAD_NODE_IP=$(pcluster describe-cluster -n "ad-cluster" --region "region-id" --query headNode.publicIpAddress | xargs echo)
```

```
$ ssh user000@$HEAD_NODE_IP
```

您可以通过提供 `/home/user000@HEAD_NODE_IP/.ssh/id_rsa` 中为新用户创建的 SSH 密钥，而不使用密码进行登录。

如果 `ssh` 命令成功，则表示您已成功以用户身份连接到集群，并通过了身份验证，可以使用 Active Directory (AD)。

# 清理
<a name="tutorials_05_multi-user-ad-step5"></a>

1. 

**从本地计算机上删除集群。**

   ```
   $ pcluster delete-cluster --cluster-name "ad-cluster" --region "region-id"
   {
     "cluster": {
       "clusterName": "ad-cluster",
       "cloudformationStackStatus": "DELETE_IN_PROGRESS",
       "cloudformationStackArn": "arn:aws:cloudformation:region-id:123456789012:stack/ad-cluster/1234567-abcd-0123-def0-abcdef0123456",
       "region": "region-id",
       "version": "3.15.0",
       "clusterStatus": "DELETE_IN_PROGRESS"
     }
   }
   ```

1. 

**检查集群删除进度。**

   ```
   $ pcluster describe-cluster --cluster-name "ad-cluster" --region "region-id" --query "clusterStatus"
   "DELETE_IN_PROGRESS"
   ```

   成功删除集群后，继续执行下一步。

## 自动
<a name="tutorials_05_multi-user-ad-step5-automated"></a>

**删除 Active Directory 资源**

1. 来自[https://console.aws.amazon.com/cloudformation/](https://console.aws.amazon.com/cloudformation/)。

1. 在导航窗格中，选择**堆栈**。

1. 从堆栈列表中选择 AD 堆栈（例如 `pcluster-ad`）。

1. 选择**删除**。

## 手动
<a name="tutorials_05_multi-user-ad-step5-manual"></a>

1. 

**删除 Amazon EC2 实例。**

   1. 从中 [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/)，选择导航窗格中的**实例**。

   1. 从实例列表中，选择您为将用户添加到目录而创建的实例。

   1. 选择**实例状态**，然后选择**终止实例**。

1. 

**删除托管区。**

   1. 创建包含以下内容的 `recordset-delete.json`。在此示例中， HostedZoneId 是负载均衡器的规范托管区域 ID。

      ```
      {
        "Changes": [
          {
            "Action": "DELETE",
            "ResourceRecordSet": {
              "Name": "corp.example.com",
              "Type": "A",
              "Region": "region-id",
              "SetIdentifier": "pcluster-active-directory",
              "AliasTarget": {
                "HostedZoneId": "Z2IFOLAFXWLO4F",
                "DNSName": "CorpExampleCom-NLB-3afe296bf4ba80d4.elb.region-id.amazonaws.com",
                "EvaluateTargetHealth": true
              }
            }
          }
        ]
      }
      ```

   1. 使用托管区 ID 将记录集更改提交到托管区。

      ```
      $ aws route53 change-resource-record-sets --hosted-zone-id Z09020002B5MZQNXMSJUB \
        --change-batch file://recordset-delete.json
      {
       "ChangeInfo": {
           "Id": "/change/C04853642A0TH2TJ5NLNI",
           "Status": "PENDING",
           "SubmittedAt": "2022-05-05T14:25:51.046000+00:00"
       }
      }
      ```

   1. 删除托管区。

      ```
      $ aws route53 delete-hosted-zone --id Z09020002B5MZQNXMSJUB
      {
       "ChangeInfo": {
           "Id": "/change/C0468051QFABTVHMDEG9",
           "Status": "PENDING",
           "SubmittedAt": "2022-05-05T14:26:13.814000+00:00"
       }
      }
      ```

1. 

**删除 LB 侦听器。**

   ```
   $ aws elbv2 delete-listener \
     --listener-arn arn:aws:elasticloadbalancing:region-id:123456789012:listener/net/CorpExampleCom-NLB/3afe296bf4ba80d4/a8f9d97318743d4b --region region-id
   ```

1. 

**删除目标组。**

   ```
   $ aws elbv2 delete-target-group \
     --target-group-arn arn:aws:elasticloadbalancing:region-id:123456789012:targetgroup/CorpExampleCom-Targets/44577c583b695e81 --region region-id
   ```

1. 

**删除负载均衡器。**

   ```
   $ aws elbv2 delete-load-balancer \
     --load-balancer-arn arn:aws:elasticloadbalancing:region-id:123456789012:loadbalancer/net/CorpExampleCom-NLB/3afe296bf4ba80d4 --region region-id
   ```

1. 

**删除集群用于从 Secrets Manager 读取证书的策略。**

   ```
   $ aws iam delete-policy --policy-arn arn:aws:iam::123456789012:policy/ReadCertExample
   ```

1. 

**删除包含域证书的密钥。**

   ```
   $ aws secretsmanager delete-secret \
     --secret-id arn:aws:secretsmanager:region-id:123456789012:secret:example-cert-123abc \
     --region region-id
   {
    "ARN": "arn:aws:secretsmanager:region-id:123456789012:secret:example-cert-123abc",
    "Name": "example-cert",
    "DeletionDate": "2022-06-04T16:27:36.183000+02:00"
   }
   ```

1. 

**从 ACM 中删除证书。**

   ```
   $ aws acm delete-certificate \
     --certificate-arn arn:aws:acm:region-id:123456789012:certificate/343db133-490f-4077-b8d4-3da5bfd89e72 --region region-id
   ```

1. 

**删除 Active Directory (AD) 资源。**

   1.  IDs 从 python 脚本的输出中获取以下资源`ad.py`：
      + AD ID
      + AD 子网 IDs
      + AD VPC ID

   1. 通过运行以下命令删除目录。

      ```
      $ aws ds delete-directory --directory-id d-abcdef0123456789 --region region-id
      {
         "DirectoryId": "d-abcdef0123456789"
      }
      ```

   1. 列出 VPC 中的安全组。

      ```
      $ aws ec2 describe-security-groups --filters '[{"Name":"vpc-id","Values":["vpc-07614ade95ebad1bc"]}]' --region region-id
      ```

   1. 删除自定义安全组。

      ```
      $ aws ec2 delete-security-group --group-id sg-021345abcdef6789 --region region-id
      ```

   1. 删除子网。

      ```
      $ aws ec2 delete-subnet --subnet-id subnet-1234567890abcdef --region region-id
      ```

      ```
      $ aws ec2 delete-subnet --subnet-id subnet-021345abcdef6789 --region region-id
      ```

   1. 描述互联网网关。

      ```
      $ aws ec2 describe-internet-gateways \
        --filters Name=attachment.vpc-id,Values=vpc-021345abcdef6789 \
        --region region-id
      {
        "InternetGateways": [
          {
            "Attachments": [
              {
                "State": "available",
                "VpcId": "vpc-021345abcdef6789"
              }
            ],
            "InternetGatewayId": "igw-1234567890abcdef",
            "OwnerId": "123456789012",
            "Tags": []
          }
        ]  
      }
      ```

   1. 分离互联网网关。

      ```
      $ aws ec2 detach-internet-gateway \
        --internet-gateway-id igw-1234567890abcdef \
        --vpc-id vpc-021345abcdef6789 \
        --region region-id
      ```

   1. 删除互联网网关。

      ```
      $ aws ec2 delete-internet-gateway \
        --internet-gateway-id igw-1234567890abcdef \
        --region region-id
      ```

   1. 删除 VPC。

      ```
      $ aws ec2 delete-vpc \
        --vpc-id vpc-021345abcdef6789 \
        --region region-id
      ```

   1. 删除包含 `ReadOnlyUser` 密码的密钥。

      ```
      $ aws secretsmanager delete-secret \
        --secret-id arn:aws:secretsmanager:region-id:123456789012:secret:ADSecretPassword-1234" \
        --region region-id
      ```

# 使用密 AWS KMS 钥配置共享存储加密
<a name="tutorials_04_encrypted_kms_fs-v3"></a>

了解如何设置客户托管 AWS KMS 密钥来加密和保护您在为其配置的集群文件存储系统中的数据 AWS ParallelCluster。

使用 AWS ParallelCluster 命令行界面 (CLI) 或 API 时，您只需为创建或更新 AWS ParallelCluster 映像和集群时创建的 AWS 资源付费。有关更多信息，请参阅 [AWS 使用的服务 AWS ParallelCluster](aws-services-v3.md)。

AWS ParallelCluster 支持以下共享存储配置选项：
+ [`SharedStorage`](SharedStorage-v3.md) / [`EbsSettings`](SharedStorage-v3.md#SharedStorage-v3-EbsSettings) / [`KmsKeyId`](SharedStorage-v3.md#yaml-SharedStorage-EbsSettings-KmsKeyId)
+ [`SharedStorage`](SharedStorage-v3.md) / [`EfsSettings`](SharedStorage-v3.md#SharedStorage-v3-EfsSettings) / [`KmsKeyId`](SharedStorage-v3.md#yaml-SharedStorage-EfsSettings-KmsKeyId)
+ [`SharedStorage`](SharedStorage-v3.md) / [`FsxLustreSettings`](SharedStorage-v3.md#SharedStorage-v3-FsxLustreSettings) / [`KmsKeyId`](SharedStorage-v3.md#yaml-SharedStorage-FsxLustreSettings-KmsKeyId)

您可以使用这些选项为 Amazon EBS、Amazon EFS 和 Lustre 共享存储系统 FSx 加密提供客户托管 AWS KMS 密钥。要使用这些选项，您必须为以下各项创建并配置 IAM 策略：
+ [`HeadNode`](HeadNode-v3.md) / [`Iam`](HeadNode-v3.md#HeadNode-v3-Iam) / [`AdditionalIamPolicies`](HeadNode-v3.md#yaml-HeadNode-Iam-AdditionalIamPolicies) / [`Policy`](HeadNode-v3.md#yaml-HeadNode-Iam-AdditionalIamPolicies-Policy)
+ [`Scheduler`](Scheduling-v3.md#yaml-Scheduling-Scheduler) / [`SlurmQueues`](Scheduling-v3.md#Scheduling-v3-SlurmQueues) / [`Iam`](Scheduling-v3.md#Scheduling-v3-SlurmQueues-Iam) / [`AdditionalIamPolicies`](Scheduling-v3.md#yaml-Scheduling-SlurmQueues-Iam-AdditionalIamPolicies) / [`Policy`](Scheduling-v3.md#yaml-Scheduling-SlurmQueues-Iam-AdditionalIamPolicies-Policy) 

**先决条件**
+ AWS ParallelCluster [已安装](install-v3-parallelcluster.md)。
+  AWS CLI [已安装并配置。](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ 您有一个 [Amazon EC2 密钥对](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html)。
+ 您拥有具有运行 [`pcluster`](pcluster-v3.md) CLI 所需的[权限](iam-roles-in-parallelcluster-v3.md#iam-roles-in-parallelcluster-v3-example-user-policies)的 IAM 角色。

**Topics**
+ [

# 创建策略
](creating-the-role-v3.md)
+ [

# 配置和创建集群
](creating-the-cluster-v3.md)

# 创建策略
<a name="creating-the-role-v3"></a>

在本教程中，您将创建一个使用密 AWS KMS 钥配置共享存储加密的策略。

**创建策略。**

1. 前往 IAM 控制台：[https://console.aws.amazon.com/iam/主页](https://console.aws.amazon.com/iam/home)。

1. 选择**策略**。

1. 选择**创建策略**。

1. 选择 **JSON** 选项卡，然后粘贴以下策略。请务必将所有出现的`123456789012`替换为您的 AWS 账户 ID 和密钥 Amazon 资源名称 (ARN) 以及 AWS 区域 您自己的名称。

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "kms:DescribeKey",
                   "kms:ReEncrypt*",
                   "kms:CreateGrant",
                   "kms:Decrypt"
               ],
               "Resource": [
                   "arn:aws:kms:us-east-1:123456789012:key/abcd1234-ef56-gh78-ij90-abcd1234efgh5678"
               ]
           }
       ]
   }
   ```

------

1. 对于本教程，将策略命名为 `ParallelClusterKmsPolicy`，然后选择**创建策略**。

1. 记下策略 ARN。您需要用它来配置您的集群。

# 配置和创建集群
<a name="creating-the-cluster-v3"></a>

下面是一个示例集群配置，其中包括带加密功能的 Amazon Elastic Block Store 共享文件系统。

```
Region: eu-west-1
Image:
  Os: alinux2
HeadNode:
  InstanceType: t2.micro
  Networking:
    SubnetId: subnet-abcdef01234567890
  Ssh:
    KeyName: my-ssh-key
  Iam:
    AdditionalIamPolicies:
      - Policy: arn:aws:iam::123456789012:policy/ParallelClusterKmsPolicy
Scheduling:
  Scheduler: slurm
  SlurmQueues:
    - Name: q1
      ComputeResources:
        - Name: t2micro
          InstanceType: t2.micro
          MinCount: 0
          MaxCount: 10
      Networking:
        SubnetIds:
          - subnet-abcdef01234567890
      Iam:
        AdditionalIamPolicies:
          - Policy: arn:aws:iam::123456789012:policy/ParallelClusterKmsPolicy
SharedStorage:
  - MountDir: /shared/ebs1
    Name: shared-ebs1
    StorageType: Ebs
    EbsSettings:
      Encrypted: True
      KmsKeyId: abcd1234-ef56-gh78-ij90-abcd1234efgh5678
```

将红色文本项目替换为您自己的值。然后，创建一个使用您的 AWS KMS 密钥对 Amazon EBS 中的数据进行加密的集群。

Amazon EFS 和 FSx Lustre 文件系统的配置类似。

Amazon EFS `SharedStorage` 配置如下。

```
...
SharedStorage:
  - MountDir: /shared/efs1
    Name: shared-efs1
    StorageType: Efs
    EfsSettings:
      Encrypted: True
      KmsKeyId: abcd1234-ef56-gh78-ij90-abcd1234efgh5678
```

fo FSx r Lustre 的`SharedStorage`配置如下所示。

```
...
SharedStorage:
  - MountDir: /shared/fsx1
    Name: shared-fsx1
    StorageType: FsxLustre
    FsxLustreSettings:
      StorageCapacity: 1200
      DeploymentType: PERSISTENT_1
      PerUnitStorageThroughput: 200
      KmsKeyId: abcd1234-ef56-gh78-ij90-abcd1234efgh5678
```

# 在多队列模式集群中运行作业
<a name="multi-queue-tutorial-v3"></a>

本教程介绍如何在[多队列模式下运行第一个 Hello World](configuration-of-multiple-queues-v3.md) “” 作业。 AWS ParallelCluster 

使用 AWS ParallelCluster 命令行界面 (CLI) 或 API 时，您只需为创建或更新 AWS ParallelCluster 映像和集群时创建的 AWS 资源付费。有关更多信息，请参阅 [AWS 使用的服务 AWS ParallelCluster](aws-services-v3.md)。

**先决条件**
+ AWS ParallelCluster [已安装](install-v3-parallelcluster.md)。
+  AWS CLI [已安装并配置。](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ 您有一个 [Amazon EC2 密钥对](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html)。
+ 您拥有具有运行 [`pcluster`](pcluster-v3.md) CLI 所需的[权限](iam-roles-in-parallelcluster-v3.md#iam-roles-in-parallelcluster-v3-example-user-policies)的 IAM 角色。

## 配置集群
<a name="multi-queue-tutorial-v3-configure-cluster"></a>

首先，通过运行以下命令验证安装 AWS ParallelCluster 是否正确。

```
$ pcluster version
```

有关 `pcluster version`的更多信息，请参阅[`pcluster version`](pcluster.version-v3.md)。

此命令返回的运行版本 AWS ParallelCluster。

接下来，运行 `pcluster configure` 以生成基本配置文件。按照运行此命令后的所有提示进行操作。

```
$ pcluster configure --config multi-queue-mode.yaml
```

有关 `pcluster configure` 命令的更多信息，请参阅[`pcluster configure`](pcluster.configure-v3.md)。

完成此步骤后，将出现一个名为 `multi-queue-mode.yaml` 的基本配置文件。此文件包含基本集群配置。

在下一步中，您将修改新配置文件并启动包含多个队列的集群。

**注意**  
本教程中使用的某些实例不符合免费套餐资格。

在本教程中，请修改您的配置文件以匹配以下配置。以红色突出显示的项目代表您的配置文件值。请使用您自己的值。

```
Region: region-id
Image:
 Os: alinux2
HeadNode:
 InstanceType: c5.xlarge
 Networking:
   SubnetId: subnet-abcdef01234567890
 Ssh:
   KeyName: yourkeypair
Scheduling:
 Scheduler: slurm
 SlurmQueues:
 - Name: spot
   ComputeResources:
   - Name: c5xlarge
     InstanceType: c5.xlarge
     MinCount: 1
     MaxCount: 10
   - Name: t2micro
     InstanceType: t2.micro
     MinCount: 1
     MaxCount: 10
   Networking:
     SubnetIds:
     - subnet-abcdef01234567890
 - Name: ondemand
   ComputeResources:
   - Name: c52xlarge
     InstanceType: c5.2xlarge
     MinCount: 0
     MaxCount: 10
   Networking:
     SubnetIds:
     - subnet-021345abcdef6789
```

## 创建集群
<a name="multi-queue-tutorial-v3-create-cluster"></a>

根据您的配置文件，创建一个名为 `multi-queue-cluster` 的集群。

```
$ pcluster create-cluster --cluster-name multi-queue-cluster --cluster-configuration multi-queue-mode.yaml
{
 "cluster": {
   "clusterName": "multi-queue-cluster",
   "cloudformationStackStatus": "CREATE_IN_PROGRESS",
   "cloudformationStackArn": "arn:aws:cloudformation:eu-west-1:123456789012:stack/multi-queue-cluster/1234567-abcd-0123-def0-abcdef0123456",
   "region": "eu-west-1",
   "version": "3.15.0",
   "clusterStatus": "CREATE_IN_PROGRESS"
 }
}
```

有关 `pcluster create-cluster` 命令的更多信息，请参阅[`pcluster create-cluster`](pcluster.create-cluster-v3.md)。

要检查集群的状态，请运行以下命令。

```
$ pcluster list-clusters
{
 "cluster": {
   "clusterName": "multi-queue-cluster",
   "cloudformationStackStatus": "CREATE_IN_PROGRESS",
   "cloudformationStackArn": "arn:aws:cloudformation:eu-west-1:123456789012:stack/multi-queue-cluster/1234567-abcd-0123-def0-abcdef0123456",
   "region": "eu-west-1",
   "version": "3.15.0",
   "clusterStatus": "CREATE_IN_PROGRESS"
 }
}
```

创建集群后，`clusterStatus` 字段将显示 `CREATE_COMPLETE`。

## 登录到头节点
<a name="multi-queue-tutorial-v3-log-into-head-node"></a>

使用您的私有 SSH 密钥文件登录到头节点。

```
$ pcluster ssh --cluster-name multi-queue-cluster -i ~/path/to/yourkeyfile.pem
```

有关 `pcluster ssh`的更多信息，请参阅[`pcluster ssh`](pcluster.ssh-v3.md)。

登录后，运行命令 `sinfo` 以验证是否已设置和配置调度器队列。

有关 `sinfo` 的更多信息，请参阅 *Slurm 文档* 中的 [sinfo](https://slurm.schedmd.com/sinfo.html)。

```
$ sinfo
PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST
spot*        up   infinite     18  idle~ spot-dy-c5xlarge-[1-9],spot-dy-t2micro-[1-9]
spot*        up   infinite      2  idle  spot-st-c5xlarge-1,spot-st-t2micro-1
ondemand     up   infinite     10  idle~ ondemand-dy-c52xlarge-[1-10]
```

输出显示您的集群中有一个 `t2.micro` 和一个 `c5.xlarge` 计算节点处于 `idle` 状态。

其它节点都处于节能状态，通过节点状态中的 `~` 后缀指示，没有支持它们的 Amazon EC2 实例。默认队列由队列名称后面的 `*` 后缀指示。`spot` 是默认作业队列。

## 在多队列模式下运行作业
<a name="multi-queue-tutorial-v3-running-job-mqm"></a>

接下来，尝试将作业运行到睡眠模式一段时间。该作业稍后将输出自己的主机名。确保当前用户可以运行此脚本。

```
$ tee <<EOF hellojob.sh
#!/bin/bash
sleep 30
echo "Hello World from \$(hostname)"
EOF

$ chmod +x hellojob.sh
$ ls -l hellojob.sh
-rwxrwxr-x 1 ec2-user ec2-user 57 Sep 23 21:57 hellojob.sh
```

使用 `sbatch` 命令提交作业。使用 `-N 2` 选项为该作业请求两个节点，然后验证作业是否成功提交。有关 `sbatch` 的更多信息，请参阅 *Slurm 文档* 中的 [https://slurm.schedmd.com/sbatch.html](https://slurm.schedmd.com/sbatch.html)。

```
$ sbatch -N 2 --wrap "srun hellojob.sh"
Submitted batch job 1
```

您可以使用 `squeue` 命令查看您的队列并检查该作业的状态。由于您未指定特定队列，因此使用默认队列 (`spot`)。有关 `squeue` 的更多信息，请参阅 *Slurm 文档* 中的 [https://slurm.schedmd.com/squeue.html](https://slurm.schedmd.com/squeue.html)。

```
$ squeue
JOBID PARTITION     NAME     USER  ST      TIME  NODES NODELIST(REASON)
   1      spot     wrap ec2-user  R       0:10      2 spot-st-c5xlarge-1,spot-st-t2micro-1
```

输出显示此作业目前处于运行状态。等待作业完成。这大约需要 30 秒。然后，再次运行 `squeue`。

```
$ squeue
JOBID PARTITION     NAME     USER          ST       TIME  NODES NODELIST(REASON)
```

现在，队列中的作业已全部完成，请在当前目录中查找名为 `slurm-1.out` 的输出文件。

```
$ cat slurm-1.out
Hello World from spot-st-t2micro-1
Hello World from spot-st-c5xlarge-1
```

输出显示该作业已在 `spot-st-t2micro-1` 和 `spot-st-c5xlarge-1` 节点上成功运行。

现在，通过使用以下命令为特定实例指定约束条件来提交相同的作业。

```
$ sbatch -N 3 -p spot -C "[c5.xlarge*1&t2.micro*2]" --wrap "srun hellojob.sh"
Submitted batch job 2
```

您对 `sbatch` 使用了以下参数：
+ `-N 3`：请求三个节点。
+ `-p spot`：将作业提交到 `spot` 队列。您也可以通过指定 `-p ondemand`，将作业提交到 `ondemand` 队列。
+ `-C "[c5.xlarge*1&t2.micro*2]"`：指定该作业的特定节点约束条件。这将请求对该作业使用一个 `c5.xlarge` 节点和两个 `t2.micro` 节点。

运行 `sinfo` 命令查看节点和队列。中的队 AWS ParallelCluster 列称为中的分区Slurm。

```
$ sinfo
PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST
spot*        up   infinite      1  alloc# spot-dy-t2micro-1
spot*        up   infinite     17  idle~ spot-dy-c5xlarge-[2-10],spot-dy-t2micro-[2-9]
spot*        up   infinite      1  mix   spot-st-c5xlarge-1
spot*        up   infinite      1  alloc spot-st-t2micro-1
ondemand     up   infinite     10  idle~ ondemand-dy-c52xlarge-[1-10]
```

节点正在启动。这由节点状态上的 `#` 后缀指示。运行 squeue 命令查看集群中作业的信息。

```
$ squeue
JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
   2      spot     wrap ec2-user CF       0:04      3 spot-dy-c5xlarge-1,spot-dy-t2micro-1,spot-st-t2micro-1
```

您的作业处于 `CF` (CONFIGURING) 状态，正在等待实例纵向扩展并加入集群。

大约三分钟后，节点可用，并且作业进入 `R` (RUNNING) 状态。

```
$ squeue
JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
   2      spot     wrap ec2-user  R       0:07      3 spot-dy-t2micro-1,spot-st-c5xlarge-1,spot-st-t2micro-1
```

作业完成，所有三个节点都处于 `idle` 状态。

```
$ squeue
JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
$ sinfo
PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST
spot*        up   infinite     17  idle~ spot-dy-c5xlarge-[1-9],spot-dy-t2micro-[2-9]
spot*        up   infinite      3  idle  spot-dy-t2micro-1,spot-st-c5xlarge-1,spot-st-t2micro-1
ondemand     up   infinite     10  idle~ ondemand-dy-c52xlarge-[1-10]
```

然后，当队列中没有剩余作业后，在本地目录中查看 `slurm-2.out`。

```
$ cat slurm-2.out 
Hello World from spot-st-t2micro-1
Hello World from spot-dy-t2micro-1
Hello World from spot-st-c5xlarge-1
```

以下是集群的最终状态。

```
$ sinfo
PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST
spot*        up   infinite     17  idle~ spot-dy-c5xlarge-[1-9],spot-dy-t2micro-[2-9]
spot*        up   infinite      3  idle  spot-dy-t2micro-1,spot-st-c5xlarge-1,spot-st-t2micro-1
ondemand     up   infinite     10  idle~ ondemand-dy-c52xlarge-[1-10]
```

注销集群后，您可以通过运行 `pcluster delete-cluster` 来进行清理。有关更多信息，请参阅[`pcluster list-clusters`](pcluster.list-clusters-v3.md)和[`pcluster delete-cluster`](pcluster.delete-cluster-v3.md)。

```
$ pcluster list-clusters
{
 "clusters": [
   {
     "clusterName": "multi-queue-cluster",
     "cloudformationStackStatus": "CREATE_COMPLETE",
     "cloudformationStackArn": "arn:aws:cloudformation:eu-west-1:123456789012:stack/multi-queue-cluster/1234567-abcd-0123-def0-abcdef0123456",
     "region": "eu-west-1",
     "version": "3.1.4",
     "clusterStatus": "CREATE_COMPLETE"
   }
 ]
}
$ pcluster delete-cluster -n multi-queue-cluster
{
 "cluster": {
   "clusterName": "multi-queue-cluster",
   "cloudformationStackStatus": "DELETE_IN_PROGRESS",
   "cloudformationStackArn": "arn:aws:cloudformation:eu-west-1:123456789012:stack/multi-queue-cluster/1234567-abcd-0123-def0-abcdef0123456",
   "region": "eu-west-1",
   "version": "3.1.4",
   "clusterStatus": "DELETE_IN_PROGRESS"
 }
}
```

# 使用 AWS ParallelCluster API
<a name="tutorials_06_API_use"></a>

在本教程中，您将使用 [Amazon API Gateway 和 AWS ParallelCluster CloudFormation 模板来构建和测试 API](https://docs.aws.amazon.com/apigateway/latest/developerguide/welcome.html)。然后，您可以使用上提供的示例客户端 GitHub 来使用 API。有关使用 API 的更多信息，请参阅 [AWS ParallelCluster API](api-reference-v3.md)。

有关更多信息，请参阅 Image [Builder *用户指南中的使用 Imag EC2 e Builder* 创建自定义组件](https://docs.aws.amazon.com/imagebuilder/latest/userguide/create-component.html)。

使用 AWS ParallelCluster 命令行界面 (CLI) 或 API 时，您只需为创建或更新 AWS ParallelCluster 映像和集群时创建的 AWS 资源付费。有关更多信息，请参阅 [AWS 使用的服务 AWS ParallelCluster](aws-services-v3.md)。

**先决条件**
+ 已在您的计算环境中[安装](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)和配置。 AWS CLI 
+ AWS ParallelCluster 安装在虚拟环境中。有关更多信息，请参阅 [AWS ParallelCluster 在虚拟环境中安装（推荐）](install-v3-virtual-environment.md)。
+ 你有一个 A [mazon EC2 密钥对](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html)。
+ 您拥有具有运行 [`pcluster`](pcluster-v3.md) CLI 所需的[权限](iam-roles-in-parallelcluster-v3.md#iam-roles-in-parallelcluster-v3-example-user-policies)的 IAM 角色。



## 步骤 1：使用 Amazon API Gateway 构建 API
<a name="tutorials_06_multi-API-use-step1"></a>

**留在您的主用户目录中并激活您的虚拟环境：**

1. 安装有用的 JSON 命令行处理器。

   ```
   $ sudo yum groupinstall -y "Development Tools"
    sudo yum install -y jq python3-devel
   ```

1. 运行以下命令获取您的 AWS ParallelCluster 版本并将其分配给环境变量。

   ```
   $ PCLUSTER_VERSION=$(pcluster version | jq -r '.version')
    echo "export PCLUSTER_VERSION=${PCLUSTER_VERSION}" |tee -a ~/.bashrc
   ```

1. 创建环境变量并将您的区域 ID 分配给该变量。

   ```
   $ export AWS_DEFAULT_REGION="us-east-1"
    echo "export AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION}" |tee -a ~/.bashrc
   ```

1. 运行以下命令以部署 API。

   ```
   API_STACK_NAME="pc-api-stack"
    echo "export API_STACK_NAME=${API_STACK_NAME}" |tee -a ~/.bashrc
   ```

   ```
   aws cloudformation create-stack \
      --region ${AWS_DEFAULT_REGION} \
      --stack-name ${API_STACK_NAME} \
      --template-url https://${AWS_DEFAULT_REGION}-aws-parallelcluster.s3.${AWS_DEFAULT_REGION}.amazonaws.com/parallelcluster/${PCLUSTER_VERSION}/api/parallelcluster-api.yaml \
      --capabilities CAPABILITY_NAMED_IAM CAPABILITY_AUTO_EXPAND \
      --parameters ParameterKey=EnableIamAdminAccess,ParameterValue=true
        
       {
          "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/my-api-stack/abcd1234-ef56-gh78-ei90-1234abcd5678"
       }
   ```

   过程完成后，继续执行下一步。

## 步骤 2：在 Amazon API Gateway 控制台中测试 API
<a name="tutorials_06_multi-API-use-step2"></a>

1. 登录到 AWS 管理控制台。

1. 导航到 [Amazon API Gateway 控制台](https://console.aws.amazon.com/apigateway/home)。

1. 选择您的 API 部署。  
![\[显示可供您选择的网关列表的 Amazon API Gateway 控制台。\]](http://docs.aws.amazon.com/zh_cn/parallelcluster/latest/ug/images/gateway_choose.png)

1. 选择**阶段**，然后选择一个阶段。  
![\[可供您选择的阶段的控制台视图。您还可以查看 API Gateway 为您的 API 提供的 URL。\]](http://docs.aws.amazon.com/zh_cn/parallelcluster/latest/ug/images/gateway_address.png)

1. 记下 API Gateway 提供的用于访问或调用您的 API 的 URL。它以蓝色突出显示。

1. 选择**资源**，然后选择 **`/clusters`** 下面的 **`GET`**。

1. 选择**测试**图标，然后向下滚动并选择**测试**图标。  
![\[API 资源和测试机制的控制台视图。\]](http://docs.aws.amazon.com/zh_cn/parallelcluster/latest/ug/images/gateway_test.png)

   将显示 `/clusters GET` 的响应。  
![\[API 资源、测试机制和测试请求响应的控制台视图。\]](http://docs.aws.amazon.com/zh_cn/parallelcluster/latest/ug/images/gateway.png)

## 步骤 3：准备并测试用于调用 API 的示例客户端
<a name="tutorials_06_multi-API-use-step3"></a>



将 AWS ParallelCluster 源代码克隆`cd`到`api`目录中，然后安装 Python 客户端库。

1. 

   ```
   $ git clone -b v${PCLUSTER_VERSION} https://github.com/aws/aws-parallelcluster aws-parallelcluster-v${PCLUSTER_VERSION}
    cd aws-parallelcluster-v${PCLUSTER_VERSION}/api
   ```

   ```
   $ pip3 install client/src
   ```

1. 导航回您的主用户目录。

1. 导出客户端在运行时使用的 API Gateway 基本 URL。

   ```
   $ export PCLUSTER_API_URL=$( aws cloudformation describe-stacks --stack-name ${API_STACK_NAME} --query 'Stacks[0].Outputs[?OutputKey==`ParallelClusterApiInvokeUrl`].OutputValue' --output text )
    echo "export PCLUSTER_API_URL=${PCLUSTER_API_URL}" |tee -a ~/.bashrc
   ```

1. 导出客户端用于创建集群的集群名称。

   ```
   $ export CLUSTER_NAME="test-api-cluster"
    echo "export CLUSTER_NAME=${CLUSTER_NAME}" |tee -a ~/.bashrc
   ```

1. 运行以下命令以存储示例客户端用于访问 API 的凭证。

   ```
   $ export PCLUSTER_API_USER_ROLE=$( aws cloudformation describe-stacks --stack-name ${API_STACK_NAME} --query 'Stacks[0].Outputs[?OutputKey==`ParallelClusterApiUserRole`].OutputValue' --output text )
    echo "export PCLUSTER_API_USER_ROLE=${PCLUSTER_API_USER_ROLE}" |tee -a ~/.bashrc
   ```

## 步骤 4：复制客户端代码脚本并运行集群测试
<a name="tutorials_06_multi-API-use-step4"></a>

1. 将以下示例客户端代码复制到您的主用户目录中的 `test_pcluster_client.py`。客户端代码发出执行以下操作的请求：
   + 创建集群。
   + 描述集群。
   + 列出集群。
   + 描述计算实例集。
   + 描述集群实例。

   ```
   # Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
   # SPDX-License-Identifier: MIT-0
   #
   # Permission is hereby granted, free of charge, to any person obtaining a copy of this
   # software and associated documentation files (the "Software"), to deal in the Software
   # without restriction, including without limitation the rights to use, copy, modify,
   # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
   # permit persons to whom the Software is furnished to do so.
   #
   # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
   # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
   # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
   # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
   # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   #
   #  Author: Evan F. Bollig (Github: bollig)
   
   import time, datetime
   import os
   import pcluster_client
   from pprint import pprint
   from pcluster_client.api import (
       cluster_compute_fleet_api,
       cluster_instances_api,
       cluster_operations_api
   )
   from pcluster_client.model.create_cluster_request_content import CreateClusterRequestContent
   from pcluster_client.model.cluster_status import ClusterStatus
   region=os.environ.get("AWS_DEFAULT_REGION")
   
   # Defining the host is optional and defaults to http://localhost
   # See configuration.py for a list of all supported configuration parameters.
   configuration = pcluster_client.Configuration(
       host = os.environ.get("PCLUSTER_API_URL")
   )
   cluster_name=os.environ.get("CLUSTER_NAME")
   
   # Enter a context with an instance of the API client
   with pcluster_client.ApiClient(configuration) as api_client:
       cluster_ops = cluster_operations_api.ClusterOperationsApi(api_client)
       fleet_ops = cluster_compute_fleet_api.ClusterComputeFleetApi(api_client)
       instance_ops = cluster_instances_api.ClusterInstancesApi(api_client)
       
       # Create cluster
       build_done = False
       try:
           with open('cluster-config.yaml', encoding="utf-8") as f:
               body = CreateClusterRequestContent(cluster_name=cluster_name, cluster_configuration=f.read())
               api_response = cluster_ops.create_cluster(body, region=region)
       except pcluster_client.ApiException as e:
           print("Exception when calling create_cluster: %s\n" % e)
           build_done = True
       time.sleep(60)
       
       # Confirm cluster status with describe_cluster
       while not build_done:
           try:
               api_response = cluster_ops.describe_cluster(cluster_name, region=region)
               pprint(api_response)
               if api_response.cluster_status == ClusterStatus('CREATE_IN_PROGRESS'):
                   print('. . . working . . .', end='', flush=True)
                   time.sleep(60)
               elif api_response.cluster_status == ClusterStatus('CREATE_COMPLETE'):
                   print('READY!')
                   build_done = True
               else:
                   print('ERROR!!!!')
                   build_done = True    
           except pcluster_client.ApiException as e:
               print("Exception when calling describe_cluster: %s\n" % e)  
    
       # List clusters
       try:
           api_response = cluster_ops.list_clusters(region=region)
           pprint(api_response)
       except pcluster_client.ApiException as e:
           print("Exception when calling list_clusters: %s\n" % e)
                   
       # DescribeComputeFleet
       try:
           api_response = fleet_ops.describe_compute_fleet(cluster_name, region=region)
           pprint(api_response)
       except pcluster_client.ApiException as e:
           print("Exception when calling compute fleet: %s\n" % e)
   
       # DescribeClusterInstances
       try:
           api_response = instance_ops.describe_cluster_instances(cluster_name, region=region)
           pprint(api_response)
       except pcluster_client.ApiException as e:
           print("Exception when calling describe_cluster_instances: %s\n" % e)
   ```

1. 创建集群配置。

   ```
   $ pcluster configure --config cluster-config.yaml
   ```

1. API 客户端库将自动从您的环境变量（例如 `AWS_ACCESS_KEY_ID`、`AWS_SECRET_ACCESS_KEY` 或 `AWS_SESSION_TOKEN`）或 `$HOME/.aws` 中检测配置详细信息。以下命令可将您当前的 IAM 角色切换到指定的 ParallelClusterApiUserRole。

   ```
   $  eval $(aws sts assume-role --role-arn ${PCLUSTER_API_USER_ROLE} --role-session-name ApiTestSession | jq -r '.Credentials | "export AWS_ACCESS_KEY_ID=\(.AccessKeyId)\nexport AWS_SECRET_ACCESS_KEY=\(.SecretAccessKey)\nexport AWS_SESSION_TOKEN=\(.SessionToken)\n"')
   ```

   **需要注意的错误：**

   如果您看到类似于下面的错误，则表示您已经假定 ParallelClusterApiUserRole 和您的 `AWS_SESSION_TOKEN` 已过期。

   ```
   An error occurred (AccessDenied) when calling the AssumeRole operation: 
   User: arn:aws:sts::XXXXXXXXXXXX:assumed-role/ParallelClusterApiUserRole-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/ApiTestSession 
   is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::XXXXXXXXXXXX:role/ParallelClusterApiUserRole-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
   ```

   删除该角色，然后重新运行 `aws sts assume-role` 命令以使用 ParallelClusterApiUserRole。

   ```
   $ unset AWS_SESSION_TOKEN
   unset AWS_SECRET_ACCESS_KEY
   unset AWS_ACCESS_KEY_ID
   ```

   要向您当前的用户提供 API 访问权限，您必须[扩展资源策略](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-resource-policies.html)。

1. 运行以下命令以测试示例客户端。

   ```
   $ python3 test_pcluster_client.py
   {'cluster_configuration': 'Region: us-east-1\n'
                             'Image:\n'
                             '  Os: alinux2\n'
                             'HeadNode:\n'
                             '  InstanceType: t2.micro\n'
                             '  Networking . . . :\n'
                             '    SubnetId: subnet-1234567890abcdef0\n'
                             '  Ssh:\n'
                             '    KeyName: adpc\n'
                             'Scheduling:\n'
                             '  Scheduler: slurm\n'
                             '  SlurmQueues:\n'
                             '  - Name: queue1\n'
                             '    ComputeResources:\n'
                             '    - Name: t2micro\n'
                             '      InstanceType: t2.micro\n'
                             '      MinCount: 0\n'
                             '      MaxCount: 10\n'
                             '    Networking . . . :\n'
                             '      SubnetIds:\n'
                             '      - subnet-1234567890abcdef0\n',
    'cluster_name': 'test-api-cluster'}
   {'cloud_formation_stack_status': 'CREATE_IN_PROGRESS',
    'cloudformation_stack_arn': 'arn:aws:cloudformation:us-east-1:123456789012:stack/test-api-cluster/abcd1234-ef56-gh78-ij90-1234abcd5678',
    'cluster_configuration': {'url': 'https://parallelcluster-021345abcdef6789-v1-do-not-delete...},
    'cluster_name': 'test-api-cluster',
    'cluster_status': 'CREATE_IN_PROGRESS',
    'compute_fleet_status': 'UNKNOWN',
    'creation_time': datetime.datetime(2022, 4, 28, 16, 18, 47, 972000, tzinfo=tzlocal()),
    'last_updated_time': datetime.datetime(2022, 4, 28, 16, 18, 47, 972000, tzinfo=tzlocal()),
    'region': 'us-east-1',
    'tags': [{'key': 'parallelcluster:version', 'value': '3.1.3'}],
    'version': '3.1.3'}
           .
           . 
           .
   . . . working . . . {'cloud_formation_stack_status': 'CREATE_COMPLETE',
    'cloudformation_stack_arn': 'arn:aws:cloudformation:us-east-1:123456789012:stack/test-api-cluster/abcd1234-ef56-gh78-ij90-1234abcd5678',
    'cluster_configuration': {'url': 'https://parallelcluster-021345abcdef6789-v1-do-not-delete...},
    'cluster_name': 'test-api-cluster',
    'cluster_status': 'CREATE_COMPLETE',
    'compute_fleet_status': 'RUNNING',
    'creation_time': datetime.datetime(2022, 4, 28, 16, 18, 47, 972000, tzinfo=tzlocal()),
    'head_node': {'instance_id': 'i-abcdef01234567890',
                  'instance_type': 't2.micro',
                  'launch_time': datetime.datetime(2022, 4, 28, 16, 21, 46, tzinfo=tzlocal()),
                  'private_ip_address': '172.31.27.153',
                  'public_ip_address': '52.90.156.51',
                  'state': 'running'},
    'last_updated_time': datetime.datetime(2022, 4, 28, 16, 18, 47, 972000, tzinfo=tzlocal()),
    'region': 'us-east-1',
    'tags': [{'key': 'parallelcluster:version', 'value': '3.1.3'}],
    'version': '3.1.3'}
   READY!
   ```

## 步骤 5：复制客户端代码脚本并删除集群
<a name="tutorials_06_multi-API-use-step5"></a>

1. 将以下示例客户端代码复制到 `delete_cluster_client.py`。客户端代码发出删除集群的请求。

   ```
   # Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
   # SPDX-License-Identifier: MIT-0
   #
   # Permission is hereby granted, free of charge, to any person obtaining a copy of this
   # software and associated documentation files (the "Software"), to deal in the Software
   # without restriction, including without limitation the rights to use, copy, modify,
   # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
   # permit persons to whom the Software is furnished to do so.
   #
   # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
   # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
   # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
   # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
   # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   #
   #  Author: Evan F. Bollig (Github: bollig)
   
   import time, datetime
   import os
   import pcluster_client
   from pprint import pprint
   from pcluster_client.api import (
       cluster_compute_fleet_api,
       cluster_instances_api,
       cluster_operations_api
   )
   from pcluster_client.model.create_cluster_request_content import CreateClusterRequestContent
   from pcluster_client.model.cluster_status import ClusterStatus
   region=os.environ.get("AWS_DEFAULT_REGION")
   
   # Defining the host is optional and defaults to http://localhost
   # See configuration.py for a list of all supported configuration parameters.
   configuration = pcluster_client.Configuration(
       host = os.environ.get("PCLUSTER_API_URL")
   )
   cluster_name=os.environ.get("CLUSTER_NAME")
   
   # Enter a context with an instance of the API client
   with pcluster_client.ApiClient(configuration) as api_client:
       cluster_ops = cluster_operations_api.ClusterOperationsApi(api_client)
       
       # Delete the cluster
       gone = False
       try:
           api_response = cluster_ops.delete_cluster(cluster_name, region=region)
       except pcluster_client.ApiException as e:
           print("Exception when calling delete_cluster: %s\n" % e)
       time.sleep(60)
       
       # Confirm cluster status with describe_cluster
       while not gone:
           try:
               api_response = cluster_ops.describe_cluster(cluster_name, region=region)
               pprint(api_response)
               if api_response.cluster_status == ClusterStatus('DELETE_IN_PROGRESS'):
                   print('. . . working . . .', end='', flush=True)
                   time.sleep(60)    
           except pcluster_client.ApiException as e:
               gone = True
               print("DELETE COMPLETE or Exception when calling describe_cluster: %s\n" % e)
   ```

1. 运行以下命令以删除集群。

   ```
   $ python3 delete_cluster_client.py
   {'cloud_formation_stack_status': 'DELETE_IN_PROGRESS',
   'cloudformation_stack_arn': 'arn:aws:cloudformation:us-east-1:123456789012:stack/test-api-cluster/abcd1234-ef56-gh78-ij90-1234abcd5678',
   'cluster_configuration': {'url': 'https://parallelcluster-021345abcdef6789-v1-do-not-delete...},
   'cluster_name': 'test-api-cluster',
   'cluster_status': 'DELETE_IN_PROGRESS',
   'compute_fleet_status': 'UNKNOWN',
   'creation_time': datetime.datetime(2022, 4, 28, 16, 50, 47, 943000, tzinfo=tzlocal()),
   'head_node': {'instance_id': 'i-abcdef01234567890',
                 'instance_type': 't2.micro',
                 'launch_time': datetime.datetime(2022, 4, 28, 16, 53, 48, tzinfo=tzlocal()),
                 'private_ip_address': '172.31.17.132',
                 'public_ip_address': '34.201.100.37',
                 'state': 'running'},
   'last_updated_time': datetime.datetime(2022, 4, 28, 16, 50, 47, 943000, tzinfo=tzlocal()),
   'region': 'us-east-1',
   'tags': [{'key': 'parallelcluster:version', 'value': '3.1.3'}],
   'version': '3.1.3'}
          .
          . 
          .
   . . . working . . . {'cloud_formation_stack_status': 'DELETE_IN_PROGRESS',
   'cloudformation_stack_arn': 'arn:aws:cloudformation:us-east-1:123456789012:stack/test-api-cluster/abcd1234-ef56-gh78-ij90-1234abcd5678',
   'cluster_configuration': {'url': 'https://parallelcluster-021345abcdef6789-v1-do-not-delete...},
   'cluster_name': 'test-api-cluster',
   'cluster_status': 'DELETE_IN_PROGRESS',
   'compute_fleet_status': 'UNKNOWN',
   'creation_time': datetime.datetime(2022, 4, 28, 16, 50, 47, 943000, tzinfo=tzlocal()),
   'last_updated_time': datetime.datetime(2022, 4, 28, 16, 50, 47, 943000, tzinfo=tzlocal()),
   'region': 'us-east-1',
   'tags': [{'key': 'parallelcluster:version', 'value': '3.1.3'}],
   'version': '3.1.3'}
   . . . working . . . DELETE COMPLETE or Exception when calling describe_cluster: (404)
   Reason: Not Found
    	      .
    	      .
    	      .
   HTTP response body: {"message":"Cluster 'test-api-cluster' does not exist or belongs to an incompatible ParallelCluster major version."}
   ```

1. 测试完成后，取消设置环境变量。

   ```
   $ unset AWS_SESSION_TOKEN
   unset AWS_SECRET_ACCESS_KEY
   unset AWS_ACCESS_KEY_ID
   ```

## 步骤 6：清理
<a name="tutorials_06_multi-API-use-step6"></a>

您可以使用 AWS 管理控制台 或 AWS CLI 删除您的 API。

1. 在 CloudFormation 控制台中，选择 API 堆栈，然后选择**删除**。

1. 如果使用的是 AWS CLI，请运行以下命令。

   使用 CloudFormation。

   ```
   $ aws cloudformation delete-stack --stack-name ${API_STACK_NAME}
   ```

# 使用创建集群 Slurm 会计
<a name="tutorials_07_slurm-accounting-v3"></a>

学习如何使用配置和创建集群 Slurm 会计。有关更多信息，请参阅 [Slurm会计 AWS ParallelCluster](slurm-accounting-v3.md)。

使用 AWS ParallelCluster 命令行界面 (CLI) 或 API 时，您只需为创建或更新 AWS ParallelCluster 映像和集群时创建的 AWS 资源付费。有关更多信息，请参阅 [AWS 使用的服务 AWS ParallelCluster](aws-services-v3.md)。

在本教程中，您将使用[CloudFormation 快速创建的模板 (us-east-1) 来创建适用于 MySQL](https://us-east-1.console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/create/review?stackName=pcluster-slurm-db&templateURL=https://us-east-1-aws-parallelcluster.s3.amazonaws.com/templates/1-click/serverless-database.yaml) 的无服务器数据库。[Amazon Aurora](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/CHAP_AuroraOverview.html)该模板指示 CloudFormation 创建所有必要的组件，以便在集群所在的 VPC 上部署 Amazon Aurora 无服务器数据库。该模板还会为集群与数据库之间的连接创建基本的网络和安全配置。

**注意**  
从 3.3.0 版开始，支持 AWS ParallelCluster Slurm 使用集群配置参数 [SlurmSettings](Scheduling-v3.md#Scheduling-v3-SlurmSettings)/[数据库](Scheduling-v3.md#Scheduling-v3-SlurmSettings-Database)进行核算。

**注意**  
快速创建模板用作一个示例。此模板并未涵盖所有可能的用例 Slurm 会计数据库服务器。您负责创建配置和容量适合您的生产工作负载的数据库服务器。

**先决条件：**
+ AWS ParallelCluster [已安装](install-v3-parallelcluster.md)。
+  AWS CLI [已安装并配置。](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ 你有一个 A [mazon EC2 密钥对](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html)。
+ 您拥有具有运行 [`pcluster`](pcluster-v3.md) CLI 所需的[权限](iam-roles-in-parallelcluster-v3.md#iam-roles-in-parallelcluster-v3-example-user-policies)的 IAM 角色。
+ 您在其中部署快速创建模板的区域支持 Amazon Aurora MySQL Serverless v2。有关更多信息，请参阅[适用于 Aurora MySQL 的 Aurora Serverless v2](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/Concepts.Aurora_Fea_Regions_DB-eng.Feature.ServerlessV2.html#Concepts.Aurora_Fea_Regions_DB-eng.Feature.ServerlessV2.amy)。

## 步骤 1：为创建 VPC 和子网 AWS ParallelCluster
<a name="slurm-accounting-vpc-v3"></a>

要将提供的 CloudFormation 模板用于 Slurm 记账数据库，您必须准备好集群的 VPC。您可以手动设置，也可以在[使用 AWS ParallelCluster 命令行界面配置和创建集群](install-v3-configuring.md)的过程中进行设置。如果您已经使用 AWS ParallelCluster，则可能已经具有可用来部署集群和数据库服务器的 VPC。

## 步骤 2：创建数据库堆栈
<a name="slurm-accounting-db-stack-v3"></a>

使用[CloudFormation 快速创建模板 (us-east-1) 为以下对象创建数据库堆栈](https://us-east-1.console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/create/review?stackName=pcluster-slurm-db&templateURL=https://us-east-1-aws-parallelcluster.s3.amazonaws.com/templates/1-click/serverless-database.yaml) Slurm 会计。该模板需要以下输入：
+ 数据库服务器凭证，特别是管理员用户名和密码。
+  Amazon Aurora 无服务器集群的大小。这取决于预期的集群负载。
+ 网络参数，特别是目标 VPC 和子网或用于创建子网的 CIDR 块。

为您的数据库服务器选择适当的凭证和大小。对于网络选项，您必须使用 AWS ParallelCluster 集群部署到的同一个 VPC。您可以为数据库创建子网并将其作为输入传递给模板。或者，为两个子网提供两个不相交的 CIDR 块，然后让 CloudFormation 模板为 CIDR 块创建两个子网。确保 CIDR 块不与现有子网重叠。如果 CIDR 块与现有子网重叠，则无法创建堆栈。

创建数据库服务器需要几分钟时间。

## 步骤 3：使用创建集群 Slurm 已启用记账
<a name="slurm-accounting-create-cluster-v3"></a>

提供的 CloudFormation 模板生成一个包含一些已定义输出的 CloudFormation 堆栈。从中 AWS 管理控制台，您可以在 CloudFormation 堆栈视图的 “输**出**” 选项卡中查看输出。要启用 Slurm 记账，其中一些输出必须在 AWS ParallelCluster 集群配置文件中使用：
+ `DatabaseHost`：用于 [`SlurmSettings`](Scheduling-v3.md#Scheduling-v3-SlurmSettings)/[`Database`](Scheduling-v3.md#Scheduling-v3-SlurmSettings-Database)/[`Uri`](Scheduling-v3.md#yaml-Scheduling-SlurmSettings-Database-Uri) 集群配置参数。
+ `DatabaseAdminUser`：用于 [`SlurmSettings`](Scheduling-v3.md#Scheduling-v3-SlurmSettings)/[`Database`](Scheduling-v3.md#Scheduling-v3-SlurmSettings-Database)/[`UserName`](Scheduling-v3.md#yaml-Scheduling-SlurmSettings-Database-UserName) 集群配置参数值。
+ `DatabaseSecretArn`：用于 [`SlurmSettings`](Scheduling-v3.md#Scheduling-v3-SlurmSettings)/[`Database`](Scheduling-v3.md#Scheduling-v3-SlurmSettings-Database)/[`PasswordSecretArn`](Scheduling-v3.md#yaml-Scheduling-SlurmSettings-Database-PasswordSecretArn) 集群配置参数。
+ `DatabaseClientSecurityGroup`：这是 [`HeadNode`](HeadNode-v3.md)/[`Networking`](HeadNode-v3.md#HeadNode-v3-Networking)/[`SecurityGroups`](HeadNode-v3.md#yaml-HeadNode-Networking-SecurityGroups) 配置参数中定义的附加到集群头节点的安全组。

使用输出值更新您的集群配置文件 `Database` 参数。使用 [`pcluster`](pcluster-v3.md) CLI 创建集群。

```
$ pcluster create-cluster -n cluster-3.x -c path/to/cluster-config.yaml
```

创建集群后，您可以开始使用 Slurm 记账命令，例如`sacctmgr`或`sacct`。

# 使用外部集群创建集群 Slurmdbd 会计
<a name="external-slurmdb-accounting"></a>

学习如何使用外部配置和创建集群 Slurmdbd 会计。有关更多信息，请参阅 [。Slurm 会计 AWS ParallelCluster](slurm-accounting-v3.md)。

使用 AWS ParallelCluster 命令行界面 (CLI) 或 API 时，您只需为创建或更新 AWS ParallelCluster 映像和集群时创建的 AWS 资源付费。有关更多信息，请参阅[使用的AWS 服务 AWS ParallelCluster](aws-services-v3.md)。

 AWS ParallelCluster 用户界面基于无服务器架构构建，你可以在其中使用它 AWS Free Tier 大多数情况下的类别。有关更多信息，请参阅 [AWS ParallelCluster UI 成本](install-pcui-costs-v3.md)。

在本教程中，您将使用 AWS CloudFormation 快速创建模板来创建必要的组件，以便在与集群相同的 VPC 上部署 Slurmdbd 实例。该模板会为集群与数据库之间的连接创建基本的联网和安全配置。

**注意**  
从开始`version 3.10.0`， AWS ParallelCluster 支持带有集群配置参数的外部 Slurmdbd。`SlurmSettings / ExternelSlurmdbd`

**注意**  
快速创建模板用作一个示例。此模板并不涵盖所有可能的使用案例。您负责创建一个外部 Slurmdbd，其配置和容量应适合您的生产工作负载。

**先决条件：**
+ AWS ParallelCluster [已安装](install-v3-parallelcluster.md)。
+  AWS CLI [已安装并配置。](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ 您有一个 [Amazon Elastic Compute Cloud 密钥对](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html)。
+ 您的 AWS Identity and Access Management 角色具有运行 [`pcluster`](pcluster-v3.md) CLI 所需的[权限](iam-roles-in-parallelcluster-v3.md#iam-roles-in-parallelcluster-v3-example-user-policies)。
+ 你有一个 Slurm 会计数据库。逐步完成创建教程 Slurm 会计数据库，请按照[创建 Slurm 会计数据库堆栈中的](tutorials_07_slurm-accounting-v3.md)步骤 1 和步骤 2 进行操作。

## 步骤 1：创建 Slurmdbd 堆栈
<a name="external-slurmdb-accounting-step1"></a>

在本教程中，使用[CloudFormation 快速创建模板 (`us-east-1`)](https://us-east-1.console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/create/review?stackName=pcluster-slurm-dbd&templateURL=https://us-east-1-aws-parallelcluster.s3.amazonaws.com/templates/1-click/external-slurmdbd.json) 创建 Slurmdbd 堆栈。该模板需要以下输入：

**网络连接**
+ **VPCId**：用于启动 Slurmdbd 实例的 VPC ID。
+ **SubnetId**：用于启动 Slurmdbd 实例的子网 ID。
+ **PrivatePrefix**：VPC 的 CIDR 前缀。
+ **PrivateIp**：要分配给 Slurmdbd 实例的辅助私有 IP。

**数据库连接**
+ **DBMSClientSG**：要附加到 Slurmdbd 实例的安全组。该安全组应允许数据库服务器和 Slurmdbd 实例之间的连接。
+ **DBMSDatabase名称**：数据库的名称。
+ **DBMSUsername**：数据库的用户名。
+ **DBMSPasswordSecretArn**：包含数据库密码的密钥。
+ **DBMSUri**：数据库服务器的 URI。

**实例设置**
+ **InstanceType**：用于 slurmdbd 实例的实例类型。
+ **KeyName**：用于 slurmdbd 实例的亚马逊密 EC2 钥对。

**Slurmdbd 设置**
+ **AMIID**：Slurmdbd 实例的 AMI。AMI 应该是 ParallelCluster AMI。 ParallelCluster AMI 的版本决定了 Slurmdbd 的版本。
+ **MungeKeySecretArn**: 包含 munge 密钥的密钥，用于对 Slurmdbd 和集群之间的通信进行身份验证。
+ **SlurmdbdPort**: slurmdbd 使用的端口号。
+ **EnableSlurmdbdSystemService**：启用 slurmdbd 作为系统服务，让它在实例启动时运行。

**警告**  
如果数据库是由不同版本的创建的 SlurmDB，请勿使用 Slurmdbd 作为系统服务。  
如果数据库包含大量条目，则 Slurm Database Daemon (SlurmDBD) 可能需要几十分钟才能更新数据库，并且在此时间间隔内没有响应。  
升级之前 SlurmDB，对数据库进行备份。有关更多信息，请参阅 [。Slurm 文档](https://slurm.schedmd.com/quickstart_admin.html#upgrade)。

## 步骤 2：使用外部集群创建集群 Slurmdbd 已启用
<a name="external-slurmdb-accounting-step2"></a>

提供的 CloudFormation 模板会生成一个包含一些已定义输出的 CloudFormation 堆栈。

从中 AWS 管理控制台，查看 CloudFormation 堆栈中的 “**输出**” 选项卡，查看创建的实体。要启用 Slurm 记账，其中一些输出必须在 AWS ParallelCluster 配置文件中使用：
+ **SlurmdbdPrivateIp**: 用于 [SlurmSettings](Scheduling-v3.md#Scheduling-v3-SlurmSettings)/[ExternalSlurmdbd](Scheduling-v3.md#Scheduling-v3-SlurmSettings-ExternalSlurmdbd)/[主机集群配置参数](Scheduling-v3.md#yaml-Scheduling-SlurmSettings-ExternalSlurmdbd-Host)。
+ **SlurmdbdPort**：用于 [ SlurmSettings](Scheduling-v3.md#Scheduling-v3-SlurmSettings)/[ ExternalSlurmdbd](Scheduling-v3.md#Scheduling-v3-SlurmSettings-ExternalSlurmdbd)/P [ort](Scheduling-v3.md#yaml-Scheduling-SlurmSettings-ExternalSlurmdbd-Port) 集群配置参数值。
+ **AccountingClientSecurityGroup**：这是附加到群集头节点的安全组，在 /Networking [HeadNode](HeadNode-v3.md)/配置参数[中](HeadNode-v3.md#HeadNode-v3-Networking)定义[AdditionalSecurityGroups](HeadNode-v3.md#yaml-HeadNode-Networking-AdditionalSecurityGroups)。

此外，在 CloudFormation 堆栈视图的 “**参数**” 选项卡中：
+ **MungeKeySecretArn**: 用于 [SlurmSettings](Scheduling-v3.md#Scheduling-v3-SlurmSettings)/cl [MungeKeySecretArn](Scheduling-v3.md#yaml-Scheduling-SlurmSettings-MungeKeySecretArn)uster 配置参数值。

使用输出值更新集群配置文件数据库参数。使用 pcluster AWS CLI 创建集群。

```
$  pcluster create-cluster -n cluster-3.x-c path/to/cluster-config.yaml
```

创建集群后，您可以开始使用 Slurm 记账命令，例如`sacctmgr`或`sacct`。

**警告**  
和外部`ParallelCluster`之间的流量 SlurmDB 未加密。建议运行集群和外部集群 SlurmDB 在可信的网络中。





# 恢复到以前的 S AWS ystems Manager 文档版本
<a name="tutorials_08_ssm-document-version-rev-v3"></a>

了解如何恢复到以前的 S AWS ystems Manager 文档版本。有关 SSM 文档的更多信息，请参阅 *AWS Systems Manager 用户指南* 中的 [AWS Systems Manager 文档](https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-ssm-docs.html)。

使用 AWS ParallelCluster 命令行界面 (CLI) 或 API 时，您只需为创建或更新 AWS ParallelCluster 映像和集群时创建的 AWS 资源付费。有关更多信息，请参阅 [AWS 使用的服务 AWS ParallelCluster](aws-services-v3.md)。

**先决条件：**
+  AWS 账户 具有管理 SSM 文档的权限。
+  AWS CLI [已安装并配置。](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)

## 恢复到以前的 SSM 文档版本
<a name="tutorials_08_ssm-document-version-rev-steps"></a>

1. 在您的终端中，运行以下命令以获取您拥有的现有 SSM 文档的列表。

   ```
   $ aws ssm list-documents --document-filter "key=Owner,value=Self"
   ```

1. 将一个 SSM 文档恢复到以前的版本。在此示例中，我们将 `SessionManagerRunShell` 文档恢复到以前版本。您可以使用 SSM `SessionManagerRunShell` 文档自定义您启动的每个 SSM Shell会话。

   1. 通过运行以下命令找到 `SessionManagerRunShell` 的 `DocumentVersion` 参数：

      ```
      $ aws ssm describe-document --name "SSM-SessionManagerRunShell"
      {
          "Document": {
              "Hash": "...",
              "HashType": "Sha256",
              "Name": "SSM-SessionManagerRunShell",
              "Owner": "123456789012",
              "CreatedDate": "2023-02-20T19:04:32.390000+00:00",
              "Status": "Active",
              "DocumentVersion": "1",
              "Parameters": [
                  {
                      "Name": "linuxcmd",
                      "Type": "String",
                      "Description": "The command to run on connection...",
                      "DefaultValue": "if [ -d '/opt/parallelcluster' ]; then source /opt/parallelcluster/cfnconfig; sudo su - $cfn_cluster_user; fi; /bin/bash"
                  }
              ],
              "PlatformTypes": [
                  "Windows",
                  "Linux",
                  "MacOS"
              ],
              "DocumentType": "Session",
              "SchemaVersion": "1.0",
              "LatestVersion": "2",
              "DefaultVersion": "1",
              "DocumentFormat": "JSON",
              "Tags": []
          }
      }
      ```

      最新版本为 `2`。

   1. 通过运行以下命令，恢复到以前的版本：

      ```
      $ aws ssm delete-document --name "SSM-SessionManagerRunShell" --document-version 2
      ```

1. 再次运行 `describe-document` 命令，验证文档版本是否已恢复：

   ```
   $ aws ssm describe-document --name "SSM-SessionManagerRunShell"
   {
       "Document": {
           "Hash": "...",
           "HashType": "Sha256",
           "Name": "SSM-SessionManagerRunShell",
           "Owner": "123456789012",
           "CreatedDate": "2023-02-20T19:04:32.390000+00:00",
           "Status": "Active",
           "DocumentVersion": "1",
           "Parameters": [
               {
                   "Name": "linuxcmd",
                   "Type": "String",
                   "Description": "The command to run on connection...",
                   "DefaultValue": "if [ -d '/opt/parallelcluster' ]; then source /opt/parallelcluster/cfnconfig; sudo su - $cfn_cluster_user; fi; /bin/bash"
               }
           ],
           "PlatformTypes": [
               "Windows",
               "Linux",
               "MacOS"
           ],
           "DocumentType": "Session",
           "SchemaVersion": "1.0",
           "LatestVersion": "1",
           "DefaultVersion": "1",
           "DocumentFormat": "JSON",
           "Tags": []
       }
   }
   ```

   最新版本为 `1`。

# 使用创建集群 CloudFormation
<a name="tutorials_09_cfn-custom-resource-v3"></a>

学习如何使用 AWS ParallelCluster CloudFormation 自定义资源创建集群。有关更多信息，请参阅 [AWS CloudFormation 自定义资源](cloudformation-v3.md)。

使用时 AWS ParallelCluster，您只需为创建或更新 AWS ParallelCluster 映像和集群时创建的 AWS 资源付费。有关更多信息，请参阅 [AWS 使用的服务 AWS ParallelCluster](aws-services-v3.md)。

**先决条件：**
+  AWS CLI [已安装并配置。](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [Amazon EC2 密钥对](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html)。
+ 具有运行 [`pcluster`](pcluster-v3.md) CLI 所需的[权限](iam-roles-in-parallelcluster-v3.md#iam-roles-in-parallelcluster-v3-example-user-policies)的 IAM 角色。

## 使用 CloudFormation 快速创建堆栈创建集群
<a name="cfn-custom-resource-quick-v3"></a>

在本教程中，您将使用快速创建堆栈来部署用于创建集群的 CloudFormation 模板和以下 AWS 资源：
+ 使用 CloudFormation 快速创建 CloudFormation 堆栈创建的根堆栈。
+ 嵌套 CloudFormation 堆栈，包括默认策略、默认 VPC 设置和自定义资源提供程序。
+ 示例 AWS ParallelCluster 集群堆栈和您可以登录并运行作业的集群。

**使用创建集群 AWS CloudFormation**

1. 登录到 AWS 管理控制台。

1. 打开 CloudFormation [快速创建链接](https://us-east-1.console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/create/review?stackName=mycluster&templateURL=https://us-east-1-aws-parallelcluster.s3.amazonaws.com/parallelcluster/3.15.0/templates/1-click/cluster-example.yaml)，在 CloudFormation 控制台中创建以下资源：
   + 带有 VPC 的嵌套 CloudFormation 堆栈，其中包含公有子网和私有子网，分别用于运行集群头节点和计算节点。
   + 带有用于管理群集的 AWS ParallelCluster 自定义资源的嵌套 CloudFormation 堆栈。
   + 带有用于管理集群的默认策略的嵌套 CloudFormation 堆栈。
   + 嵌套 CloudFormation 堆栈的根堆栈。
   + 具有Slurm调度程序和已定义数量的计算节点的 AWS ParallelCluster 集群。  
![\[控制台 CloudFormation 快速创建用户界面。\]](http://docs.aws.amazon.com/zh_cn/parallelcluster/latest/ug/images/cfn-quick-create.png)

1. 在**快速创建堆栈****参数**部分，输入以下参数的值：

   1. 对于 **KeyName**，请输入您的 Amazon EC2 密钥对的名称。

   1. 对于 **AvailabilityZone**，为集群节点选择可用区，例如`us-east-1a`。

1. 在页面底部选中各个框以确认各项访问功能。

1. 选择**创建堆栈**。

1. 等待 CloudFormation 堆栈达到`CREATE_COMPLETE`状态。

## 使用 CloudFormation 命令行界面 (CLI) 创建集群
<a name="cfn-custom-resource-cli-v3"></a>

在本教程中，您将使用用于的 AWS 命令行界面 (CLI) CloudFormation 来部署用于创建集群的 CloudFormation 模板。

**创建以下 AWS 资源：**
+ 使用 CloudFormation 快速创建 CloudFormation 堆栈创建的根堆栈。
+ 嵌套 CloudFormation 堆栈，包括默认策略、默认 VPC 设置和自定义资源提供程序。
+ 示例 AWS ParallelCluster 集群堆栈和您可以登录并运行作业的集群。

用您自己的值替换*inputs highlighted in red*（例如*keypair*）。

**使用创建集群 AWS CloudFormation**

1. 使用以下内容创建`cluster_template.yaml`名为的 CloudFormation 模板：

   ```
   AWSTemplateFormatVersion: '2010-09-09'
   Description: > AWS ParallelCluster CloudFormation Template
   
   Parameters:
     KeyName:
       Description: KeyPair to login to the head node
       Type: AWS::EC2::KeyPair::KeyName
   
     AvailabilityZone:
       Description: Availability zone where instances will be launched
       Type: AWS::EC2::AvailabilityZone::Name
       Default: us-east-2a
   
   Mappings:
     ParallelCluster:
       Constants:
         Version: 3.15.0
   
   Resources:
     PclusterClusterProvider:
       Type: AWS::CloudFormation::Stack
       Properties:
         TemplateURL: !Sub
           - https://${AWS::Region}-aws-parallelcluster.s3.${AWS::Region}.${AWS::URLSuffix}/parallelcluster/${Version}/templates/custom_resource/cluster.yaml
           - { Version: !FindInMap [ParallelCluster, Constants, Version] }
   
     PclusterVpc:
       Type: AWS::CloudFormation::Stack
       Properties:
         Parameters:
           PublicCIDR: 10.0.0.0/24
           PrivateCIDR: 10.0.16.0/20
           AvailabilityZone: !Ref AvailabilityZone
         TemplateURL: !Sub
           - https://${AWS::Region}-aws-parallelcluster.s3.${AWS::Region}.${AWS::URLSuffix}/parallelcluster/${Version}/templates/networking/public-private-${Version}.cfn.json
           - { Version: !FindInMap [ParallelCluster, Constants, Version ] }
   
     PclusterCluster:
       Type: Custom::PclusterCluster
       Properties:
         ServiceToken: !GetAtt [ PclusterClusterProvider , Outputs.ServiceToken ]
         ClusterName: !Sub 'c-${AWS::StackName}'
         ClusterConfiguration:
           Image:
             Os: alinux2
           HeadNode:
             InstanceType: t2.medium
             Networking:
               SubnetId: !GetAtt [ PclusterVpc , Outputs.PublicSubnetId ]
             Ssh:
               KeyName: !Ref KeyName
           Scheduling:
             Scheduler: slurm
             SlurmQueues:
             - Name: queue0
               ComputeResources:
               - Name: queue0-cr0
                 InstanceType: t2.micro
               Networking:
                 SubnetIds:
                 -  !GetAtt [ PclusterVpc , Outputs.PrivateSubnetId ]
   Outputs:
     HeadNodeIp:
       Description: The Public IP address of the HeadNode
       Value: !GetAtt [ PclusterCluster, headNode.publicIpAddress ]
   ```

1. 运行以下 AWS CLI 命令部署 CloudFormation 堆栈以进行集群创建和管理。

   ```
   $ aws cloudformation deploy --template-file ./cluster_template.yaml \
     --stack-name mycluster \
     --parameter-overrides KeyName=keypair \
                           AvailabilityZone=us-east-2b \
     --capabilities CAPABILITY_NAMED_IAM CAPABILITY_AUTO_EXPAND
   ```

## 查看 CloudFormation 集群输出
<a name="cfn-custom-resource-view-v3"></a>

查看集 CloudFormation 群输出以获取有用的集群详细信息。添加的 `ValidationMessages` 属性允许访问集群创建和更新操作中的验证消息。

1. 导航到[CloudFormation 控制台](https://console.aws.amazon.com/cloudformation/home)并选择包含您的 AWS ParallelCluster 自定义资源的堆栈。

1. 选择**堆栈详细信息**，然后选择**输出**选项卡。  
![\[控制台 CloudFormation 输出表显示了 HeadNodeIp 和的值 ValidationMessages。\]](http://docs.aws.amazon.com/zh_cn/parallelcluster/latest/ug/images/cfn-outputs.png)

   验证消息可能会被截断。有关如何检索日志的更多信息，请参阅[AWS ParallelCluster 故障排除](troubleshooting-v3.md)。

## 访问您的集群
<a name="cfn-custom-resource-access-v3"></a>

访问集群。

**`ssh` 登录到集群头节点**

1.  CloudFormation 堆栈部署完成后，使用以下命令获取头节点的 IP 地址：

   ```
   $ HEAD_NODE_IP=$(aws cloudformation describe-stacks --stack-name=mycluster --query "Stacks|[0].Outputs[?OutputKey=='HeadNodeIp']|[0].OutputValue" --output=text)
   ```

   您也可以从 CloudFormation 控制台集群堆栈**输出**选项卡中的**HeadNodeIp**参数中检索头节点 IP 地址。

   您可以在此处找到头节点 IP 地址，因为它是在集群 CloudFormation 模板的`Outputs`部分中添加的，专门针对此示例集群。

1. 通过运行以下命令，连接集群头节点：

   ```
   $ ssh -i keyname.pem ec2-user@$HEAD_NODE_IP
   ```

## 清理
<a name="cfn-custom-resource-cleanup-v3"></a>

请删除集群。

1. 运行以下 AWS CLI 命令删除 CloudFormation 堆栈和集群。

   ```
   $ aws cloudformation delete-stack --stack-name=mycluster
   ```

1. 通过运行以下命令，检查堆栈删除状态。

   ```
   $ aws cloudformation describe-stacks --stack-name=mycluster
   ```

# 使用 Terraform 部署 ParallelCluster API
<a name="tutorial-deploy-terraform"></a>

在本教程中，您将定义一个简单的 Terraform 项目来部署 API。 ParallelCluster 

**先决条件**
+ Terraform v1.5.7\$1 已安装。
+ 具有部署 ParallelCluster API 权限的 IAM 角色。请参阅[所需的权限](tutorial-deploy-terraform-permissions.md)。

# 定义 Terraform 项目
<a name="tutorial-deploy-terraform-define"></a>

在本教程中，您将定义一个 Terraform 项目。

1. 创建名为 `my-pcluster-api` 的目录。

   您创建的所有文件都将位于此目录中。

1. 创建用于配置`provider.tf` AWS 提供程序的文件。

   ```
   provider "aws" {
     region  = var.region
     profile = var.profile
   }
   ```

1. 使用 ParallelCluster模块创建文件`main.tf`以定义资源。

   ```
   module "parallelcluster_pcluster_api" {
     source = "aws-tf/parallelcluster/aws//modules/pcluster_api"
     version = "1.1.0"
   
     region                = var.region
     api_stack_name        = var.api_stack_name
     api_version           = var.api_version
   
     parameters = {
       EnableIamAdminAccess = "true"
     }
   }
   ```

1. 创建 `variables.tf` 文件来定义可以为此项目注入的变量。

   ```
   variable "region" {
     description = "The region the ParallelCluster API is deployed in."
     type        = string
     default     = "us-east-1"
   }
   
   variable "profile" {
     type        = string
     description = "The AWS profile used to deploy the clusters."
     default     = null
   }
   
   variable "api_stack_name" {
     type        = string
     description = "The name of the CloudFormation stack used to deploy the ParallelCluster API."
     default     = "ParallelCluster"
   }
   
   variable "api_version" {
     type        = string
     description = "The version of the ParallelCluster API."
   }
   ```

1. 创建 `terraform.tfvars` 文件来设置变量的任意值。

   下面的文件`us-east-1`使用堆栈名称部署了 ParallelCluster API 3.11.1。`MyParallelClusterAPI-3111`您将能够使用其堆栈名称来引用此 ParallelCluster API 部署。
**注意**  
以下代码中的`api_version`赋值可以替换为任何支持的 AWS ParallelCluster 版本。

   ```
   region = "us-east-1"
   api_stack_name = "MyParallelClusterAPI-3111"
   api_version = "3.11.1"
   ```

1. 创建 `outputs.tf` 文件来定义此项目返回的输出。

   ```
   output "pcluster_api_stack_outputs" {
     value = module.parallelcluster_pcluster_api.stack_outputs
   }
   ```

   项目目录为：

   ```
   my-pcluster-api
   ├── main.tf - Terraform entrypoint to define the resources using the ParallelCluster module.
   ├── outputs.tf - Defines the outputs returned by Terraform.
   ├── providers.tf - Configures the AWS provider.
   ├── terraform.tfvars - Set the arbitrary values for the variables, i.e. region, PCAPI version, PCAPI stack name
   └── variables.tf - Defines the variables, e.g. region, PCAPI version, PCAPI stack name.
   ```

# 部署 API
<a name="tutorial-deploy-terraform-deploy-api"></a>

要部署 API，请按顺序运行标准的 Terraform 命令。

1. 构建项目：

   ```
   terraform init
   ```

1. 定义部署计划：

   ```
   terraform plan -out tfplan
   ```

1. 部署计划：

   ```
   terraform apply tfplan
   ```

# 所需的权限
<a name="tutorial-deploy-terraform-permissions"></a>

你需要以下权限才能使用 Terraform 部署 ParallelCluster API：

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Action": [
                "cloudformation:DescribeStacks",
                "cloudformation:GetTemplate"
            ],
            "Resource": "arn:aws:cloudformation:us-east-1:111122223333:stack/*",
            "Effect": "Allow",
            "Sid": "CloudFormationRead"
        },
        {
            "Action": [
                "cloudformation:CreateStack",
                "cloudformation:DeleteStack",
                "cloudformation:CreateChangeSet"
            ],
            "Resource": "arn:aws:cloudformation:us-east-1:111122223333:stack/MyParallelClusterAPI*",
            "Effect": "Allow",
            "Sid": "CloudFormationWrite"
        },
        {
            "Action": [
                "cloudformation:CreateChangeSet"
            ],
            "Resource": [
                "arn:aws:cloudformation:us-east-1:111122223333:aws:transform/Include",
                "arn:aws:cloudformation:us-east-1:111122223333:aws:transform/Serverless-2016-10-31"
            ],
            "Effect": "Allow",
            "Sid": "CloudFormationTransformWrite"
        },
        {
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:us-east-1:111122223333:*-aws-parallelcluster/parallelcluster/*/api/ParallelCluster.openapi.yaml",
                "arn:aws:s3:us-east-1:111122223333:*-aws-parallelcluster/parallelcluster/*/layers/aws-parallelcluster/lambda-layer.zip"
            ],
            "Effect": "Allow",
            "Sid": "S3ParallelClusterArtifacts"
        },
        {
            "Action": [
                "iam:CreateRole",
                "iam:DeleteRole",
                "iam:GetRole",
                "iam:CreatePolicy",
                "iam:DeletePolicy",
                "iam:GetPolicy",
                "iam:GetRolePolicy",
                "iam:AttachRolePolicy",
                "iam:DetachRolePolicy",
                "iam:PutRolePolicy",
                "iam:DeleteRolePolicy",
                "iam:ListPolicyVersions"
            ],
            "Resource": [
                "arn:aws:iam::111122223333:role/*",
                "arn:aws:iam::111122223333:policy/*"
            ],
            "Effect": "Allow",
            "Sid": "IAM"
        },
        {
            "Action": [
                "iam:PassRole"
            ],
            "Resource": [
                "arn:aws:iam::111122223333:role/ParallelClusterLambdaRole-*",
                "arn:aws:iam::111122223333:role/APIGatewayExecutionRole-*"
            ],
            "Effect": "Allow",
            "Sid": "IAMPassRole"
        },
        {
            "Action": [
                "lambda:CreateFunction",
                "lambda:DeleteFunction",
                "lambda:GetFunction",
                "lambda:PublishLayerVersion",
                "lambda:DeleteLayerVersion",
                "lambda:GetLayerVersion",
                "lambda:TagResource",
                "lambda:UntagResource"
            ],
            "Resource": [
                "arn:aws:lambda:us-east-1:111122223333:layer:PCLayer-*",
                "arn:aws:lambda:us-east-1:111122223333:function:*-ParallelClusterFunction-*"
            ],
            "Effect": "Allow",
            "Sid": "Lambda"
        },
        {
            "Action": [
                "logs:CreateLogGroup",
                "logs:DeleteLogGroup",
                "logs:DescribeLogGroups",
                "logs:PutRetentionPolicy",
                "logs:TagLogGroup",
                "logs:UntagLogGroup"
            ],
            "Resource": [
                "arn:aws:logs:us-east-1:111122223333:log-group:/aws/lambda/*-ParallelClusterFunction-*"
            ],
            "Effect": "Allow",
            "Sid": "Logs"
        },
        {
            "Action": [
                "apigateway:DELETE",
                "apigateway:GET",
                "apigateway:PATCH",
                "apigateway:POST",
                "apigateway:PUT",
                "apigateway:UpdateRestApiPolicy"
            ],
            "Resource": [
                "arn:aws:apigateway:us-east-1::/restapis",
                "arn:aws:apigateway:us-east-1::/restapis/*",
                "arn:aws:apigateway:us-east-1::/tags/*"
            ],
            "Effect": "Allow",
            "Sid": "APIGateway"
        }
    ]
}
```

------

# 使用 Terraform 创建集群
<a name="tutorial-create-cluster-terraform"></a>

使用时 AWS ParallelCluster，您只需为创建或更新 AWS ParallelCluster 映像和集群时创建的 AWS 资源付费。有关更多信息，请参阅 [AWS 使用的服务 AWS ParallelCluster](aws-services-v3.md)。

**先决条件**
+ Terraform v1.5.7\$1 已安装。
+ [AWS ParallelCluster API](api-reference-v3.md) v3.8.0\$1 已部署在您的账户中。请参阅[使用 Terraform 部署 ParallelCluster API](tutorial-deploy-terraform.md)。
+ 具有调用 ParallelCluster API 权限的 IAM 角色。参见 [所需权限］

# 定义 Terraform 项目
<a name="tutorial-create-cluster-terraform-define"></a>

在本教程中，您将定义一个简单的 Terraform 项目来部署集群。

1. 创建名为 `my-clusters` 的目录。

   您创建的所有文件都将位于此目录中。

1. 创建文件`terraform.tf`以导入 ParallelCluster 提供程序。

   ```
   terraform {
     required_version = ">= 1.5.7"
     required_providers {
       aws-parallelcluster = {
         source  = "aws-tf/aws-parallelcluster"
         version = "~> 1.0"
       }
     }
   }
   ```

1. 创建用于配置 ParallelCluster 和 AWS 提供程序的文件`providers.tf`。

   ```
   provider "aws" {
     region  = var.region
     profile = var.profile
   }
   
   provider "aws-parallelcluster" {
     region         = var.region
     profile        = var.profile
     api_stack_name = var.api_stack_name
     use_user_role  = true
   }
   ```

1. 使用 ParallelCluster模块创建文件`main.tf`以定义资源。

   ```
   module "pcluster" {
     source  = "aws-tf/parallelcluster/aws"
     version = "1.1.0"
   
     region                = var.region
     api_stack_name        = var.api_stack_name
     api_version           = var.api_version
     deploy_pcluster_api   = false
   
     template_vars         = local.config_vars
     cluster_configs       = local.cluster_configs
     config_path           = "config/clusters.yaml"
   }
   ```

1. 创建 `clusters.tf` 文件来将多个集群定义为 Terraform 局部变量。
**注意**  
可以在 `cluster_config` 元素中定义多个集群。对于每个集群，您都可以在局部变量中显式定义集群属性（见 `DemoCluster01`）或引用外部文件（见 `DemoCluster02`）。

   要查看可在配置元素中设置的集群属性，请参阅[集群配置文件](cluster-configuration-file-v3.md)。

   要查看创建集群时可设置的选项，请参阅 [`pcluster create-cluster`](pcluster.create-cluster-v3.md)。

   ```
   locals {
     cluster_configs = {
       DemoCluster01 : {
         region : local.config_vars.region
         rollbackOnFailure : false
         validationFailureLevel : "WARNING"
         suppressValidators : [
           "type:KeyPairValidator"
         ]
         configuration : {
           Region : local.config_vars.region
           Image : {
             Os : "alinux2"
           }
           HeadNode : {
             InstanceType : "t3.small"
             Networking : {
               SubnetId : local.config_vars.subnet
             }
             Iam : {
               AdditionalIamPolicies : [
                 { Policy : "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" }
               ]
             }
           }
           Scheduling : {
             Scheduler : "slurm"
             SlurmQueues : [{
               Name : "queue1"
               CapacityType : "ONDEMAND"
               Networking : {
                 SubnetIds : [local.config_vars.subnet]
               }
               Iam : {
                 AdditionalIamPolicies : [
                   { Policy : "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" }
                 ]
               }
               ComputeResources : [{
                 Name : "compute"
                 InstanceType : "t3.small"
                 MinCount : "1"
                 MaxCount : "4"
               }]
             }]
             SlurmSettings : {
               QueueUpdateStrategy : "TERMINATE"
             }
           }
         }
       }
       DemoCluster02 : {
         configuration : "config/cluster_config.yaml"
       }
     }
   }
   ```

1. 创建 `config/clusters.yaml` 文件来将多个集群定义为 YAML 配置。

   ```
   DemoCluster03:
     region: ${region}
     rollbackOnFailure: true
     validationFailureLevel: WARNING
     suppressValidators:
       - type:KeyPairValidator
     configuration: config/cluster_config.yaml
   DemoCluster04:
     region: ${region}
     rollbackOnFailure: false
     configuration: config/cluster_config.yaml
   ```

1. 创建文件`config/cluster_config.yaml`，这是一个标准 ParallelCluster 配置文件，可以在其中注入 Terraform 变量。

   要查看可在配置元素中设置的集群属性，请参阅[集群配置文件](cluster-configuration-file-v3.md)。

   ```
   Region: ${region}
   Image:
    Os: alinux2
   HeadNode:
    InstanceType: t3.small
    Networking:
      SubnetId: ${subnet}
    Iam:
      AdditionalIamPolicies:
        - Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
   Scheduling:
    Scheduler: slurm
    SlurmQueues:
      - Name: queue1
        CapacityType: ONDEMAND
        Networking:
          SubnetIds:
            - ${subnet}
        Iam:
          AdditionalIamPolicies:
            - Policy: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
        ComputeResources:
          - Name: compute
            InstanceType: t3.small
            MinCount: 1
            MaxCount: 5
    SlurmSettings:
      QueueUpdateStrategy: TERMINATE
   ```

1. 创建 `clusters_vars.tf` 文件来定义可以注入到集群配置中的变量。

   此文件使您能够定义可在集群配置中使用的动态值，例如区域和子网。

   此示例直接从项目变量中检索值，但您可能需要使用自定义逻辑来确定它们。

   ```
   locals {
     config_vars = {
       subnet = var.subnet_id
       region = var.cluster_region
     }
   }
   ```

1. 创建 `variables.tf` 文件来定义可以为此项目注入的变量。

   ```
   variable "region" {
     description = "The region the ParallelCluster API is deployed in."
     type        = string
     default     = "us-east-1"
   }
   
   variable "cluster_region" {
     description = "The region the clusters will be deployed in."
     type        = string
     default     = "us-east-1"
   }
   
   variable "profile" {
     type        = string
     description = "The AWS profile used to deploy the clusters."
     default     = null
   }
   
   variable "subnet_id" {
     type        = string
     description = "The id of the subnet to be used for the ParallelCluster instances."
   }
   
   variable "api_stack_name" {
     type        = string
     description = "The name of the CloudFormation stack used to deploy the ParallelCluster API."
     default     = "ParallelCluster"
   }
   
   variable "api_version" {
     type        = string
     description = "The version of the ParallelCluster API."
   }
   ```

1. 创建 `terraform.tfvars` 文件来设置变量的任意值。

   以下文件使用现有 ParallelCluster API 3.11.1 在子网`eu-west-1`中部署集群`subnet-123456789`，该API 3.11.1 已使用堆栈名称部署在子网中`us-east-1`。`MyParallelClusterAPI-3111`

   ```
   region = "us-east-1"
   api_stack_name = "MyParallelClusterAPI-3111"
   api_version = "3.11.1"
   
   cluster_region = "eu-west-1"
   subnet_id = "subnet-123456789"
   ```

1. 创建 `outputs.tf` 文件来定义此项目返回的输出。

   ```
   output "clusters" {
     value = module.pcluster.clusters
   }
   ```

   项目目录为：

   ```
   my-clusters
   ├── config
   │   ├── cluster_config.yaml - Cluster configuration, where terraform variables can be injected..
   │   └── clusters.yaml - File listing all the clusters to deploy.
   ├── clusters.tf - Clusters defined as Terraform local variables.
   ├── clusters_vars.tf - Variables that can be injected into cluster configurations.
   ├── main.tf - Terraform entrypoint where the ParallelCluster module is configured.
   ├── outputs.tf - Defines the cluster as a Terraform output.
   ├── providers.tf - Configures the providers: ParallelCluster and AWS.
   ├── terraform.tf - Import the ParallelCluster provider.
   ├── terraform.tfvars - Defines values for variables, e.g. region, PCAPI stack name.
   └── variables.tf - Defines the variables, e.g. region, PCAPI stack name.
   ```

# 部署集群
<a name="tutorial-create-cluster-terraform-deploy"></a>

要部署集群，请按顺序运行标准的 Terraform 命令。

**注意**  
此示例假设您已经在账户中部署了 ParallelCluster API。

1. 构建项目：

   ```
   terraform init
   ```

1. 定义部署计划：

   ```
   terraform plan -out tfplan
   ```

1. 部署计划：

   ```
   terraform apply tfplan
   ```

## 使用集群部署 ParallelCluster API
<a name="tutorial-create-cluster-terraform-deploy-api"></a>

如果您尚未部署 ParallelCluster API，但想将其与集群一起部署，请更改以下文件：
+ `main.tf`

  ```
  module "pcluster" {
    source  = "aws-tf/aws/parallelcluster"
    version = "1.0.0"
  
    region                = var.region
    api_stack_name        = var.api_stack_name
    api_version           = var.api_version
    deploy_pcluster_api   = true
    parameters = {
      EnableIamAdminAccess = "true"
    }
    
    template_vars         = local.config_vars
    cluster_configs       = local.cluster_configs
    config_path           = "config/clusters.yaml"
  }
  ```
+ `providers.tf`

  ```
  provider "aws-parallelcluster" {
    region   = var.region
    profile  = var.profile
    endpoint = module.pcluster.pcluster_api_stack_outputs.ParallelClusterApiInvokeUrl
    role_arn = module.pcluster.pcluster_api_stack_outputs.ParallelClusterApiUserRole
  }
  ```

# 所需的权限
<a name="tutorial-create-cluster-terraform-permissions"></a>

使用 Terraform 部署集群需要以下权限：
+ 担任 ParallelCluster API 角色，该角色负责与 ParallelCluster API 交互
+ 描述 ParallelCluster API 的 CloudFormation 堆栈以验证其存在并检索其参数和输出

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:sts::111122223333:role/PCAPIUserRole-*",
            "Effect": "Allow",
            "Sid": "AssumePCAPIUserRole"
        },
        {
            "Action": [
                "cloudformation:DescribeStacks"
            ],
            "Resource": "arn:aws:cloudformation:us-east-1:111122223333:stack/*",
            "Effect": "Allow",
            "Sid": "CloudFormation"
        }
    ]
}
```

------

# 使用 Terraform 创建自定义 AMI
<a name="tutorial-create-ami-terraform"></a>

使用时 AWS ParallelCluster，您只需为创建或更新 AWS ParallelCluster 映像和集群时创建的 AWS 资源付费。有关更多信息，请参阅 [AWS 使用的服务 AWS ParallelCluster](aws-services-v3.md)。

**先决条件**
+  Terraform v1.5.7\$1 已安装。
+ [AWS ParallelCluster API](api-reference-v3.md) v3.8.0\$1 已部署在您的账户中。请参阅[使用 Terraform 创建集群](tutorial-create-cluster-terraform.md)。
+ 具有调用 ParallelCluster API 权限的 IAM 角色。请参阅[所需的权限](tutorial-create-ami-terraform-permissions.md)。

# 定义 Terraform 项目
<a name="tutorial-create-ami-terraform-define"></a>

在本教程中，您将定义一个简单的 Terraform 项目来部署自定义 ParallelCluster AMI。

1. 创建名为 `my-amis` 的目录。

   您创建的所有文件都将位于此目录中。

1. 创建文件`terraform.tf`以导入 ParallelCluster 提供程序。

   ```
   terraform {
     required_version = ">= 1.5.7"
     required_providers {
       aws-parallelcluster = {
         source  = "aws-tf/aws-parallelcluster"
         version = "~> 1.0"
       }
     }
   }
   ```

1. 创建用于配置 ParallelCluster 和 AWS 提供程序的文件`providers.tf`。

   ```
   provider "aws" {
     region  = var.region
     profile = var.profile
   }
   
   provider "aws-parallelcluster" {
     region         = var.region
     profile        = var.profile
     api_stack_name = var.api_stack_name
     use_user_role  = true
   }
   ```

1. 使用 ParallelCluster模块创建文件`main.tf`以定义资源。

   要查看可在 `image_configuration` 元素中设置的映像属性，请参阅[构建映像配置文件](image-builder-configuration-file-v3.md)。

   要查看创建映像时可设置的选项（如 `image_id` 和 `rollback_on_failure`），请参阅 [`pcluster build-image`](pcluster.build-image-v3.md)。

   ```
   data "aws-parallelcluster_list_official_images" "parent_image" {
     region = var.region
     os = var.os
     architecture = var.architecture
   }
   
   resource "aws-parallelcluster_image" "demo01" {
     image_id            = "demo01"
     image_configuration = yamlencode({
       "Build":{
         "InstanceType": "c5.2xlarge",
         "ParentImage": data.aws-parallelcluster_list_official_images.parent_image.official_images[0].amiId,
         "UpdateOsPackages": {"Enabled": false}
       }
     })
     rollback_on_failure = false
   }
   ```

1. 创建 `variables.tf` 文件来定义可以为此项目注入的变量。

   ```
   variable "region" {
     description = "The region the ParallelCluster API is deployed in."
     type        = string
     default     = "us-east-1"
   }
   
   variable "profile" {
     type        = string
     description = "The AWS profile used to deploy the clusters."
     default     = null
   }
   
   variable "api_stack_name" {
     type        = string
     description = "The name of the CloudFormation stack used to deploy the ParallelCluster API."
     default     = "ParallelCluster"
   }
   
   variable "api_version" {
     type        = string
     description = "The version of the ParallelCluster API."
   }
   
   variable "os" {
     type        = string
     description = "The OS of the ParallelCluster image."
   }
   
   variable "architecture" {
     type        = string
     description = "The architecture of the ParallelCluster image."
   }
   ```

1. 创建文件`terraform.tfvars`以设置变量的任意值。

   在下面的文件中，使用已经使用堆栈名称部署的现有 ParallelCluster API 3.11.1，`us-east-1`基于适用于 x86\$164 架构的 Amazon Linux 2 部署自定义 AMI。`us-east-1` `MyParallelClusterAPI-3111`

   ```
   region = "us-east-1"
   api_stack_name = "MyParallelClusterAPI-3111"
   api_version = "3.11.1"
   
   os = "alinux2"
   architecture = "x86_64"
   ```

1. 创建 `outputs.tf` 文件来定义此项目返回的输出。

   ```
   output "parent_image" {
     value = data.aws-parallelcluster_list_official_images.parent_image.official_images[0]
   }
   
   output "custom_image" {
     value = aws-parallelcluster_image.demo01
   }
   ```

   项目目录为：

   ```
   my-amis
   ├── main.tf - Terraform entrypoint where the ParallelCluster module is configured.
   ├── outputs.tf - Defines the cluster as a Terraform output.
   ├── providers.tf - Configures the providers: ParallelCluster and AWS.
   ├── terraform.tf - Import the ParallelCluster provider.
   ├── terraform.tfvars - Defines values for variables, e.g. region, PCAPI stack name.
   └── variables.tf - Defines the variables, e.g. region, PCAPI stack name.
   ```

# 部署 AMI
<a name="tutorial-create-ami-terraform-deploy"></a>

要部署 AMI，请按顺序运行标准的 Terraform 命令。

1. 构建项目：

   ```
   terraform init
   ```

1. 定义部署计划：

   ```
   terraform plan -out tfplan
   ```

1. 部署计划：

   ```
   terraform apply tfplan
   ```

# 所需的权限
<a name="tutorial-create-ami-terraform-permissions"></a>

使用 Terraform 部署自定义 AMI 需要以下权限：
+ 担任 ParallelCluster API 角色，该角色负责与 ParallelCluster API 交互
+ 描述 ParallelCluster API 的 CloudFormation 堆栈，以验证其存在并检索其参数和输出

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:sts::111122223333:role/PCAPIUserRole-*",
            "Effect": "Allow",
            "Sid": "AssumePCAPIUserRole"
        },
        {
            "Action": [
                "cloudformation:DescribeStacks"
            ],
            "Resource": "arn:aws:cloudformation:us-east-1:111122223333:stack/*",
            "Effect": "Allow",
            "Sid": "CloudFormation"
        }
    ]
}
```

------

# AWS ParallelCluster 用户界面与身份中心集成
<a name="tutorials_10_pcui-aws-ic-integration-v3"></a>

本教程的目标是演示如何将用户 AWS ParallelCluster 界面与 IAM Identity Center 集成，以实现单点登录解决方案，该解决方案可统一可与 AWS ParallelCluster 集群共享的 Active Directory 中的用户。

使用时 AWS ParallelCluster，您只需为创建或更新 AWS ParallelCluster 映像和集群时创建的 AWS 资源付费。有关更多信息，请参阅 [AWS 使用的服务 AWS ParallelCluster](aws-services-v3.md)。

**先决条件：**
+ 现有的 AWS ParallelCluster UI，可按照[此处](install-pcui-v3.md)的说明进行安装。
+ 现有的托管 Active Directory，最好是同时用于[与之集成的](tutorials_05_multi-user-ad.md)目录 AWS ParallelCluster。

## 启用 IAM Identity Center
<a name="enable-iam-identity-center-v3"></a>

如果您已经将身份中心连接到您的 AWS Managed Microsoft AD （Active Directory），则可以使用该身份中心，并且可以跳至**将您的应用程序添加到 IAM 身份中心**部分。

如果您尚未将身份中心连接到 AWS Managed Microsoft AD，请按照以下步骤进行设置。

**启用 Identity Center**

1. 在控制台中，导航至 IAM Identity Center。（请确保您位于您所在的地区 AWS Managed Microsoft AD。）

1. 单击**启用**按钮，此时系统可能会询问您是否要启用组织，这是一项要求，因此您可以选择启用。**注**：这将给您的账户管理员发送一封确认电子邮件，您应点击链接进行确认。

**将 Identity Center 连接到 Managed AD**

1. 在启用 Identity Center 后的下一页，您会看到“建议设置步骤”，在步骤 1 下，选择**选择您的身份源**。

1. 在“身份源”部分，单击**操作**下拉菜单（右上角），然后选择**更改身份源**。

1. 选择 **Active Directory**。

1. 在**现有目录**下，选择您的目录。

1. 单击下一步。

1. 查看您的更改，滚动到底部，在文本框中键入 ACCEPT 进行确认，然后单击**更改身份源**。

1. 等待更改完成，然后您应该会在顶部看到一个绿色横幅。

**将用户和组同步到 Identity Center**

1. 在绿色横幅中，单击**开始引导式设置**（右上角的按钮）  
![\[屏幕截图突出显示“开始引导式设置”按钮。\]](http://docs.aws.amazon.com/zh_cn/parallelcluster/latest/ug/images/tutorials/pcui_awsic_integration/IAC_start_guided_setup_1.png)

1. 在**配置属性映射**中，单击**下一步**

1. 在“配置同步范围”部分，键入要同步到 Identity Center 的用户的名称，然后单击**添加**

1. 添加完用户和组后，单击**下一步**  
![\[屏幕截图突出显示“下一步”按钮。\]](http://docs.aws.amazon.com/zh_cn/parallelcluster/latest/ug/images/tutorials/pcui_awsic_integration/IAC_guided_setup_add_users_groups_2.png)

1. 查看您的更改，然后单击**保存配置**

1. 如果您在下一个屏幕中看到有关用户未同步的警告，请选择右上角的**恢复同步**按钮。

1. 接下来，要启用用户，请在左侧的**用户**选项卡中，选择一个用户，然后单击**启用用户访问** > **启用用户访问** 

   **注**：如果顶部出现警告横幅，则可能需要选择“恢复同步”，然后等待用户进行同步（尝试使用刷新按钮查看用户是否已同步）。  
![\[屏幕截图突出显示“用户”选项卡。\]](http://docs.aws.amazon.com/zh_cn/parallelcluster/latest/ug/images/tutorials/pcui_awsic_integration/IAC_enable_user_access_3.png)

## 将应用程序添加到 IAM Identity Center
<a name="adding-apps-to-iam-identity-center-v3"></a>

将用户与 IAM Identity Center 同步后，您需要添加新的应用程序。这将配置可从 IAM Identity Center 门户使用哪些启用了 SSO 的应用程序。在本例中，我们将添加 AWS ParallelCluster UI 作为应用程序，而 IAM Identity Center 将作为身份提供者。

下一步将 AWS ParallelCluster 用户界面作为应用程序添加到 IAM 身份中心。 AWS ParallelCluster UI 是一个 Web 门户，可帮助用户管理其集群。有关更多信息，请参阅 [AWS ParallelCluster UI](pcui-using-v3.md)。

**在 Identity Center 中设置应用程序**

1. 在 **IAM Identity Center** > **应用程序**下（位于左侧菜单栏上，单击“应用程序”）

1. 单击**添加应用程序**

1. 选择**添加自定义 SAML 2.0 应用程序**

1. 单击**下一步**

1. 选择您要使用的显示名称和描述（例如 PC AWS ParallelCluster UI 和 UI）

1. 在 **IAM Identity Center 元数据**下，复制 IAM Identity Center SAML 元数据文件的链接并保存备用，这将在 Web 应用程序上配置 SSO 时使用

1. 在**应用程序属性**下的“应用程序启动 URL”中，输入您的 PCUI 地址。**这可以通过进入 CloudFormation 控制台，选择与 PCUI 对应的堆栈（例如 parallelcluster-ui），然后转到 “输出” 选项卡进行查找** ParallelCluster UIUrl

   例如 https://m2iwazsi1j.execute-api.us-east-1.amazonaws.com

1. 在**应用程序元数据**下，选择**手动键入您的元数据值**。然后提供以下值。

   1. **重要提示**：请确保将域前缀、区域和用户池 ID 值替换为与您的环境相关的信息。

   1. 打开 **Amazon Cognito** > **用户池**控制台，即可获取域前缀、区域和用户池 ID  
![\[在 Cognito 用户池下突出显示用户池名称的屏幕截图\]](http://docs.aws.amazon.com/zh_cn/parallelcluster/latest/ug/images/tutorials/pcui_awsic_integration/Amazon_cognito_user_pools_4.png)

   1. 选择与 PCUI 对应的用户池（其用户池名称将像 pcui-cd8a2-cognito-153 s98-UserP EK3 TO45 ool）

   1. 导航到**应用程序集成**  
![\[在 “应用程序集成” 选项卡中突出显示 Cognito 域名的屏幕截图\]](http://docs.aws.amazon.com/zh_cn/parallelcluster/latest/ug/images/tutorials/pcui_awsic_integration/Amazon_cognito_app_integration_5.png)

1. 应用程序断言消费者服务 (ACS) 网址：https://<domain-prefix>.auth。 <region>.amazoncognito。 com/saml2/idpresponse

   应用程序 SAML 受众：urn:amazon:cognito:sp:<userpool-id>

1. 选择**提交**。然后，转到您添加的应用程序的**详细信息**页面。

1. 选择**操作**下拉列表并选择**编辑属性映射**。然后，提供以下属性。

   1. 应用程序中的用户属性：**subject**（注：**subject** 已预填写。） → 映射到 IAM Identity Center 中的这个字符串值或用户属性：**\$1\$1user:email\$1**，格式：**emailAddress**

   1. 应用程序中的用户属性：**email** → 映射到 IAM Identity Center 中的这个字符串值或用户属性：**\$1\$1user:email\$1**，格式：**unspecified**  
![\[屏幕快照突出显示 PCUI 的属性映射部分\]](http://docs.aws.amazon.com/zh_cn/parallelcluster/latest/ug/images/tutorials/pcui_awsic_integration/IAC_attribute_mappings_PCUI_6.png)

1. 保存更改。

1. 选择**分配用户**按钮，然后将您的用户分配给应用程序。这些是您的 Active Directory 中有权访问 PCUI 界面的用户。  
![\[屏幕截图突出显示为应用程序分配用户。\]](http://docs.aws.amazon.com/zh_cn/parallelcluster/latest/ug/images/tutorials/pcui_awsic_integration/IAC_PCUI_App_7.png)

**将 IAM Identity Center 配置为用户池中的 SAML IdP**

1. 在您的用户池设置中，选择**登录体验** > **添加身份提供者**  
![\[屏幕截图突出显示登录体验选项卡\]](http://docs.aws.amazon.com/zh_cn/parallelcluster/latest/ug/images/tutorials/pcui_awsic_integration/Amazon_cognito_sign_in_expereince_8.png)

1. 选择一个 SAML IdP

1. 如需**提供商名称，请**提供 **IdentityCenter**

1. 在**元数据文档源**下，选择**输入元数据文档端点 URL**，然后提供在 Identity Center 的应用程序设置期间复制的 URL

1. 在**属性**下，如果是电子邮件，则选择 email  
![\[屏幕截图突出显示登录体验选项卡\]](http://docs.aws.amazon.com/zh_cn/parallelcluster/latest/ug/images/tutorials/pcui_awsic_integration/Amazonw_cognito_SAML_9.png)

1. 选择**添加身份提供者**。

**将 IdP 与用户池应用程序客户端集成**

1. 接下来，在用户池的**应用程序集成**部分下，选择**应用程序客户端列表**下列出的客户端  
![\[屏幕截图突出显示登录体验选项卡\]](http://docs.aws.amazon.com/zh_cn/parallelcluster/latest/ug/images/tutorials/pcui_awsic_integration/Amazon_cognito_user_pool_app_client_10.png)

1. 在**托管 UI** 下，选择**编辑**

1. 在 “**身份提供者**” 下**IdentityCenter**也选择。

1. 选择**保存更改**

**验证您的设置**

1. 接下来，我们将通过登录 PCUI 来验证刚刚创建的设置。登录 PCUI 门户，您现在应该可以看到使用企业 ID 登录的选项：  
![\[屏幕截图突出显示登录体验选项卡\]](http://docs.aws.amazon.com/zh_cn/parallelcluster/latest/ug/images/tutorials/pcui_awsic_integration/Amazon_cognito_validate_step_11.png)

1. 单击该**IdentityCenter**按钮将带您进入 IAM Identity Center IdP 登录页面，然后打开一个包含您的应用程序（包括 PCUI）的页面，然后打开该应用程序。

1. 进入以下屏幕后，可看到您的用户应该已经添加到 Cognito 用户池中。  
![\[屏幕截图突出显示登录体验选项卡\]](http://docs.aws.amazon.com/zh_cn/parallelcluster/latest/ug/images/tutorials/pcui_awsic_integration/Amazon_cognito_continue_with_IC_12.png)

**将用户设为管理员**

1. 现在导航到 **Amazon Cognito** > **用户池**控制台，选择新创建的用户，其前缀应为 identitycenter  
![\[屏幕截图突出显示登录体验选项卡\]](http://docs.aws.amazon.com/zh_cn/parallelcluster/latest/ug/images/tutorials/pcui_awsic_integration/Amazon_cognito_user_pools_new_created_user_13.png)

1. 在**组成员资格**下，选择**将用户添加到组**，选择**管理员**，然后单击**添加**。

1. 现在，当您单击 “**继续**” 时， IdentityCenter您将被导航到 AWS ParallelCluster 用户界面页面。

# 使用 Pyxis 运行容器化作业
<a name="tutorials_11_running-containerized-jobs-with-pyxis"></a>

了解如何创建一个能够使用 Pyxis 运行容器化作业的集群，Pyxis 是一个 SPANK 插件，用于在 SLURM 中管理容器化作业。Pyxis 中的容器由 Enroot 管理，Enroot 是将传统 container/OS 图像转换为非特权沙箱的工具。有关更多信息，请参阅 [NVIDIA Pyxis](https://github.com/NVIDIA/pyxis) 和 [NVIDIA Enroot](https://github.com/NVIDIA/enroot)。

**注意**  
此功能在 AWS ParallelCluster v3.11.1 中可用
本教程中的脚本移动 (`mv`) 一些文件，这会将它们从其原始位置删除。如果要将这些文件的副本保存在其原始位置，请更改脚本以改用 copy (`cp`) 命令。

使用时 AWS ParallelCluster，您只需为创建或更新 AWS ParallelCluster 映像和集群时创建的 AWS 资源付费。有关更多信息，请参阅 [AWS 使用的服务 AWS ParallelCluster](aws-services-v3.md)。

**先决条件：**
+  AWS CLI 已[安装并配置。](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [Amazon EC2 密钥对](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html)。
+ 具有运行 [pcluster CLI](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html) 所需的[权限](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html)的 IAM 角色。

## 创建集群
<a name="create-the-cluster"></a>

从 AWS ParallelCluster 3.11.1 开始，所有官方版本都预 AMIs 装了 Pyxis 和 Enroot。特别是，SLURM 在 Pyxis 支持下重新编译，Enroot 作为二进制文件安装到系统中。不过，您必须根据自己的具体需求进行配置。Enroot 和 Pyxis 使用的文件夹对集群性能有重要影响。有关更多信息，请参阅 [Pyxis documentation](https://github.com/NVIDIA/pyxis/wiki/Setup#slurm-plugstack-configuration) 和 [Enroot documentation](https://github.com/NVIDIA/pyxis/wiki/Setup#enroot-configuration-example)。

为方便起见，您可在 `/opt/parallelcluster/examples/` 中找到 Pyxis、Enroot 和 SPANK 的配置示例。

要使用我们提供的示例配置部署集群，请完成以下教程。

**使用示例配置创建集群**

必须在头节点上配置 Pyxis 和 Enroot，方法是先为 Enroot 创建持久和易失性目录，然后为 Pyxis 创建运行时目录，最后将 Pyxis 作为 SPANK 插件在整个集群中启用。

1. 在头节点中执行以下脚本作为[OnNodeConfigured](HeadNode-v3.md#yaml-HeadNode-CustomActions-OnNodeConfigured)自定义操作，在头节点上配置 Pyxis 和 Enroot。

   ```
   #!/bin/bash
   set -e
   
   echo "Executing $0"
   
   # Configure Enroot
   ENROOT_PERSISTENT_DIR="/var/enroot"
   ENROOT_VOLATILE_DIR="/run/enroot"
   
   sudo mkdir -p $ENROOT_PERSISTENT_DIR
   sudo chmod 1777 $ENROOT_PERSISTENT_DIR
   sudo mkdir -p $ENROOT_VOLATILE_DIR
   sudo chmod 1777 $ENROOT_VOLATILE_DIR
   sudo mv /opt/parallelcluster/examples/enroot/enroot.conf /etc/enroot/enroot.conf
   sudo chmod 0644 /etc/enroot/enroot.conf
   
   # Configure Pyxis
   PYXIS_RUNTIME_DIR="/run/pyxis"
   
   sudo mkdir -p $PYXIS_RUNTIME_DIR
   sudo chmod 1777 $PYXIS_RUNTIME_DIR
   
   sudo mkdir -p /opt/slurm/etc/plugstack.conf.d/
   sudo mv /opt/parallelcluster/examples/spank/plugstack.conf /opt/slurm/etc/
   sudo mv /opt/parallelcluster/examples/pyxis/pyxis.conf /opt/slurm/etc/plugstack.conf.d/
   sudo -i scontrol reconfigure
   ```

1. 必须在计算实例集上配置 Pyxis 和 Enroot，方法是为 Enroot 创建持久和易失性目录，为 Pyxis 创建运行时目录。在计算节点中将以下脚本作为[OnNodeStart](Scheduling-v3.md#yaml-Scheduling-SlurmQueues-CustomActions-OnNodeStart)自定义操作执行，以便在计算队列上配置 Pyxis 和 Enroot。

   ```
   #!/bin/bash
   set -e
   
   echo "Executing $0"
   
   # Configure Enroot
   ENROOT_PERSISTENT_DIR="/var/enroot"
   ENROOT_VOLATILE_DIR="/run/enroot"
   ENROOT_CONF_DIR="/etc/enroot"
   
   sudo mkdir -p $ENROOT_PERSISTENT_DIR
   sudo chmod 1777 $ENROOT_PERSISTENT_DIR
   sudo mkdir -p $ENROOT_VOLATILE_DIR
   sudo chmod 1777 $ENROOT_VOLATILE_DIR
   sudo mkdir -p $ENROOT_CONF_DIR
   sudo chmod 1777 $ENROOT_CONF_DIR
   sudo mv /opt/parallelcluster/examples/enroot/enroot.conf /etc/enroot/enroot.conf
   sudo chmod 0644 /etc/enroot/enroot.conf
   
   # Configure Pyxis
   PYXIS_RUNTIME_DIR="/run/pyxis"
   
   sudo mkdir -p $PYXIS_RUNTIME_DIR
   sudo chmod 1777 $PYXIS_RUNTIME_DIR 
   
   # In Ubuntu24.04 Apparmor blocks the creation of unprivileged user namespaces,
   # which is required by Enroot. So to run Enroot, it is required to disable this restriction.
   # See https://ubuntu.com/blog/ubuntu-23-10-restricted-unprivileged-user-namespaces
   source /etc/os-release
   if [ "${ID}${VERSION_ID}" == "ubuntu24.04" ]; then
       echo "kernel.apparmor_restrict_unprivileged_userns = 0" | sudo tee /etc/sysctl.d/99-pcluster-disable-apparmor-restrict-unprivileged-userns.conf
       sudo sysctl --system
   fi
   ```

## 提交作业
<a name="submit-jobs"></a>

现在，Pyxis 已配置到集群中，您可以使用 sbatch 和 srun 命令提交容器化作业了，这些命令现在增加了特定于容器的选项。

```
# Submitting an interactive job
srun -N 2 --container-image docker://ubuntu:22.04 hostname

# Submitting a batch job
sbatch -N 2 --wrap='srun --container-image docker://ubuntu:22.04 hostname'
```

# 创建具有启用 EFA 的 Lustre FSx 的集群
<a name="tutorial-efa-enabled-fsx-lustre"></a>

在本教程中，您将创建一个使用支持 EFA 的 FSx Lustre 文件系统作为共享存储的集群。使用启用 EFA 的 FSx Lustre 文件系统可以将性能提高多达 8 倍。*要验证是否需要启用 EFA 的文件系统，请查看 for Lustre 用户指南中的[使用启用 EFA 的文件系统](https://docs.aws.amazon.com/fsx/latest/LustreGuide/efa-file-systems.html)。FSx *

使用时 AWS ParallelCluster，您只需为创建或更新 AWS ParallelCluster 映像和集群时创建的 AWS 资源付费。有关更多信息，请参阅 [AWS 使用的服务 AWS ParallelCluster](aws-services-v3.md)。

## 要求
<a name="tutorial-efa-enabled-fsx-lustre-requirements"></a>
+ C AWS LI 已[安装并配置](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)完毕。
+ C ParallelCluster LI 已[安装并配置](install-v3-parallelcluster.md)完毕。
+ 用于登录集群[的 Amazon EC2 密钥对](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html)。
+ 具有运行 ParallelCluster CLI 所需[权限](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html)的 IAM 角色。

## 创建安全组
<a name="tutorial-efa-enabled-fsx-lustre-security-groups"></a>

在部署集群和文件系统的同一 VPC 中创建两个安全组：一个用于在群集节点上运行的客户端，另一个用于文件系统。

```
# Create security group for the FSx client
aws ec2 create-security-group \
    --group-name Fsx-Client-SecurityGroup \
    --description "Allow traffic for the FSx Lustre client" \
    --vpc-id vpc-cluster \
    --region region

# Create security group for the FSx file system
aws ec2 create-security-group \
    --group-name Fsx-FileSystem-SecurityGroup \
    --description "Allow traffic for the FSx Lustre File System" \
    --vpc-id vpc-cluster \
    --region region
```

在本教程的其余部分中，我们将假设`sg-client`和分别`sg-file-system`是客户端和文件系统的安全组 ID。

按照 EFA 的[要求，为客户端配置安全组以允许所有出站流量进入文件系统](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa-start.html#efa-start-security)。

```
# Allow all outbound traffic from the client to the file system
aws ec2 authorize-security-group-egress \
 --group-id sg-client \ 
 --protocol -1 \
 --port -1 \
 --source-group sg-file-system \
 --region region
```

按照 EFA 的[要求，为文件系统配置安全组，使其允许其内部的所有流量以及来自客户端的所有入站流量](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa-start.html#efa-start-security)。 inbound/outbound 

```
# Allow all inbound traffic within this security group
aws ec2 authorize-security-group-ingress \
    --group-id sg-file-system \
    --protocol -1 \
    --port -1 \
    --source-group sg-file-system \
    --region region

# Allow all outbound traffic within this security group
aws ec2 authorize-security-group-egress \
    --group-id sg-file-system \
    --protocol -1 \
    --port -1 \
    --source-group sg-file-system \
    --region region

# Allow all inbound traffic from the client
aws ec2 authorize-security-group-ingress \
    --group-id sg-file-system \
    --protocol -1 \
    --port -1 \
    --source-group sg-client \
    --region region

# Allow all outbound traffic to the client
aws ec2 authorize-security-group-egress \
    --group-id sg-file-system \
    --protocol -1 \
    --port -1 \
    --source-group sg-client \
    --region region
```

## 创建文件系统
<a name="tutorial-efa-enabled-fsx-lustre-create-filesystem"></a>

在计算节点所在的可用区 (AZ) 中创建文件系统；并在以下代码中`subnet-compute-nodes`替换为其 ID。这是允许 EFA 与您的文件系统配合使用所必需的。请注意，作为创建文件系统的一部分，我们使用 EfaEnable 属性启用 EFA。

```
aws fsx create-file-system \
    --file-system-type LUSTRE \
    --storage-capacity 38400 \
    --storage-type SSD \
    --subnet-ids subnet-compute-nodes \
    --security-group-ids sg-file-system \
    --lustre-configuration DeploymentType=PERSISTENT_2,PerUnitStorageThroughput=125,EfaEnabled=true,MetadataConfiguration={Mode=AUTOMATIC} \
    --region region
```

记下上一个命令返回的文件系统 ID。在本教程的其余部分中，`fs-id`用此文件系统 ID 替换。

## 创建集群
<a name="tutorial-efa-enabled-fsx-lustre-create-cluster"></a>

1. 使用 AWS ParallelCluster YAML 配置文件中设置的以下配置创建集群：

   1. AMI 基于支持的操作系统，例如 Ubuntu 22.04。

   1. 计算节点必须使用[支持 EFA 且具有 [Nitro v4\$1](https://docs.aws.amazon.com/ec2/latest/instancetypes/ec2-nitro-instances.html) 的实例类型](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa.html#efa-instance-types)，例如 g6.16xlarge。
      + 计算节点必须位于文件系统所在的同一个可用区中。
      + 计算节点必须将 [Efa/Enabled](Scheduling-v3.md#yaml-Scheduling-SlurmQueues-ComputeResources-Efa-Enabled) 设置为 true。
      + 计算节点必须将配置脚本`configure-efa-fsx-lustre-client.sh`作为[OnNodeStart](Scheduling-v3.md#yaml-Scheduling-SlurmQueues-CustomActions-OnNodeStart)自定义操作运行。为了方便起见，该脚本在[FSx 官方文档](https://docs.aws.amazon.com/fsx/latest/LustreGuide/configure-efa-clients.html)中提供，并在我们的公共存储桶中提供，旨在在计算节点上配置 FSx Lustre 客户端，让它们使用 EFA。

1. 创建集群配置文件`config.yaml`：

   ```
   Region: region
   Image:
     Os: ubuntu2204
   HeadNode:
     InstanceType: c5.xlarge
     Networking:
       SubnetId: subnet-xxxxxxxxxx
       AdditionalSecurityGroups:
           - sg-client
     Ssh:
       KeyName: my-ssh-key
   Scheduling:
     Scheduler: slurm
     SlurmQueues:
       - Name: q1
         ComputeResources:
           - Name: cr1
             Instances:
               - InstanceType: g6.16xlarge
             MinCount: 1
             MaxCount: 3
             Efa:
               Enabled: true
         Networking:
           SubnetIds:
             - subnet-xxxxxxxxxx # Subnet in the same AZ where the file system is
           AdditionalSecurityGroups:
             - sg-client
           PlacementGroup:
             Enabled: false
         CustomActions:
           OnNodeStart:
             Script: https://us-east-1-aws-parallelcluster.s3.us-east-1.amazonaws.com/scripts/fsx-lustre-efa/configure-efa-fsx-lustre-client.sh
   SharedStorage:
     - MountDir: /fsx
       Name: my-fsxlustre-efa-external
       StorageType: FsxLustre
       FsxLustreSettings:
         FileSystemId: fs-id
   ```

   然后使用该配置创建集群：

   ```
   pcluster create-cluster \
       --cluster-name fsx-efa-tutorial \
       --cluster-configuration config.yaml \
       --region region
   ```

## FSx 使用 EFA 进行验证正在起作用
<a name="tutorial-efa-enabled-fsx-lustre-validate"></a>

要验证 Lustre 网络流量是否在使用 EFA，请使用可以显示给定网络接口的网络流量的 Lustre `lnetctl` 工具。为此，请在计算节点中执行以下命令：

```
# Take note of the number of packets flowing through the interface, 
# which are specified in statistics:send_count and statistics:recv_count
sudo lnetctl net show --net efa -v

# Generate traffic to the file system
echo 'Hello World' > /fsx/hello-world.txt

# Take note of the number of packets flowing through the interface, 
# which are specified in statistics:send_count and statistics:recv_count
sudo lnetctl net show --net efa -v
```

如果该功能起作用，则流经该接口的数据包数量预计会增加。

# 使用 p6e-gb200 实例支持 nvidia-imex
<a name="support-nvidia-imex-p6e-gb200-instance"></a>

本教程向您展示如何开始使用 AWS ParallelCluster p6e-GB200，以利用最高的 GPU 性能进行 AI 训练和推理。 [p6e-gb200.36xlarge 实例只能通过 p6e 获得，GB200 UltraServers其中 P6e 是 Ultraserver 大](https://aws.amazon.com/ec2/instance-types/p6/)小，构成超级`u-p6e-gb200x72`服务器。`p6e-gb200.36xlarge` [InstanceType](Scheduling-v3.md#yaml-Scheduling-SlurmQueues-ComputeResources-InstanceType)购买 Ultraserver 后`u-p6e-gb200x72`，它将通过适用于 [ML 的 EC2 容量块](https://aws.amazon.com/ec2/capacityblocks/)提供，该容量块将有 18 `p6e-gb200.36xlarge` 个实例。要了解更多信息，请参阅 [p6e-。GB200](https://aws.amazon.com/ec2/instance-types/p6/)

AWS ParallelCluster 版本 3.14.0：
+ 提供此实例类型所需的完整 NVIDIA 软件堆栈（驱动程序、CUDA、EFA、NVIDIA-IMEX） 
+ 为 p6e-ultraserver 创建 nvidia-imex 配置 GB200 
+ 启用并启动 p6e-Ultraserver 的`nvidia-imex`服务 GB200 
+ 配置 Slurm Block 拓扑插件，使每台 p6e-GB200 Ultraserver（EC2 容量块）都是大小合适的 Slurm Block（参见 3.14.0 版本的条目）。[发布说明和文档历史记录](document_history.md)

但是，通过 GPU-to-GPU通信 NVLink 需要额外的配置，特别是包含 IMEX 域中计算节点的 IP 地址的[https://docs.nvidia.com/multi-node-nvlink-systems/imex-guide/config.html#imex-service-node-configuration-file-location](https://docs.nvidia.com/multi-node-nvlink-systems/imex-guide/config.html#imex-service-node-configuration-file-location)文件，该文件 ParallelCluster 不会自动生成。为了帮助生成此文件，我们提供了一个序言脚本，该脚本可以自动发现计算节点 IPs 并配置以[https://docs.nvidia.com/multi-node-nvlink-systems/imex-guide/config.html#imex-service-node-configuration-file-location](https://docs.nvidia.com/multi-node-nvlink-systems/imex-guide/config.html#imex-service-node-configuration-file-location)下 [NVIDIA IMEX Slurm Job Scheduler 集成建议](https://docs.nvidia.com/multi-node-nvlink-systems/imex-guide/deployment.html#job-scheduler-integration)。本教程将向您介绍如何创建 prolog 脚本、如何通过 HeadNode 自定义操作进行部署以及验证 IMEX 设置。

**注意**  
亚马逊 Linux 2023、Ubun GB200 tu 22.04 和 Ubuntu 24 AWS ParallelCluster .04 从 v3.14.0 开始支持 p6e-。有关详细的软件版本和支持的发行版的更新列表，请参阅[AWS ParallelCluster 变更日志](https://github.com/aws/aws-parallelcluster/blob/develop/CHANGELOG.md)。

## 创建用于管理 nvidia-imex 的 Prolog 脚本
<a name="support-nvidia-imex-p6e-gb200-instance-prolog"></a>

**局限性：**
+ 此 prolog 脚本将在提交专属作业时运行。这是为了确保 IMEX 重新启动不会中断属于 IMEX 域的 P6e-GB200 节点上正在运行的任何作业。

以下是你应该在 Slurm 中配置为序言的`91_nvidia_imex_prolog.sh`脚本。它用于自动更新计算节点上的 nvidia-imex 配置。脚本名称的前缀为，`91`以符合 S [chedMD 的命名惯例](https://slurm.schedmd.com/prolog_epilog.html)。这样可以确保它在序列中的任何其他 prolog 脚本之前执行。该脚本会在任务启动时重新配置 NVIDIA Imex 节点的配置，并重新加载必要的 NVIDIA 守护程序。

**注意**  
如果在同一节点上同时启动多个作业，则不会执行此脚本，因此我们建议在提交时使用该`--exclusive`标志。

```
#!/usr/bin/env bash

# This prolog script configures the NVIDIA IMEX on compute nodes involved in the job execution.
#
# In particular:
# - Checks whether the job is executed exclusively.
#   If not, it exits immediately because it requires jobs to be executed exclusively.
# - Checks if it is running on a p6e-gb200 instance type.
#   If not, it exits immediately because IMEX must be configured only on that instance type.
# - Checks if the IMEX service is enabled.
#   If not, it exits immediately because IMEX must be enabled to get configured.
# - Creates the IMEX default channel.
#   For more information about IMEX channels, see https://docs.nvidia.com/multi-node-nvlink-systems/imex-guide/imexchannels.html
# - Writes the private IP addresses of compute nodes into /etc/nvidia-imex/nodes_config.cfg.
# - Restarts the IMEX system service.
#
# REQUIREMENTS:
#  - This prolog assumes to be run only with exclusive jobs.

LOG_FILE_PATH="/var/log/parallelcluster/nvidia-imex-prolog.log"
SCONTROL_CMD="/opt/slurm/bin/scontrol"
IMEX_START_TIMEOUT=60
IMEX_STOP_TIMEOUT=15
ALLOWED_INSTANCE_TYPES="^(p6e-gb200)"
IMEX_SERVICE="nvidia-imex"
IMEX_NODES_CONFIG="/etc/nvidia-imex/nodes_config.cfg"

function info() {
  echo "$(date "+%Y-%m-%dT%H:%M:%S.%3N") [INFO] [PID:$$] [JOB:${SLURM_JOB_ID}] $1"
}

function warn() {
  echo "$(date "+%Y-%m-%dT%H:%M:%S.%3N") [WARN] [PID:$$] [JOB:${SLURM_JOB_ID}] $1"
}

function error() {
  echo "$(date "+%Y-%m-%dT%H:%M:%S.%3N") [ERROR] [PID:$$] [JOB:${SLURM_JOB_ID}] $1"
}

function error_exit() {
  error "$1" && exit 1
}

function prolog_end() {
    info "PROLOG End JobId=${SLURM_JOB_ID}: $0"
    info "----------------"
    exit 0
}

function get_instance_type() {
  local token=$(curl -X PUT -s "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
  curl -s -H "X-aws-ec2-metadata-token: ${token}" http://169.254.169.254/latest/meta-data/instance-type
}

function return_if_unsupported_instance_type() {
  local instance_type=$(get_instance_type)

  if [[ ! ${instance_type} =~ ${ALLOWED_INSTANCE_TYPES} ]]; then
    info "Skipping IMEX configuration because instance type ${instance_type} does not support it"
    prolog_end
  fi
}

function return_if_imex_disabled() {
  if ! systemctl is-enabled "${IMEX_SERVICE}" &>/dev/null; then
    warn "Skipping IMEX configuration because system service ${IMEX_SERVICE} is not enabled"
    prolog_end
  fi
}

function return_if_job_is_not_exclusive() {
  if [[ "${SLURM_JOB_OVERSUBSCRIBE}" =~ ^(NO|TOPO)$  ]]; then
    info "Job is exclusive, proceeding with IMEX configuration"
  else
    info "Skipping IMEX configuration because the job is not exclusive"
    prolog_end
  fi
}

function get_ips_from_node_names() {
  local _nodes=$1
  ${SCONTROL_CMD} -ao show node "${_nodes}" | sed 's/^.* NodeAddr=\([^ ]*\).*/\1/'
}

function get_compute_resource_name() {
  local _queue_name_prefix=$1
  local _slurmd_node_name=$2
  echo "${_slurmd_node_name}" | sed -E "s/${_queue_name_prefix}(.+)-[0-9]+$/\1/"
}

function reload_imex() {
  info "Stopping IMEX"
  timeout ${IMEX_STOP_TIMEOUT} systemctl stop ${IMEX_SERVICE}
  pkill -9 ${IMEX_SERVICE}

  info "Restarting IMEX"
  timeout ${IMEX_START_TIMEOUT} systemctl start ${IMEX_SERVICE}
}

function create_default_imex_channel() {
  info "Creating IMEX default channel"
  MAJOR_NUMBER=$(cat /proc/devices | grep nvidia-caps-imex-channels | cut -d' ' -f1)
  if [ ! -d "/dev/nvidia-caps-imex-channels" ]; then
    sudo mkdir /dev/nvidia-caps-imex-channels
  fi

  # Then check and create device node
  if [ ! -e "/dev/nvidia-caps-imex-channels/channel0" ]; then
    sudo mknod /dev/nvidia-caps-imex-channels/channel0 c $MAJOR_NUMBER 0
    info "IMEX default channel created"
  else
    info "IMEX default channel already exists"
  fi
}

{
  info "PROLOG Start JobId=${SLURM_JOB_ID}: $0"

  return_if_job_is_not_exclusive
  return_if_unsupported_instance_type
  return_if_imex_disabled

  create_default_imex_channel

  IPS_FROM_CR=$(get_ips_from_node_names "${SLURM_NODELIST}")

  info "Node Names: ${SLURM_NODELIST}"
  info "Node IPs: ${IPS_FROM_CR}"
  info "IMEX Nodes Config: ${IMEX_NODES_CONFIG}"

  info "Updating IMEX nodes config ${IMEX_NODES_CONFIG}"
  echo "${IPS_FROM_CR}" > "${IMEX_NODES_CONFIG}"
  reload_imex

  prolog_end

} 2>&1 | tee -a "${LOG_FILE_PATH}" | logger -t "91_nvidia_imex_prolog"
```

## 创建 HeadNode OnNodeStart 自定义操作脚本
<a name="support-nvidia-imex-p6e-gb200-instance-action-script"></a>

创建一个`install_custom_action.sh`自定义操作，该操作将在共享目录中下载前面提到的 prolog 脚本，`/opt/slurm/etc/scripts/prolog.d/`该目录可由 Compute Nodes 访问，并设置要执行的适当权限。

```
#!/bin/bash
set -e

echo "Executing $0"

PROLOG_NVIDIA_IMEX=/opt/slurm/etc/scripts/prolog.d/91_nvidia_imex_prolog.sh
aws s3 cp "s3://<Bucket>/91_nvidia_imex_prolog.sh" "${PROLOG_NVIDIA_IMEX}"
chmod 0755 "${PROLOG_NVIDIA_IMEX}"
```

## 创建集群
<a name="support-nvidia-imex-p6e-gb200-instance-cluster"></a>

创建包含 P6e 实例的集群。GB200 您可以在下面找到包含 Ultraserver SlurmQueues 类型的配置示例。`u-p6e-gb200x72`

P6e-目前GB200 仅在 Local Zones 中可用。有些 L [ocal Zones 不支持 NAT 网关](https://docs.aws.amazon.com/local-zones/latest/ug/local-zones-connectivity-nat.html)，因此请根据 ParallelCluster 需要遵循[本地区域的连接选项](https://docs.aws.amazon.com/local-zones/latest/ug/local-zones-connectivity.html)[为受限环境配置安全组](security-groups-configuration.md)来连接 AWS 服务。请按照 [使用容量块（CB）启动实例](launch-instances-capacity-blocks.md) (AWS ParallelClusterLaunch) 进行操作，因为 Ultraserver 只能作为容量块使用。

```
HeadNode:
  CustomActions:
    OnNodeStart:
      Script: s3://<s3-bucket-name>/install_custom_action.sh
    S3Access:
      - BucketName: <s3-bucket-name>
  InstanceType: <HeadNode-instance-type>
  Networking:
    SubnetId: <subnet-abcd78901234567890>
  Ssh:
    KeyName: <Key-name>
Image:
  Os: ubuntu2404
Scheduling:
  Scheduler: slurm
  SlurmSettings:
    CustomSlurmSettings:
      - PrologFlags: "Alloc,NoHold"
      - MessageTimeout: 240
  SlurmQueues:
    - CapacityReservationTarget:
        CapacityReservationId: <cr-123456789012345678>
      CapacityType: CAPACITY_BLOCK
      ComputeResources: ### u-p6e-gb200x72
        - DisableSimultaneousMultithreading: true
          Efa:
            Enabled: true
          InstanceType: p6e-gb200.36xlarge  
          MaxCount: 18
          MinCount: 18
          Name: cr1
      Name: q1
      Networking:
        SubnetIds:
          - <subnet-1234567890123456>
```

## 验证 IMEX 设置
<a name="support-nvidia-imex-p6e-gb200-instance-validate"></a>

当你提交 S `91_nvidia_imex_prolog.sh` lurm 作业时，序言就会运行。以下是检查 NVidia-imex 域名状态的示例任务。

```
#!/bin/bash
#SBATCH --job-name=nvidia-imex-status-job
#SBATCH --ntasks-per-node=1
#SBATCH --output=slurm-%j.out
#SBATCH --error=slurm-%j.err

QUEUE_NAME="q1"
COMPUTE_RES_NAME="cr1"
IMEX_CONFIG_FILE="/opt/parallelcluster/shared/nvidia-imex/config_${QUEUE_NAME}_${COMPUTE_RES_NAME}.cfg"

srun bash -c "/usr/bin/nvidia-imex-ctl -N -c ${IMEX_CONFIG_FILE} > result_\${SLURM_JOB_ID}_\$(hostname).out 2> result_\${SLURM_JOB_ID}_\$(hostname).err"
```

查看 Job 的输出：

```
Connectivity Table Legend:
I - Invalid - Node wasn't reachable, no connection status available
N - Never Connected
R - Recovering - Connection was lost, but clean up has not yet been triggered.
D - Disconnected - Connection was lost, and clean up has been triggreed.
A - Authenticating - If GSSAPI enabled, client has initiated mutual authentication.
!V! - Version mismatch, communication disabled.
!M! - Node map mismatch, communication disabled.
C - Connected - Ready for operation

5/12/2025 06:08:10.580
Nodes:
Node #0   - 172.31.48.81    - READY                - Version: 570.172
Node #1   - 172.31.48.98    - READY                - Version: 570.172
Node #2   - 172.31.48.221   - READY                - Version: 570.172
Node #3   - 172.31.49.228   - READY                - Version: 570.172
Node #4   - 172.31.50.39    - READY                - Version: 570.172
Node #5   - 172.31.50.44    - READY                - Version: 570.172
Node #6   - 172.31.51.66    - READY                - Version: 570.172
Node #7   - 172.31.51.157   - READY                - Version: 570.172
Node #8   - 172.31.52.239   - READY                - Version: 570.172
Node #9   - 172.31.53.80    - READY                - Version: 570.172
Node #10  - 172.31.54.95    - READY                - Version: 570.172
Node #11  - 172.31.54.183   - READY                - Version: 570.172
Node #12  - 172.31.54.203   - READY                - Version: 570.172
Node #13  - 172.31.54.241   - READY                - Version: 570.172
Node #14  - 172.31.55.59    - READY                - Version: 570.172
Node #15  - 172.31.55.187   - READY                - Version: 570.172
Node #16  - 172.31.55.197   - READY                - Version: 570.172
Node #17  - 172.31.56.47    - READY                - Version: 570.172

 Nodes From\To  0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  16  17
       0        C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C 
       1        C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C 
       2        C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C
       3        C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C  
       4        C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C 
       5        C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C 
       6        C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C
       7        C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C 
       8        C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C 
       9        C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   
      10        C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   
      11        C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   
      12        C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   
      13        C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   
      14        C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C  
      15        C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C  
      16        C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C  
      17        C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C   C  

Domain State: UP
```

# 使用启动模板覆盖自定义计算节点网络接口
<a name="tutorial-network-customization-v3"></a>

从 AWS ParallelCluster 3.15.0 开始，该`LaunchTemplateOverrides`参数允许您使用引用的启动模板中的配置覆盖默认网络接口配置，从而自定义计算节点的网络接口。计算节点的整个网络接口部分被用于覆盖的启动模板的网络接口部分覆盖。

本教程演示了一个覆盖`p6-b300.48xlarge`计算节点默认网络配置的示例。当您需要与默认配置不同的特定网络接口配置时，此自定义非常有用。 AWS ParallelCluster 在本示例中，我们按照 A [mazon EC2 EFA 支持的实例类型文档中概述的 P6-B300 实例](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa-acc-inst-types.html)配置用例 2。

**注意**  
为了最大限度地提高灵活性，建议使用而不是控制台 AWS CLI 来创建启动模板。

**注意**  
启动模板应仅包含网络接口替代项。 AWS ParallelCluster 具有防止覆盖其他参数的验证。

**警告**  
如果您使用替换功能以所使用的实例类型不支持的方式配置网络接口，则实例将无法启动。

**先决条件**
+ AWS ParallelCluster 已安装版本 3.15.0 或更高版本[。](install-v3-parallelcluster.md)
+  AWS CLI [已安装并配置。](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ 您拥有具有运行 [`pcluster`](pcluster-v3.md) CLI 所需的[权限](iam-roles-in-parallelcluster-v3.md#iam-roles-in-parallelcluster-v3-example-user-policies)的 IAM 角色。

## 步骤 1：创建安全组
<a name="tutorial-network-customization-v3-security-groups"></a>

在创建用于替代的启动模板时，必须引用安全组。在创建集群之前，计算资源的默认 AWS ParallelCluster 安全组不存在，因此您必须创建自定义安全组。然后，头节点安全组必须引用此安全组，以允许头节点和计算节点之间的流量。

如果您要更新现有集群以自定义新容量，则可以在启动模板中使用默认 AWS ParallelCluster 计算节点安全组，而不是创建自定义计算节点安全组。

创建以下两个安全组：
+ **Head node 附加安全组** (`sg-1234abcd`)：
  + 入口：来自计算安全组的所有流量
+ **计算安全组** (`sg-abcd1234`)：
  + 入口：来自头节点安全组的所有流量
  + 入口：所有来自自我的流量 () compute-to-compute
  + 出口：默认全部允许

## 步骤 2：创建启动模板
<a name="tutorial-network-customization-v3-launch-template"></a>

创建用于定义`p6-b300.48xlarge`计算节点网络接口配置的启动模板。对于主网络接口（网卡索引 0，设备索引 0），请使用 ENA（默认）网络接口。对于其余的网卡，创建一个仅限 EFA 的接口（网卡索引 1-16，设备索引 0）和 ENA（默认）接口（网卡索引 1-16，设备索引 1）。

运行以下 AWS CLI 命令来创建启动模板 (`lt-123456789`)：

```
aws ec2 create-launch-template \
  --region us-east-1 \
  --launch-template-name override-lt \
  --launch-template-data '{
    "NetworkInterfaces": [
      {"NetworkCardIndex":0,  "DeviceIndex":0, "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":1,  "DeviceIndex":0, "InterfaceType":"efa-only", "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":1,  "DeviceIndex":1, "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":2,  "DeviceIndex":0, "InterfaceType":"efa-only", "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":2,  "DeviceIndex":1, "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":3,  "DeviceIndex":0, "InterfaceType":"efa-only", "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":3,  "DeviceIndex":1, "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":4,  "DeviceIndex":0, "InterfaceType":"efa-only", "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":4,  "DeviceIndex":1, "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":5,  "DeviceIndex":0, "InterfaceType":"efa-only", "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":5,  "DeviceIndex":1, "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":6,  "DeviceIndex":0, "InterfaceType":"efa-only", "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":6,  "DeviceIndex":1, "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":7,  "DeviceIndex":0, "InterfaceType":"efa-only", "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":7,  "DeviceIndex":1, "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":8,  "DeviceIndex":0, "InterfaceType":"efa-only", "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":8,  "DeviceIndex":1, "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":9,  "DeviceIndex":0, "InterfaceType":"efa-only", "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":9,  "DeviceIndex":1, "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":10, "DeviceIndex":0, "InterfaceType":"efa-only", "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":10, "DeviceIndex":1, "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":11, "DeviceIndex":0, "InterfaceType":"efa-only", "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":11, "DeviceIndex":1, "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":12, "DeviceIndex":0, "InterfaceType":"efa-only", "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":12, "DeviceIndex":1, "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":13, "DeviceIndex":0, "InterfaceType":"efa-only", "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":13, "DeviceIndex":1, "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":14, "DeviceIndex":0, "InterfaceType":"efa-only", "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":14, "DeviceIndex":1, "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":15, "DeviceIndex":0, "InterfaceType":"efa-only", "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":15, "DeviceIndex":1, "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":16, "DeviceIndex":0, "InterfaceType":"efa-only", "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"},
      {"NetworkCardIndex":16, "DeviceIndex":1, "Groups":["sg-abcd1234"], "SubnetId":"subnet-123456789"}
    ]
  }'
```

## 步骤 3：使用启动模板覆盖创建集群
<a name="tutorial-network-customization-v3-create-cluster"></a>

创建使用`LaunchTemplateOverrides`参数引用您创建的启动模板的集群配置。

```
Region: us-east-1
HeadNode:
  InstanceType: c5.xlarge
  Networking:
    SubnetId: subnet-abcdefghi
    AdditionalSecurityGroups:
      # Add the head node SG that allows traffic from the compute node SG
      - sg-1234abcd
...

Scheduling:
  Scheduler: slurm
  SlurmQueues:
  - Name: queue0
    Networking:
      SubnetIds:
        - subnet-123456789
    ComputeResources:
      - Name: compute-resource1
        InstanceType: p6-b300.48xlarge
        Efa:
          Enabled: false # The override replaces all network interface configuration, so this setting is ignored
        LaunchTemplateOverrides:
          LaunchTemplateId: lt-123456789
          Version: 1 # If the launch template is updated, then the new version should be specified here.
```