2026-05-28 — ECS 클러스터 사용 현황 감사 (지난 7일)¶
한 줄 요약
us-east-1 리전의 ECS 클러스터 40개 중 지난 7일간 실제로 태스크가 실행된
클러스터는 1개(compositet3-prod-240531-cluster)였다는 사실을 CloudWatch
메트릭과 ECS 이벤트로 교차검증한 절차.
- 대상 계정:
790590917886(reco-kyle프로파일) - 대상 리전:
us-east-1 - 작업일: 2026-05-28
1. 배경/목적¶
미사용 ECS 클러스터를 정리하기 전 단계로, "최근 사용 흔적이 있는가"라는 기준으로 클러스터를 분류해야 했다. "있다/없다"를 일관되게 판정할 수 있는 지표가 필요했다.
무엇을 "사용 중"으로 볼 것인가¶
| 후보 신호 | 판정에 적합한가 | 이유 |
|---|---|---|
describe-clusters의 runningTasksCount |
△ | 현재 시점 스냅샷일 뿐 |
서비스의 desiredCount > 0 |
△ | 설정값이지 활동 증거가 아님 |
| 서비스 이벤트 개수 | ❌ | has reached a steady state.가 6시간마다 자동 발생해 desired=0인 클러스터도 100개씩 쌓임 |
CloudWatch AWS/ECS CPUUtilization 데이터포인트 |
✅ | 태스크가 실제로 실행되어야만 점이 찍힘 |
CloudWatch AWS/ECS CPUReservation |
✅ | EC2 launch type에서 컨테이너 인스턴스가 예약돼 있을 때만 점이 찍힘 |
ECS/ContainerInsights RunningTaskCount |
✅ (단, Container Insights 활성화 시) |
→ 결론: CPUUtilization 데이터포인트 존재 여부를 1차 지표로 삼는다.
2. 절차¶
2.1 클러스터 목록 가져오기¶
2.2 각 클러스터에 대해 지난 7일 CPUUtilization 데이터포인트 수 확인¶
스크립트(check_ecs.sh):
#!/bin/bash
PROFILE=reco-kyle
REGION=us-east-1
START=$(date -u -v-7d '+%Y-%m-%dT%H:%M:%SZ')
END=$(date -u '+%Y-%m-%dT%H:%M:%SZ')
check_cluster() {
local arn=$1
local name=$(echo "$arn" | awk -F/ '{print $NF}')
# 클러스터 레벨 CPUUtilization (EC2 launch type)
local cluster_dp=$(aws cloudwatch get-metric-statistics \
--profile $PROFILE --region $REGION \
--namespace AWS/ECS --metric-name CPUUtilization \
--dimensions Name=ClusterName,Value="$name" \
--start-time "$START" --end-time "$END" \
--period 86400 --statistics Maximum \
--query 'length(Datapoints)' --output text 2>/dev/null)
# Fargate 등 서비스 레벨 메트릭이 따로 있는 경우 보강
local svc_dp=0
if [ "$cluster_dp" = "0" ] || [ -z "$cluster_dp" ]; then
local services=$(aws cloudwatch list-metrics \
--profile $PROFILE --region $REGION \
--namespace AWS/ECS --metric-name CPUUtilization \
--dimensions Name=ClusterName,Value="$name" \
--query 'Metrics[?length(Dimensions)==`2`].Dimensions[?Name==`ServiceName`].Value' \
--output text 2>/dev/null | tr '\t' '\n' | sort -u)
for svc in $services; do
[ -z "$svc" ] && continue
local dp=$(aws cloudwatch get-metric-statistics \
--profile $PROFILE --region $REGION \
--namespace AWS/ECS --metric-name CPUUtilization \
--dimensions Name=ClusterName,Value="$name" Name=ServiceName,Value="$svc" \
--start-time "$START" --end-time "$END" \
--period 86400 --statistics Maximum \
--query 'length(Datapoints)' --output text 2>/dev/null)
if [ -n "$dp" ] && [ "$dp" != "0" ]; then
svc_dp=$((svc_dp + dp))
break
fi
done
fi
local total=$((${cluster_dp:-0} + svc_dp))
if [ "$total" -gt 0 ]; then
echo "USED|$name|cluster_dp=${cluster_dp:-0}|svc_dp=$svc_dp"
else
echo "IDLE|$name|cluster_dp=0|svc_dp=0"
fi
}
export -f check_cluster
export PROFILE REGION START END
aws ecs list-clusters --profile $PROFILE --region $REGION \
--query 'clusterArns[]' --output text | tr '\t' '\n' | \
xargs -P 10 -I{} bash -c 'check_cluster "$@"' _ {}
2.3 (선택) 교차검증¶
ContainerInsights, CPUReservation, 그리고 현재 상태로 결과를 재확인:
# ContainerInsights RunningTaskCount (활성화돼 있을 때만 데이터 존재)
aws cloudwatch get-metric-statistics \
--profile reco-kyle --region us-east-1 \
--namespace ECS/ContainerInsights --metric-name RunningTaskCount \
--dimensions Name=ClusterName,Value="$NAME" \
--start-time "$START" --end-time "$END" \
--period 86400 --statistics Maximum
# 현재 클러스터 스냅샷
aws ecs describe-clusters --profile reco-kyle --region us-east-1 \
--clusters "$NAME" \
--query 'clusters[0].[runningTasksCount,pendingTasksCount,activeServicesCount,registeredContainerInstancesCount]'
# 서비스 이벤트 중 실제 활동 메시지가 있는지 보기
aws ecs describe-services --profile reco-kyle --region us-east-1 \
--cluster "$NAME" --services "$SVC" \
--query 'services[0].events[0:10].[createdAt,message]' --output table
이벤트 내용으로 한 번 더 거르기
서비스 이벤트가 "started 1 tasks", "stopped N tasks", "unable to place a task" 같이 상태 변화 메시지면 활동 신호, "has reached a steady state."만 반복되면 노이즈로 간주한다.
3. 검증¶
이 절차에서 확인해야 할 출력:
USED|...라인의 클러스터 이름 목록 = 지난 7일 사용된 클러스터- 의심 가는 클러스터는 직접
CPUUtilization값까지 조회해 0이 아닌 Maximum이 있었는지 확인:
aws cloudwatch get-metric-statistics \
--profile reco-kyle --region us-east-1 \
--namespace AWS/ECS --metric-name CPUUtilization \
--dimensions Name=ClusterName,Value=compositet3-prod-240531-cluster \
--start-time "$START" --end-time "$END" \
--period 86400 --statistics Maximum Average
본 작업 결과: compositet3-prod-240531-cluster만 7일 모두 데이터포인트 존재,
Maximum CPU ~26%까지 관측됨.
4. 함정과 노하우¶
get-metric-statistics --period 86400은 86400초(1일) 단위로 집계한다. 더 짧은 활동(예: 30분짜리 잡)도 잡고 싶다면--period 3600(1시간)을 쓰고 datapoint 개수 대신 Sum/Maximum 값을 본다.- 서비스 이벤트 개수는 활동 신호가 아니다. ECS는 desired=0인 서비스에도
~6시간 주기로
steady state이벤트를 남긴다. 7일이면 ~28개 + 다른 자동 이벤트로 90~100개가 흔하게 쌓인다. - Fargate-only 서비스는 클러스터 디멘션 단독
CPUUtilization이 안 찍힐 수 있다.ClusterName + ServiceName디멘션 메트릭까지 함께 보아야 한다. - Container Insights는 클러스터마다 켜져 있지 않을 수 있다.
ECS/ContainerInsights네임스페이스에 데이터가 없다고 "사용 안 됨"으로 단정하면 안 된다.
5. 롤백¶
이 작업은 읽기 전용 감사라 롤백이 필요 없다.