

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 在 AWS PCS 中使用 Slurm REST API 驗證
<a name="slurm-rest-api-authenticate"></a>

 AWS PCS 中的 Slurm REST API 使用 JSON Web Token (JWT) 身分驗證來確保對叢集資源的安全存取。 AWS PCS 提供存放在 AWS Secrets Manager 中的受管簽署金鑰，您可用來產生包含特定使用者身分宣告的 JWT 權杖。

## 先決條件
<a name="slurm-rest-api-authenticate-prerequisites"></a>

使用 Slurm REST API 驗證之前，請確定您有：
+ **叢集組態**：已啟用 Slurm 25.05\$1 和 REST API 的 AWS PCS 叢集。
+ **AWS 許可**：存取 JWT 簽署金鑰的 AWS Secrets Manager。
+ **使用者資訊**：您叢集帳戶的使用者名稱、POSIX 使用者 ID 和一或多個 POSIX 群組 IDs。
+ **網路存取**：叢集 VPC 內的連線與允許連接埠 6820 的安全群組。

## 程序
<a name="slurm-rest-api-authenticate-procedure"></a>

**擷取 Slurm REST API 端點地址**

------
#### [ AWS 管理主控台 ]

1. 在 https：//[https://console.aws.amazon.com/pcs/](https://console.aws.amazon.com/pcs/) 開啟 AWS PCS 主控台。

1. 從清單中選擇您的叢集。

1. 在叢集組態詳細資訊中，找到**端點**區段。

1. 請注意 **Slurm REST API (slurmrestd)** 的私有 IP 地址和連接埠。

1. 您可以透過傳送格式正確的 HTTP 請求到此地址來進行 API 呼叫。

------
#### [ AWS CLI ]

1. 使用 查詢您的叢集狀態`aws pcs get-cluster`。在回應的 `endpoints` 欄位中尋找`SLURMRESTD`端點。請見此處範例：

   ```
   "endpoints": [
         {
             "type": "SLURMCTLD",
             "privateIpAddress": "192.0.2.1",
             "port": "6817"
         },
         {
             "type": "SLURMRESTD",
             "privateIpAddress": "192.0.2.1",
             "port": "6820"
         }
     ]
   ```

1. 您可以將格式正確的 HTTP 請求傳送至 `http://<privateIpAddress>:<port>/`

------

**擷取 JWT 簽署金鑰**

1. 在 https：//[https://console.aws.amazon.com/pcs/](https://console.aws.amazon.com/pcs/) 開啟 AWS PCS 主控台。

1. 從清單中選擇您的叢集。

1. 在叢集組態詳細資訊中，找到**排程器身分驗證**區段。

1. 請注意 **JSON Web Token (JWT) 金鑰** ARN 和版本。

1. 使用 從 Secrets Manager AWS CLI 擷取簽署金鑰：

   ```
   aws secretsmanager get-secret-value --secret-id arn:aws:secretsmanager:region:account:secret:name --version-id version
   ```

**產生 JWT 字符**

1. 使用下列必要宣告建立 JWT：
   + `exp` – JWT 自 1970 以來的過期時間，以秒為單位
   + `iat` – 自 1970 以來的目前時間，以秒為單位
   + `sun` – 身分驗證的使用者名稱
   + `uid` – POSIX 使用者 ID
   + `gid` – POSIX 群組 ID
   + `id` – 其他 POSIX 身分屬性
     + `gecos` – 使用者註解欄位，通常用於存放人類可讀取的名稱
     + `dir` – 使用者的主目錄
     + `shell` – 使用者的預設 shell
     + `gids` – 使用者所在的其他 POSIX 群組 IDs清單

1. 使用從 Secrets Manager 擷取的簽署金鑰簽署 JWT。

1. 為字符設定適當的過期時間。

**注意**  
作為`sun`宣告的替代方案，您可以提供下列任何一項：  
`username`
您在 `userclaimfield`中透過 定義的自訂欄位名稱 `AuthAltParameters Slurm custom settings`
`id` 宣告中的`name`欄位

**驗證 API 請求**

1. 使用下列其中一種方法在 HTTP 請求中包含 JWT 字符：
   + **承載字符** – 新增`Authorization: Bearer <jwt>`標頭
   + **Slurm 標頭** – 新增`X-SLURM-USER-TOKEN: <jwt>`標頭

1. 向 REST API 端點提出 HTTP 請求：

   以下是使用 curl 和 `Authorized: Bearer`標頭存取 `/ping` API 的範例。

   ```
   curl -X GET -H "Authorization: Bearer <jwt>" \
         http://<privateIpAddress>:6820/slurm/v0.0.43/ping
   ```

## 產生 JWT 的範例
<a name="slurm-rest-api-authenticate-example"></a>

擷取 AWS PCS 叢集 JWT 簽署金鑰，並將其儲存為本機檔案。將 **aws-region**、 **secret-arn** 和 **secret 版本**的值取代為您的叢集適用的值。

```
#!/bin/bash
SECRET_KEY=$(aws secretsmanager get-secret-value \
  --region aws-region \
  --secret-id secret-arn \
  --version-stage secret-version \
  --query 'SecretString' \
  --output text)
echo "$SECRET_KEY" | base64 --decode > jwt.key
```

此 Python 範例說明如何使用簽署金鑰來產生 JWT 字符：

```
#!/usr/bin/env python3

import sys
import os
import pprint
import json
import time
from datetime import datetime, timedelta, timezone
from jwt import JWT
from jwt.jwa import HS256
from jwt.jwk import jwk_from_dict
from jwt.utils import b64decode,b64encode
if len(sys.argv) != 3:
    sys.exit("Usage: gen_jwt.py [jwt_key_file] [expiration_time_seconds]")
SIGNING_KEY = sys.argv[1]
EXPIRATION_TIME = int(sys.argv[2])
with open(SIGNING_KEY, "rb") as f:
    priv_key = f.read()
signing_key = jwk_from_dict({
    'kty': 'oct',
    'k': b64encode(priv_key)
})
message = {
    "exp": int(time.time() + EXPIRATION_TIME),
    "iat": int(time.time()),
    "sun": "ec2-user",
    "uid": 1000,
    "gid": 1000,
    "id": {
        "gecos": "EC2 User",
        "dir": "/home/ec2-user",
        "gids": [1000],
        "shell": "/bin/bash"
    }
}
a = JWT()
compact_jws = a.encode(message, signing_key, alg='HS256')
print(compact_jws)
```

指令碼會將 JWT 列印到螢幕。

```
abcdefgtjwttoken...
```