Slurm Metric을 Amazon CloudWatch로 수집하고 Grafana 대시보드로 시각화해 봤습니다.
안녕하세요 클래스메소드 김재욱(Kim Jaewook) 입니다. 이번에는 Slurm Metric을 Amazon CloudWatch로 수집하고 Grafana 대시보드로 시각화해 봤습니다.
전체 흐름
[PCS 클러스터]
Slurm Controller (OpenMetrics 엔드포인트, 포트 6817)
│
│ (Prometheus 스크래핑 형식으로 노출)
▼
[CloudWatch Agent] ← PCS 로그인 노드(또는 접근 가능한 EC2)에 설치
- Prometheus 리시버로 스크래핑
- EMF(Embedded Metric Format)로 변환
│
▼
[Amazon CloudWatch]
- Logs: 로그 그룹에 EMF 로그 적재
- Metrics: 커스텀 네임스페이스(CWAgent/Prometheus)로 메트릭 저장
│
▼
[Grafana] (별도 EC2에 구축)
- CloudWatch 데이터소스로 연결
- 대시보드에서 시각화
사전 조건
- AWS PCS 클러스터 (Slurm 25.11 이상 필요 — OpenMetrics 기능이 이 버전부터 지원)
- 클러스터가 프라이빗 서브넷 + NAT Gateway 구성이어도 무방 (CloudWatch API 호출을 위해 아웃바운드 통신만 되면 됨)
- 로그인 노드에 SSH 또는 SSM 접속 가능
- 별도 EC2에 Grafana(OSS) 설치되어 있음 (Amazon Managed Grafana를 쓴다면 뒤쪽 데이터소스 연동 부분만 참고)
1단계: PCS 클러스터에서 OpenMetrics 활성화
필요한 설정 2가지
AWS PCS의 Slurm 커스텀 설정에 다음 두 가지를 반드시 함께 넣어야 합니다.
| 파라미터 | 값 | 비고 |
|---|---|---|
MetricsType |
metrics/openmetrics |
OpenMetrics 형식으로 메트릭을 노출 |
CommunicationParameters |
enable_http |
AWS PCS는 기본적으로 HTTP 엔드포인트가 꺼져 있음. 이걸 명시하지 않으면 MetricsType requires enable_http to be set in CommunicationParameters 에러가 남 |
2단계: 메트릭 엔드포인트 위치 찾기
로그인 노드에서 curl http://localhost:6817/metrics를 때려봤는데 계속 응답이 없었습니다. 원인은 간단했습니다 — 포트 6817은 로그인 노드가 아니라 Slurm 컨트롤러(slurmctld)의 포트입니다. 로그인 노드의 slurmd는 보통 6818번 포트를 씁니다.
AWS PCS 콘솔의 클러스터 상세 정보에서 "Slurm 기본 컨트롤러(slurmctld)"의 IP:포트를 확인해서, 그 주소로 curl 해야 합니다.
# 컨트롤러 IP는 PCS 콘솔의 클러스터 정보에서 확인
curl -s http://<컨트롤러_IP>:6817/metrics
컨트롤러 IP로 접속에는 성공했는데, 응답이 이랬습니다.
slurmctld index of metrics endpoints:
'/metrics/jobs': get job metrics
'/metrics/nodes': get node metrics
'/metrics/partitions': get partition metrics
'/metrics/jobs-users-accts': get user and account jobs metrics
'/metrics/scheduler': get scheduler metrics
즉 /metrics는 실제 메트릭이 아니라 하위 경로 목록을 보여주는 인덱스였습니다. 실제 OpenMetrics 형식(# HELP, # TYPE 포함) 데이터는 아래 경로들에서 나옵니다.
curl -s http://<컨트롤러_IP>:6817/metrics/jobs # 잡 상태별 개수 (running, pending, completed 등)
curl -s http://<컨트롤러_IP>:6817/metrics/nodes # 노드별 CPU/상태 (node 라벨 포함)
curl -s http://<컨트롤러_IP>:6817/metrics/scheduler # 스케줄러 내부 통계
curl -s http://<컨트롤러_IP>:6817/metrics/partitions # 파티션별 잡 상태 (partition 라벨 포함)
모든 메트릭이 gauge 타입인 것도 확인해뒀습니다. (뒤에서 이게 왜 중요한지 나옵니다.)
3단계: CloudWatch Agent 설치 및 Prometheus 스크래핑 설정
이제 로그인 노드(컨트롤러에 네트워크로 접근 가능한 EC2)에 CloudWatch Agent를 설치해서, 컨트롤러의 메트릭 엔드포인트를 스크래핑하도록 설정합니다.
IAM 권한 준비
CloudWatch Agent가 실행되는 인스턴스의 IAM Role에 CloudWatchAgentServerPolicy (AWS 관리형 정책)를 연결합니다. 이 정책엔 cloudwatch:PutMetricData, logs:PutLogEvents 등 쓰기 권한이 들어 있습니다.
CloudWatch Agent 설치
# 배포판 확인
cat /etc/os-release
# Amazon Linux 계열
sudo yum install -y amazon-cloudwatch-agent
Prometheus 스크래핑 설정 (prometheus.yaml)
4개의 메트릭 경로마다 metrics_path가 다르므로, job을 4개로 나눠서 정의합니다.
sudo mkdir -p /opt/aws/amazon-cloudwatch-agent/etc
sudo tee /opt/aws/amazon-cloudwatch-agent/etc/prometheus.yaml > /dev/null << 'EOF'
global:
scrape_interval: 30s
scrape_configs:
- job_name: 'pcs-slurm-jobs'
metrics_path: /metrics/jobs
static_configs:
- targets: ['<컨트롤러_IP>:6817']
- job_name: 'pcs-slurm-nodes'
metrics_path: /metrics/nodes
static_configs:
- targets: ['<컨트롤러_IP>:6817']
- job_name: 'pcs-slurm-scheduler'
metrics_path: /metrics/scheduler
static_configs:
- targets: ['<컨트롤러_IP>:6817']
- job_name: 'pcs-slurm-partitions'
metrics_path: /metrics/partitions
static_configs:
- targets: ['<컨트롤러_IP>:6817']
EOF
CloudWatch Agent 설정 (EMF 방식)
sudo tee /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json > /dev/null << 'EOF'
{
"agent": {
"region": "<YOUR_REGION>"
},
"logs": {
"metrics_collected": {
"prometheus": {
"log_group_name": "pcs-slurm-metrics",
"prometheus_config_path": "/opt/aws/amazon-cloudwatch-agent/etc/prometheus.yaml",
"emf_processor": {
"metric_declaration": [
{
"source_labels": ["job"],
"label_matcher": "^pcs-slurm-jobs$",
"dimensions": [["job"]],
"metric_selectors": ["^slurm_.*"]
},
{
"source_labels": ["job"],
"label_matcher": "^pcs-slurm-nodes$",
"dimensions": [["job", "node"]],
"metric_selectors": ["^slurm_.*"]
},
{
"source_labels": ["job"],
"label_matcher": "^pcs-slurm-scheduler$",
"dimensions": [["job"]],
"metric_selectors": ["^slurm_.*"]
},
{
"source_labels": ["job"],
"label_matcher": "^pcs-slurm-partitions$",
"dimensions": [["job", "partition"]],
"metric_selectors": ["^slurm_.*"]
}
]
}
}
}
}
}
EOF
처음엔 각 job의 metric_selectors를 ^slurm_jobs_.*, ^slurm_node_.*처럼 세밀하게 지정했는데, 다음과 같은 로그가 찍히면서 일부 메트릭이 드롭됐습니다.
Dropped metric: no metric declaration matched metric name Metric name: slurm_nodes_down
원인은 Slurm 메트릭 이름이 일관되지 않다는 것이었습니다. slurm_node_cpus처럼 단수형도 있고, slurm_nodes_down처럼 복수형도 있습니다. 정규식을 촘촘하게 짜려다 오히려 빠지는 메트릭이 생기니, ^slurm_.*로 넓게 잡고 job 라벨(label_matcher)로 구분하는 게 훨씬 안전합니다.
CloudWatch Agent 시작
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
-a fetch-config -m ec2 -s \
-c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json
# 상태 확인
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a status
# 로그로 드롭되는 메트릭이 있는지 확인
sudo tail -50 /opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log | grep -i "drop\|unsupported\|error"
Dropped metric 같은 로그가 더 이상 나오지 않으면 정상입니다. (EC2MetadataError 관련 로그는 agent 기능에 영향 없다고 명시되어 있으므로 무시해도 됩니다.)
※ 참고: CloudWatch Agent의 Prometheus 수집기는 Gauge, Counter, Summary 타입만 지원하고 Histogram은 지원하지 않습니다. 다행히 Slurm의 OpenMetrics 메트릭은 전부 gauge라 이 문제는 겪지 않았지만, 다른 Prometheus exporter를 연동할 때는 유의해야 합니다.
4단계: CloudWatch에서 수집 확인
AWS 콘솔 → CloudWatch → Log groups에서 pcs-slurm-metrics 로그 그룹이 생성됐는지 확인합니다.

그리고 CloudWatch → Metrics → All metrics에서 커스텀 네임스페이스를 확인하면, CWAgent/Prometheus라는 네임스페이스 아래 job, job+node, job+partition 조합의 메트릭들이 쌓여 있는 걸 볼 수 있습니다.
5단계: Grafana와 CloudWatch 연동
이제 별도 EC2에 구축해둔 Grafana에서 CloudWatch를 데이터소스로 추가합니다.
Grafana 데이터소스 설정에서 CloudWatch 연결 테스트를 했더니 이런 에러가 났습니다.
AccessDenied: User: .../GrafanaXXXQueryPolicy/... is not authorized to perform: cloudwatch:ListMetrics
앞서 CloudWatch Agent용으로 붙여둔 CloudWatchAgentServerPolicy는 메트릭을 쓰는(PutMetricData) 권한만 있고, Grafana가 필요로 하는 읽는(ListMetrics, GetMetricData) 권한이 없습니다. 이 둘은 완전히 별개의 권한이라는 걸 놓치기 쉽습니다.
해결: Grafana가 돌아가는 EC2의 IAM Role에 CloudWatchReadOnlyAccess(AWS 관리형 정책)를 추가로 연결합니다.
데이터소스 설정 순서 정리
- Grafana 좌측 메뉴 → Connections → Data sources → Add data source
- CloudWatch 선택
- Authentication Provider:
AWS SDK Default(EC2 인스턴스 프로파일 자동 사용) - Default Region: 사용 중인 리전 선택 (필수!)
- (선택) Namespaces of Custom Metrics에
CWAgent/Prometheus입력 — 나중에 패널 만들 때 자동완성됨 - Save & Test →
Successfully queried the CloudWatch metrics API확인
6단계: 대시보드 만들고 실제로 테스트하기
패널 예시
| 목적 | Namespace | Metric name | Dimensions |
|---|---|---|---|
| 실행 중인 잡 수 | CWAgent/Prometheus |
slurm_jobs_running |
job=pcs-slurm-jobs |
| 대기 중인 잡 수 | CWAgent/Prometheus |
slurm_jobs_pending |
job=pcs-slurm-jobs |
| 노드별 CPU 할당 | CWAgent/Prometheus |
slurm_node_cpus_alloc |
job=pcs-slurm-nodes |
| 파티션별 대기 잡 | CWAgent/Prometheus |
slurm_partition_jobs_pending |
job=pcs-slurm-partitions, partition=<파티션명> |
실제 잡을 던져서 그래프 변화 확인
export PATH=/opt/aws/pcs/scheduler/slurm-25.11/bin:$PATH
cat > ~/test_job.sh << 'EOF'
#!/bin/bash
#SBATCH --job-name=test_job
#SBATCH --partition=<파티션명>
#SBATCH --ntasks=1
#SBATCH --time=00:03:00
sleep 90
EOF
sbatch ~/test_job.sh
squeue
잡을 제출하고 1~2분 정도 기다리면(노드가 0대에서 새로 뜨는 시간 포함), Grafana 대시보드의 slurm_jobs_running 값이 0 → 1로 올라가는 걸 실시간으로 확인할 수 있습니다.

정리
| 구성 요소 | 역할 |
|---|---|
| PCS 클러스터 (MetricsType + enable_http) | Slurm 컨트롤러가 OpenMetrics 형식으로 메트릭 노출 (포트 6817, /metrics/jobs 등 하위 경로) |
| CloudWatch Agent (Prometheus 리시버) | 컨트롤러의 메트릭을 스크래핑해서 EMF로 변환 후 CloudWatch로 전송 |
| CloudWatch Logs / Metrics | EMF 로그 적재 + 커스텀 네임스페이스(CWAgent/Prometheus)로 메트릭 저장 |
| Grafana (CloudWatch 데이터소스) | 저장된 메트릭을 대시보드로 시각화 |
핵심 포인트를 요약하면:
- PCS에서 OpenMetrics를 쓰려면 MetricsType과 CommunicationParameters=enable_http를 클러스터 생성 시점에 함께 넣어야 한다 (기존 클러스터에 나중에 추가하면 잘 안 먹는다)
- 메트릭 엔드포인트는 로그인 노드가 아니라 컨트롤러에 있고, /metrics는 인덱스일 뿐 실제 데이터는 /metrics/jobs 등 하위 경로에 있다
- CloudWatch Agent 설정 시 metric_selectors 정규식은 넓게 잡는 게 안전하다
- 쓰기 권한(CloudWatchAgentServerPolicy)과 읽기 권한(CloudWatchReadOnlyAccess)은 별개다 — Agent를 실행하는 인스턴스와 Grafana를 실행하는 인스턴스에 각각 맞는 권한을 챙겨야 한다
- Grafana의 CloudWatch 데이터소스는 Default Region을 반드시 명시해야 한다
Amazon Managed Service for Prometheus 없이도, HPC 클러스터의 Slurm 메트릭을 CloudWatch + Grafana 조합으로 충분히 모니터링할 수 있다는 걸 확인했습니다. 관리형 Prometheus 워크스페이스 비용이 부담스럽거나, 이미 CloudWatch 중심으로 모니터링 체계를 운영하고 있는 환경이라면 이 방식도 좋은 대안이 될 수 있을 것 같습니다.










