

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# AWS PCS에서 Slurm REST API로 인증
<a name="slurm-rest-api-authenticate"></a>

 AWS PCS의 Slurm REST API는 JSON 웹 토큰(JWT) 인증을 사용하여 클러스터 리소스에 대한 보안 액세스를 보장합니다. AWS PCS는 AWS Secrets Manager에 저장된 관리형 서명 키를 제공하며, 이를 사용하여 특정 사용자 자격 증명 클레임이 포함된 JWT 토큰을 생성합니다.

## 사전 조건
<a name="slurm-rest-api-authenticate-prerequisites"></a>

Slurm REST API로 인증하기 전에 다음을 확인하세요.
+ **클러스터 구성**: Slurm 25.05 이상 및 REST API가 활성화된 AWS PCS 클러스터.
+ **AWS 권한**: JWT 서명 키에 대한 AWS Secrets Manager에 대한 액세스입니다.
+ **사용자 정보**: 클러스터 계정의 사용자 이름, POSIX 사용자 ID 및 하나 이상의 POSIX 그룹 IDs.
+ **네트워크 액세스**: 포트 6820을 허용하는 보안 그룹을 사용한 클러스터의 VPC 내 연결.

## 절차
<a name="slurm-rest-api-authenticate-procedure"></a>

**Slurm REST API 엔드포인트 주소를 검색하려면**

------
#### [ AWS Management Console ]

1. [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 요청을 로 전송하여 API 호출을 수행할 수 있습니다. `http://<privateIpAddress>:<port>/` 

------

**JWT 서명 키를 검색하려면**

1. [https://console.aws.amazon.com/pcs/](https://console.aws.amazon.com/pcs/) AWS PCS 콘솔을 엽니다.

1. 목록에서 클러스터를 선택합니다.

1. 클러스터 구성 세부 정보에서 **스케줄러 인증** 섹션을 찾습니다.

1. **JSON 웹 토큰(JWT) 키** ARN 및 버전을 기록해 둡니다.

1.  AWS CLI 를 사용하여 Secrets Manager에서 서명 키를 검색합니다.

   ```
   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` - 사용자의 기본 셸
     + `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...
```