셋업 + 오프닝
오늘 여러분은 낭비가 심어진 실제 EKS 클러스터를 read-only로 분석하며, 상용 비용 도구의 "두뇌"를 자연어로 직접 만듭니다.
0.1 준비물 체크
- 노트북 (관리자 권한, 외부 네트워크 접속 가능)
- 배포 킷에서 받은 것: 참가자 Role ARN, Kiro 테스트 계정,
mcp.json스니펫 - 터미널 도구:
awsCLI v2,kubectl, (선택)jq
curl -fsSL https://cli.kiro.dev/install | bash kiro-cli login # 배포 킷의 테스트 계정으로 로그인
예상 결과
Logged in 메시지. kiro-cli --version으로 2.x 확인.aws configure # 배포 킷의 액세스 키 입력 (리전: ap-northeast-2) aws eks update-kubeconfig --name cost-workshop --region ap-northeast-2 \ --role-arn <배포 킷의 WorkshopParticipant Role ARN> kubectl get nodes
예상 결과
kubectl delete는 Forbidden — 여러분은 오늘 진단만 합니다.0.2 3계층 낭비 모델 — 오늘의 지도
CAST AI·Kubecost·Karpenter를 분해하면, 생태계 전체가 같은 3계층 낭비를 다른 방식으로 다룹니다. 오늘의 모든 실습이 이 지도를 따라갑니다.
| 계층 | 낭비 | 핵심 신호 | 여러분 스킬이 구현할 계산 |
|---|---|---|---|
| L1 Over-provisioning | 요청 ≫ 실사용 | p95 사용량 vs requests | 권장 request = p95 ÷ 0.7 (KRR 방식) |
| L2 Bin-packing slack | 노드에 남는 미요청 용량 | 노드별 요청합 ÷ allocatable | "이 노드 파드들이 다른 노드에 다 들어가나?" 시뮬레이션 |
| L3 용량 단가 | 온디맨드 x86 정가 | Spot 히스토리, arm64 대안 | Pricing API × 시나리오 절감액 |
| L4 숨은 낭비 | 버려진 리소스 | 트래픽 0, 고아 EBS, gp2, 24/7 dev | 각각 CLI 한 줄 — 미션 워밍업 |
kubectl get nodes에 8대가 보인다- Kiro CLI 로그인 완료
- 3계층 모델에서 L1과 L2의 차이를 설명할 수 있다 (L1: 파드가 과하게 예약 / L2: 노드에 예약조차 안 된 빈 공간)
Kiro CLI 부트캠프
45분 안에 오늘 쓸 무기를 전부 장전합니다: 셸 실행, 스킬, 컨텍스트, MCP.
0.5.1 셸 실행과 권한 — read-only 안전 운영
kiro-cli > !kubectl get nodes > /tools
예상 결과
! 접두어는 셸 직접 실행. /tools에서 도구별 권한 상태가 보입니다. /tools trust로 read-only 커맨드를 신뢰 목록에 올리면 매번 승인하지 않아도 됩니다.toolsSettings.allowedCommands에 kubectl get *, kubectl top *만 등록하면 "읽기만 허용되는 에이전트"를 만들 수 있습니다. 오늘 클러스터는 IAM 수준에서도 read-only라 이중 안전장치입니다.0.5.2 첫 스킬 — Hello World
스킬 = .kiro/skills/<이름>/SKILL.md 파일 하나. frontmatter의 description이 자동 발동 트리거라 구체적으로 쓰는 게 핵심이고, 슬래시 이름(/cluster-hello)은 디렉토리명에서 옵니다. 오늘은 이 파일을 직접 손으로 쓰지 않습니다 — Kiro에게 자연어로 "이런 스킬을 만들어줘"라고 요청하면 Kiro가 SKILL.md를 생성합니다. 그게 이 워크샵의 핵심입니다.
kiro-cli > .kiro/skills/cluster-hello 에 스킬을 하나 만들어줘. 이 클러스터의 노드 수 · 네임스페이스 수 · 총 파드 수를 각각 kubectl로 세서 "노드 N대, 네임스페이스 M개, 파드 P개" 한 줄로 답하는 스킬이야. description은 "클러스터를 한 줄로 요약해달라고 하면 사용"으로 써줘. # Kiro가 SKILL.md를 만들면 열어서 확인 → 그 다음 발동: > /cluster-hello # 또는 그냥 "클러스터 요약해줘"
예상 결과
.kiro/skills/cluster-hello/SKILL.md를 생성합니다(fs_write 승인 한 번). 만들어진 파일을 열어보면 frontmatter 2줄 + 단계별 지시로 구조화돼 있습니다 — "내가 요구사항을 말하면 Kiro가 스킬로 구현"하는 흐름을 여기서 처음 경험합니다. 발동하면 "노드 8대, 네임스페이스 9개, 파드 40여 개" 같은 한 줄 요약. 슬래시(/cluster-hello)·자연어 매칭 둘 다 동작합니다.0.5.3 컨텍스트 관리
> /context show # 현재 토큰 사용량 > /compact # 대화 압축 — 긴 분석 세션 중간에 사용
0.5.4 MCP 2종 연결
kiro-cli mcp add --name aws-docs --command uvx --args "awslabs.aws-documentation-mcp-server@latest" # context7은 본인 무료 키 필요 (아래 함정 카드) — 배포 킷 mcp.json 참고 kiro-cli mcp add --name context7 --command npx \ --args "-y,@upstash/context7-mcp" --env "CONTEXT7_API_KEY=<본인키>" kiro-cli > EKS extended support 요금이 표준 지원과 얼마나 다른지 AWS 문서에서 찾아줘
예상 결과
context7.com/dashboard에서 카드 없이 가입 → 키는 IP가 아니라 키 단위 한도라 서로 간섭하지 않습니다./help를 먼저 확인하세요. 2.12.0에는 v3 엔진이 내장돼 있지만 기본은 v2라 kiro-cli로 그냥 실행하면 교재대로 동작합니다 (--v3는 오늘 쓰지 마세요 — 5.5에서 소개). 헤드리스 파이프(--no-interactive)는 유료 티어 전용이라 오늘은 진행자 데모로만 봅니다.!kubectl과/tools trust를 사용했다/cluster-hello스킬이 발동된다- MCP 2종이
kiro-cli mcp list에 보인다
자연어 클러스터 탐험
스킬을 만들기 전에, 먼저 이 클러스터에 얼마가 들어가고 있는지 못 박고 시작합니다. 모든 절감액은 이 숫자의 몇 %입니다.
1.1 베이스라인 — 이 클러스터는 매달 얼마인가
이 클러스터의 노드 인스턴스 타입과 대수를 확인하고, AWS Pricing API로 서울 리전 온디맨드 단가를 조회해서 월 예상 비용을 계산해줘. 노드 외에 NAT Gateway, EBS 볼륨도 있으면 포함해줘. 주의: 계정 전체 말고 이 클러스터의 VPC와 클러스터 태그가 붙은 리소스만 집계해줘.
💭 먼저 직접 예측해보고 → 클릭해서 비교
1.2 탐험 프롬프트 시퀀스
아래 프롬프트를 순서대로 넣고, 결과에서 이상한 것을 최소 3개 메모하세요. 그것이 오후 미션의 표적입니다.
노드별 CPU/메모리 사용률을 보여줘. kubectl top nodes 결과와
각 노드의 allocatable 대비 requests 합계를 표로 정리해줘.
kubectl top이 안 되면 Prometheus로 대체해줘 (예: node CPU
100 - avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m]))*100).💭 먼저 직접 예측해보고 → 클릭해서 비교
Prometheus에 물어봐서 (localhost:9090 port-forward 되어 있음)
지난 7일 기준 워크로드별 CPU p95 사용량과 requests를 비교해줘.
갭이 큰 순서로 표를 만들어줘. 쿼리:
quantile_over_time(0.95, rate(container_cpu_usage_seconds_total{container!=""}[15m])[7d:5m])
주의 1: rate 창은 15m 이상 (수집 간격보다 넉넉하게 — 5m이면 히스토리가 비어 보임)
주의 2: 7일 창에는 재시작된 옛 파드 시리즈도 포함되니
워크로드(Deployment) 단위로 레플리카별 샘플을 전부 풀링해 p95를 구하고
현재 replicas와 비교해줘.💭 먼저 직접 예측해보고 → 클릭해서 비교
payment-api가 압도적 1위(요청 1000m vs 7일 p95 ~130m, ×6 replicas). search-worker, user-svc가 뒤를 잇습니다. 지난 7일 히스토리가 조회되는 것에 주목 — 백분위수 계산이 가능한 이유입니다. 시리즈 수 ≠ 파드 수인 것도 확인해보세요 (OOM 재시작 흔적).store-front 네임스페이스에서 최근 재시작이 많은 파드와 그 이유를 찾아줘. OOMKilled가 있는지 (kube_pod_container_status_last_terminated_reason), CPU 스로틀링이 심한 파드가 있는지도 확인해줘: rate(container_cpu_cfs_throttled_periods_total[5m]) / rate(container_cpu_cfs_periods_total[5m]) > 0.1
💭 먼저 직접 예측해보고 → 클릭해서 비교
checkout-worker가 OOMKilled 반복, report-gen이 스로틀링 50%+ — 이 둘은 "줄이면 안 되고 늘려야 하는" 워크로드입니다. 오후 함정의 복선.- 월 베이스라인 비용($)을 계산해 적어뒀다
- requests ≫ 실사용 워크로드를 3개 이상 찾았다
- OOMKill·스로틀링 파드를 각각 1개 찾았다
스킬 v1 — L1 라이트사이징
아침에 손으로 한 분석을 스킬로 굳힙니다. KRR이 하는 계산 그대로: 권장 request = p95 ÷ 0.7.
2.1 공식
2.2 스킬 작성
아래 요구사항을 Kiro에게 그대로 말해 rightsize 스킬을 만들게 하세요. Kiro가 .kiro/skills/rightsize/SKILL.md를 생성하면 열어서 공식·게이트가 제대로 들어갔는지 검토합니다 — 안 맞으면 "게이트 조건 빠졌어, 추가해줘"처럼 대화로 고치면 됩니다.
kiro-cli
> .kiro/skills/rightsize 에 EKS 워크로드 라이트사이징 스킬을 만들어줘.
description은 "request 대비 실사용 갭 분석·권장 request·월 절감액 산출을 요청하면 사용".
스킬이 따라야 할 절차는 이렇게 명시해줘:
1) Prometheus(localhost:9090)에서 워크로드별 7일 CPU p95 —
quantile_over_time(0.95, rate(container_cpu_usage_seconds_total{container!=""}[15m])[7d:5m])
rate 창은 반드시 15m (5m은 백필 간격과 같아 빈 결과). 워크로드 단위로 샘플 풀링해 p95.
메모리는 max_over_time(container_memory_working_set_bytes{container!=""}[7d])
2) kube_pod_container_resource_requests 와 비교해 갭 계산
3) 신뢰성 게이트 — 다음은 축소 대상에서 빼고 "늘려야 함"으로 분리:
· last_terminated_reason=OOMKilled 존재 · CPU 스로틀 비율 > 0.1
4) 권장 request = CPU p95 ÷ 0.7, 메모리 max × 1.1 (반올림)
5) 절감액 = Σ(현재−권장) × replicas × 단가 × 730h
(단가는 Pricing API의 m5.xlarge 서울 온디맨드에서 vCPU/GiB 비율로 유도)
6) 결과는 워크로드별 표(현재/권장/월 절감액) + 늘려야 할 목록 + kubectl patch 예시
# 생성된 SKILL.md를 열어 6단계와 게이트가 다 들어갔는지 확인expected-skills/rightsize/SKILL.md(예상 형태 — 정답 아님)와 비교해 보완하세요.> /rightsize # 또는: store-front 네임스페이스 라이트사이징 분석해줘
💭 먼저 직접 예측해보고 → 클릭해서 비교
payment-api 권장 CPU ≈ 185m (7일 p95 ~130m ÷ 0.7), 현재 1000m → 워크로드 하나로 ~4.9 vCPU 절감. checkout-worker·report-gen은 "늘려야 함" 쪽에 있어야 정답.checkout-worker는 request가 이미 과소(128Mi)라 주기적으로 OOMKilled 됩니다. 사용량 그래프만 보면 "메모리 여유"로 오판하기 쉽습니다 — 죽기 직전 순간만 높기 때문. 사용량이 낮다 ≠ 줄여도 된다. 종료 이유(last_terminated_reason)를 반드시 함께 봐야 합니다. 이 워크로드를 "줄여라"라고 리포트하면 감점입니다.- /rightsize가 표 + 절감액 + 제외 목록을 출력한다
- payment-api 권장값이 100~200m 범위다
- checkout-worker, report-gen이 축소 목록에 없다
스킬 v2 — L2 통합 · L3 단가
L1이 파드 단위 절약이라면, L2·L3는 노드 단위 절약 — 금액이 큰 쪽입니다.
3.1 Bin-packing — "8대가 5대면 된다"를 증명하기
kiro-cli
> .kiro/skills/consolidate 에 EKS 노드 통합 시뮬레이션 스킬을 만들어줘.
description은 "노드 감축 가능 대수·차단 요소(PDB·do-not-disrupt)·월 절감액을 요청하면 사용".
절차:
1) 노드별 allocatable과 파드 requests 합계 수집 (kubectl describe nodes 또는 KSM)
2) First-Fit 시뮬레이션 — requests 합이 낮은 노드부터, 그 파드들이 다른 노드
남은 공간(allocatable − requests합)에 전부 들어가는지 검사.
DaemonSet 제외, kube-system은 이주 불가로 취급
3) 차단 요소 검사 (있으면 그 노드는 못 비움):
· PDB maxUnavailable:0 또는 minAvailable=replicas · do-not-disrupt=true 어노테이션
4) 결과: "N대 → M대 가능" + 차단 요소 목록·해결안(PDB 완화 YAML)
+ 절감액 = 감축 대수 × 노드 시간 단가 × 730h
# 생성 후 열어서 확인 → 발동:
> /consolidate # 또는 "노드 몇 대까지 줄일 수 있어?"💭 먼저 직접 예측해보고 → 클릭해서 비교
payment-api-pdb(maxUnavailable: 0)와 pinned-job(do-not-disrupt). 라이트사이징(v1) 이후에 통합하면 더 줄어든다는 관찰이 나오면 상위권.maxUnavailable: 0은 노드 drain을 영원히 막습니다. 차단 요소 언급 없이 "3대 끄면 됩니다"라고 쓴 리포트는 실무에서 사고가 됩니다 — 채점에서도 감점.3.2 노드 다운사이징 — "대수" 말고 "크기"를 줄이기
3.1은 노드 대수를 줄였습니다(8→5). 그런데 L1 라이트사이징으로 파드 request 총합이 내려가면, 선택지가 하나 더 열립니다 — 노드를 덜 쓰는 게 아니라 작게 쓰기. 예: m5.xlarge(4 vCPU) 대신 m5.large(2 vCPU)로 갈아타면, 같은 파드를 더 많은·더 작은 노드에 담게 됩니다. 이미 Graviton으로 전환한 조직(예: SmartThings IoT)이 흔히 다음으로 검토하는 레버가 바로 이것입니다.
고객이 자주 묻는 질문 — "노드를 절반 크기로 줄이면 얼마 아껴?" — 을 스킬로 답하게 합니다. 대수 감축(3.1)과 같은 절감인지, 더 큰지/작은지를 시뮬레이션으로 비교하는 게 핵심입니다.
kiro-cli
> .kiro/skills/nodesize 에 EKS 노드 다운사이징 시뮬레이션 스킬을 만들어줘.
description은 "노드 인스턴스 크기를 줄였을 때(예: xlarge→large) 필요 대수·
스케줄링 제약·월 절감액을 요청하면 사용".
절차:
1) 현재 노드의 allocatable(vCPU/메모리)과 전체 파드 requests 합계 수집.
라이트사이징을 이미 적용했다면 권장 request 기준으로도 한 번 더 계산.
2) 후보 인스턴스(현재의 1/2 크기)의 allocatable을 Pricing/스펙에서 확인 —
주의: allocatable ≠ 물리 스펙. kube-reserved·system-reserved·eviction 여유가
빠지므로 작은 노드일수록 사용 가능 비율이 더 낮다.
3) 필요 대수 = ceil(요청총합 / 후보 노드 allocatable), 단 아래 제약 검사:
· 단일 파드의 최대 request > 후보 노드 allocatable 이면 그 노드는 불가 (스케줄 실패)
· maxPods/ENI 한도 — 작은 노드는 파드 밀도 상한이 낮다
· DaemonSet 고정비 — 노드가 늘면 DaemonSet 사본도 늘어 오버헤드 비율↑
4) 절감액 = (현재 대수×현재 단가 − 필요 대수×후보 단가) × 730h.
단가는 Pricing API에서 조회. Graviton(m6g)이면 m6g.xlarge/m6g.large로 조회.
5) 결과: "xlarge N대 → large M대" + 스케줄 불가 파드 목록 + 대수감축(3.1)과의 비교 표
# 생성 후 열어서 확인 → 발동:
> /nodesize # 또는 "노드를 절반 크기로 줄이면 얼마 아껴?"예상 결과
m5.xlarge×8(요청합 ~19.9 vCPU)을 m5.large(2 vCPU, allocatable ~1.7)로 바꾸면 단순히는 ~12대(월 ~$1,034)가 필요해 절감이 ~$344(25%)에 그칩니다 — 통합($517)보다 못합니다. 하지만 L1 라이트사이징 후(요청합 ~11 vCPU) 기준이면 large ~7대로 내려가고, payment-api처럼 큰 단일 request가 없으면 large에 잘 담깁니다. 정답의 방향: "크기 축소는 라이트사이징(L1)과 통합(3.1) 이후에 얹어야 의미가 있다"는 관찰이 나오면 상위권. 고객이 이미 Graviton이면 m6g 단가로 계산해 대수 감축과 중복이 아닌 순 절감을 분리해 제시합니다.payment-api(1000m)는 large allocatable(~1.7 vCPU)의 60%를 혼자 먹어 노드 하나를 사실상 독점(+DaemonSet). 여러 개를 못 얹으니 빈패킹 밀도가 급락해 대수가 폭증합니다. request가 큰 워크로드가 있으면 아예 스케줄이 실패할 수도 있습니다. ③ DaemonSet 세금 — 노드 수가 2배면 로깅·모니터링 DaemonSet 사본도 2배라 고정비가 늘어납니다. 고객에게 "절반 아낀다"고 답하면 실측에서 어긋나 신뢰를 잃습니다 — 반드시 시뮬레이션으로 실제 대수를 구하세요.3.3 용량 단가 — 같은 용량을 더 싸게
이 클러스터 노드(m5.xlarge, 서울)를 기준으로: 1. aws ec2 describe-spot-price-history로 최근 Spot 가격을 조회하고 2. Pricing API로 m6g.large(Graviton) 온디맨드 단가를 조회해서 3. [현재 온디맨드 / Spot 전환 / Graviton 전환 / Spot+Graviton] 4개 시나리오의 월 비용을 표로 비교해줘. 통합 후 5대 기준으로도 계산해줘.
💭 먼저 직접 예측해보고 → 클릭해서 비교
docker manifest inspect) 확인하는 답변이 나오면 보너스.- /consolidate가 "8→5" + 차단 요소 2개를 찾는다
- /nodesize가 "크기 축소"를 시뮬레이션하고, 대수 감축(3.1)과 겹치는 부분을 구분한다
- "절반 크기 = 절반 비용"이 왜 틀린지 3가지 이유를 댈 수 있다
- Spot/Graviton 4-시나리오 표를 만들었다
- 모든 절감액이 챕터 1의 베이스라인 대비 %로도 표현된다
미션 — 나만의 스킬 완성
지금까지 만든 조각을 하나의 스킬로 합쳐, 실행 한 번에 Available Savings Report를 생성합니다.
여러분의 스킬이 실행 한 번으로 아래 리포트를 HTML 대시보드로 만들고(차트 포함), YAML 패치 파일들을 함께 생성해야 합니다. 아래는 완성된 스킬이 뽑는 예시 산출물입니다 — 오늘의 목표점입니다:
📊 예시 리포트 열기 (sample-report.html) →
| 섹션 | 내용 | 재료 |
|---|---|---|
| 📋 Summary | 총 월 절감액 $X (~Y%) + 안전한 적용 순서 | 챕터 1 베이스라인 |
| 1️⃣ 효율 진단 | Provisioned/Requested/Used 3단계 + 업계 벤치마크 대비 | 탐험 1-2 |
| 2️⃣ 라이트사이징 | p95 기반 권장값 표 + 월 절감액 | 스킬 v1 |
| 3️⃣ ⚠️ 신뢰성 | OOMKill·스로틀링 → "늘려야 할 것" 목록 | 스킬 v1 게이트 |
| 4️⃣ Consolidation | 8→5 시뮬레이션 + 차단 요소 | 스킬 v2 (3.1) |
| 5️⃣ 노드 다운사이징 | 크기 축소(xlarge→large) 시뮬 + 대수감축과 순 절감 분리 | 실습 3-2 (nodesize) |
| 6️⃣ 단가 시나리오 | Spot/Graviton 전환별 절감액 | 실습 3-3 |
| 7️⃣ 네트워크 | 크로스-AZ chatty pair + NAT 경유 낭비 | 실습 4-1 (아래) |
| 8️⃣ 숨은 낭비 | abandoned·고아 EBS·gp2·Unbound PV·24/7 dev + 컨트롤플레인 버전 리스크(미래비용) | 워밍업 (아래) + 4.3 |
kiro-cli
> 지금까지 만든 rightsize·consolidate 스킬과 L4 스캔 결과를 종합해서
Available Savings Report를 report.html 한 파일로 만들어줘. 요구사항:
· 맨 위에 KPI 4개(베이스라인 월 비용 / 즉시 절감액 / 식별 항목 수 / 축소금지 수)
· 섹션: 요약·L1 라이트사이징·신뢰성·L2 통합·노드 다운사이징·단가·NET·숨은낭비·적용순서·YAML패치
· 차트는 인라인 SVG나 CDN 없이 동작하는 방식으로 (베이스라인 도넛, L1 현재vs실사용 막대,
노드 통합 바, 다운사이징 대수 비교, L3 시나리오 막대)
· 절감액은 전부 베이스라인 대비 %도 함께
· L1/L2/노드다운사이징은 서로 겹치니 "적용 순서" 섹션에서 순 절감액을 따로 명시
(라이트사이징 → 통합 또는 다운사이징 중 택1 → 단가, 순서를 명확히)
· 함정 2종(OOMKill·스로틀)은 빨간 카드로 "늘려라"로 표시
그리고 patches/ 폴더에 kubectl patch용 YAML도 같이 만들어줘.예상 결과
4.1 네트워크 — 크로스-AZ "chatty pair" 찾기
노드·파드 낭비 말고 트래픽 낭비도 있습니다. 서로 다른 AZ에 떨어진 두 서비스가 계속 통신하면 cross-AZ 요금($0.01/GB, 양방향)이 붙습니다. 이 클러스터엔 이미 X-Ray 서비스맵이 구축돼 있으니, 서비스맵 + 파드 zone을 겹쳐 봅니다.
store-front 네임스페이스에서 서로 통신량이 많은 파드 쌍을 찾고,
그 두 파드가 같은 AZ에 있는지 다른 AZ에 있는지 비교해줘.
1. Prometheus로 파드별 네트워크 송수신 rate 확인:
sum by (pod)(rate(container_network_transmit_bytes_total{namespace="store-front"}[15m]))
2. 트래픽 상위 파드가 어느 노드에 있고, 그 노드의 zone은 뭔지:
kubectl get pod <파드> -o wide → 노드의 topology.kubernetes.io/zone 라벨
3. X-Ray 서비스맵(aws xray get-service-graph)에 양방향 엣지가 있으면 함께 제시
다른 AZ에 걸친 통신이면 cross-AZ 비용($0.01/GB 양방향)과 해결책을 알려줘.💭 먼저 직접 예측해보고 → 클릭해서 비교
chat-a(zone 2a)와 chat-b(zone 2c)가 양방향 ~130KB/s(부하 시 ~776KB/s)로 상호 폴링 — 서로 다른 AZ입니다. X-Ray 서비스맵에도 chat-a↔chat-b 양방향 엣지로 보입니다. 해결: 같은 AZ로 co-locate(podAffinity) 또는 topology aware routing. 소액이지만 "고칠 수 있는 아키텍처 낭비"로 리포트에 넣으면 가점.4.2 워밍업 — 숨은 낭비 5종 (각각 CLI 한 줄)
다음 숨은 낭비를 전부 찾아줘: 1. 네트워크 트래픽이 거의 0인 Deployment (abandoned) — Prometheus rate(container_network_*) 2. 어느 파드에도 연결 안 된 EBS 볼륨 — aws ec2 describe-volumes --filters Name=status,Values=available 3. gp2 타입 볼륨 (gp3 대비 비쌈) 4. Bound 안 된 PV/PVC 5. dev 네임스페이스에서 24/7 도는 워크로드 (off-hours 스케일다운 대상)
💭 먼저 직접 예측해보고 → 클릭해서 비교
legacy-batch(트래픽 0), 고아 EBS, gp2 볼륨, dev 네임스페이스 nginx 3종이 걸립니다. 5종 모두 커버가 필수입니다 — 실무에서 가장 흔하고 가장 쉬운 돈입니다.4.3 컨트롤플레인 버전 리스크 — 지금은 0원, 방치하면 월 $365
지금까지는 노드·파드·스토리지(데이터플레인)의 낭비였습니다. 하나 남은 축이 컨트롤플레인입니다. EKS는 K8s 버전이 표준 지원 기간(GA 후 14개월)을 넘기면 자동으로 Extended Support로 넘어가고, 컨트롤플레인 요금이 $0.10 → $0.60/시간(6배)으로 뜁니다 — 클러스터당 월 +$365. 이건 "이미 새는 돈"이 아니라 "방치하면 새게 될 돈"이라, 진단의 결이 다릅니다.
이 클러스터의 K8s 버전이 표준 지원인지 Extended Support인지, 표준 지원이 언제 끝나는지 확인하고, Extended로 넘어가면 월 비용이 얼마나 더 드는지 계산해줘. 1. 현재 버전: aws eks describe-cluster --name cost-workshop --query cluster.version 2. 버전별 지원 상태·종료일: aws eks describe-cluster-versions (versionStatus = STANDARD_SUPPORT / EXTENDED_SUPPORT / UNSUPPORTED) 3. Extended 요금: 컨트롤플레인 $0.10→$0.60/h (6배) = 클러스터당 월 +$365 → 표준 지원 종료일까지 남은 개월수와 함께 "언제까지 올려야 하나" 제시
💭 먼저 직접 예측해보고 → 클릭해서 비교
STANDARD_SUPPORT — 추가 비용 0원입니다. 핵심은 "표준 지원 종료일"을 확인해 그 전에 업그레이드 계획을 세우는 것. 방치해 Extended로 넘어가면 클러스터당 월 +$365(6배). SmartThings처럼 클러스터가 수십 개면 × 클러스터 수 — "EOL 임박 클러스터 목록"이 곧 리스크 리포트입니다. 진단은 describe-cluster-versions가 실제 종료일을 반환하므로 오늘 바로 됩니다.4.4 채점 기준
| 축 | 배점 | 기준 |
|---|---|---|
| 커버리지 | 40% | 정답지 낭비 항목 중 몇 개를 찾았나 (L4 5종 필수 + 컨트롤플레인 버전 리스크) |
| 정확도 | 30% | 절감액 추정이 정답지 대비 ±30% 이내인가, 베이스라인 % 표기 |
| 신뢰성 | 30% | OOMKill·스로틀링을 "늘려라"로 분류했나, 차단 요소를 명시했나. 줄여라 하면 감점 |
심화 보너스(상위권 변별): CloudWatch 로그 비용 감사, 비용 추이 그래프 생성.
patches/right-size-*.yaml, pdb-fix-*.yaml을 생성하게 하세요 — "월요일에 그대로 PR 올릴 수 있는" 파일이 오늘의 진짜 산출물입니다.발표 + 클로징
팀별 리포트 공유 후, 오늘 만든 것이 실무에서 어디에 서 있는지 확인합니다.
5.1 현장 적용 — 두 개의 실제 질문에 답하기
오늘 만든 스킬은 교보재가 아니라 현장에서 바로 받는 질문에 답하는 도구입니다. 실제로 이런 요청이 들어옵니다 — "Graviton 전환은 이미 많이 했는데, ① 노드를 절반 크기로 줄이면 얼마 아끼나? ② 파드 최적화로는 얼마 아끼나?" 오늘 배운 흐름에 그대로 매핑됩니다:
| 현장 질문 | 오늘의 어느 스킬로 답하나 | 답하는 방식 |
|---|---|---|
| ① 노드 크기 절반화 (예: xlarge→large) | /nodesize (3.2) + /consolidate (3.1) | 요청합을 후보 노드 allocatable로 나눠 실제 필요 대수를 시뮬레이션. "절반 크기≠절반 비용" 3함정을 짚고, 라이트사이징 後 기준으로 순 절감을 제시. 이미 Graviton이면 m6g 단가로 계산. |
| ② 파드 최적화 (Graviton과 별개) | /rightsize (2장) + 신뢰성 게이트 | 7일 p95 ÷ 0.7로 워크로드별 권장 request·절감액. OOMKill·스로틀 워크로드는 "늘려라"로 분리해 안전한 숫자만 제시. |
5.2 오늘 만든 것의 정체
- CAST AI도 read-only 에이전트로 시작합니다 (관찰→분석→제안, 실행은 별도 동의). 여러분의 스킬이 정확히 그 분석 엔진입니다 — 절감액의 15~20% 수수료 없이.
- KRR의 계산(p95 ÷ 목표 사용률)을 오늘 스킬 v1에서 그대로 구현했습니다.
- Karpenter consolidation의 판단(bin-packing 시뮬레이션 + 차단 요소)을 스킬 v2가 합니다.
5.3 월요일에 할 일
- 이 스킬 디렉토리(
.kiro/skills/)를 회사 저장소에 복사 — 클러스터가 바뀌어도 동작합니다 - 실무 클러스터에서는 AWS split cost allocation data를 켜세요 — 파드별 비용이 CUR에 네이티브로 들어옵니다 (오늘 손으로 계산한 배분이 자동화됨)
- Kubecost/OpenCost를 붙이면 오늘 공식들이 대시보드가 됩니다 — 이제 그 숫자가 어떻게 계산되는지 알고 보게 됩니다
5.4 오늘은 시작점 — FinOps 5축 로드맵
비용 최적화는 "한 번 진단하고 끝"이 아닙니다. 성숙한 FinOps는 5개 축을 계속 도는 사이클로 운영합니다. 오늘 만든 스킬은 그중 ①·②의 엔진이고, 나머지 3축은 같은 스킬을 조금씩 확장하면 닿습니다.
| FinOps 축 | 오늘 워크샵 | 확장 방법 (다음 스킬) |
|---|---|---|
| ① 비용 가시성 | ✅ 베이스라인 + 9섹션 진단 리포트 | 완성 — 클러스터가 바뀌어도 재실행 |
| ② 지속적 최적화 | ✅ rightsize·consolidate 스킬 | v3 Hooks로 주기 실행(아래 5.5) → 사람 없이 반복 |
| ③ 예산 관리 | △ 리포트에 예산선 1개 | 팀/네임스페이스별 월 예산을 config로 두고 초과 시 경고 |
| ④ 실시간 예산 대비 | △ 리포트 예산 게이지 | Hook을 CloudWatch 알람/Slack에 연결 — 예산 80% 도달 시 알림 |
| ⑤ AI 미래 예측 | △ 리포트 6개월 추세선 | Prometheus predict_linear 또는 Cost Explorer 예측 API로 "언제 예산 초과" |
5.5 다음 단계 — Kiro CLI v3 (Early Access)
오늘은 v2 엔진으로 스킬을 만들었습니다. 2.12.0에는 이미 v3 엔진이 들어있고(kiro-cli chat --v3로 opt-in, 기본은 v2), 오늘 만든 read-only 분석 스킬을 팀 단위로 자동화·표준화하기 좋은 두 기능이 새로 생겼습니다. 아래는 회사에 돌아가 응용할 거리입니다.
① Agent config — read-only를 파일로 못 박기
v2의 toolsSettings.allowedCommands(실습 B-1 실무 팁에서 본 것)가 v3에선 Markdown + YAML frontmatter 파일로 바뀝니다. .kiro/agents/<이름>.md(워크샵 공유) 또는 ~/.kiro/agents/(개인)에 두고, tools는 read/write/shell/web/@mcp/* 태그로, 권한은 permissions.rules 블록으로 제어합니다. 오늘의 "읽기 전용 진단 에이전트"를 그대로 코드화할 수 있습니다.
# .kiro/agents/cost-readonly.md
---
description: EKS 비용 read-only 진단 에이전트
model: claude-sonnet-4.6
tools: [read, shell, web]
permissions:
rules:
- capability: shell
effect: allow
match: ["kubectl get *", "kubectl top *", "kubectl describe *"]
- capability: shell
effect: deny # deny > ask > allow, 매칭 없으면 기본 ask
match: ["kubectl delete *", "kubectl apply *", "kubectl edit *"]
---
너는 EKS 비용 분석가다. read-only 명령만 쓰고, 9섹션 절감 리포트를 생성한다....md 하나를 저장소에 커밋하면 끝.② Hooks — 진단을 이벤트에 걸어 자동 실행
v3 훅은 .kiro/hooks/<이름>.json 독립 파일입니다. SessionStart, PreToolUse/PostToolUse, UserPromptSubmit, PostFileSave 등 트리거에 걸 수 있고, action은 command(셸 실행, exit 2로 도구 실행 차단 가능) 또는 agent(모델 컨텍스트에 프롬프트 주입 — 정책 강제)입니다.
# .kiro/hooks/guard-readonly.json ← 파괴적 kubectl을 훅으로 한 번 더 차단
{
"version": "v1",
"hooks": [{
"name": "block-mutations",
"trigger": "PreToolUse",
"matcher": "execute_bash",
"action": { "type": "agent",
"prompt": "이 세션은 read-only 진단이다. delete/apply/edit/scale 명령은 거부하고 이유를 설명하라." },
"enabled": true
}]
}SessionStart 훅으로 "세션 시작 시 자동으로 베이스라인 비용 스냅샷을 찍어라"를, command action으로 CI에서 "PR마다 rightsize 스킬을 헤드리스로 돌려 절감 리포트를 코멘트"를 걸 수 있습니다 — 오늘 만든 스킬이 사람 없이도 도는 지점입니다./tools trust·--trust-all-tools·supervised 모드가 제거되고 permissions로 대체됐습니다. Amazon Linux 2 미지원. 스킬(.kiro/skills/) 마이그레이션 가이드는 아직 준비 중이라 오늘 실습은 v2로 하고, v3는 돌아가서 실험해보세요. 상세: kiro.dev/docs/cli/v3/feature-overview- 내 스킬이 9섹션 리포트를 생성한다
- 총 절감액을 베이스라인 대비 %로 말할 수 있다
- "줄이면 안 되는 것"이 뭔지, 왜인지 설명할 수 있다