Chapter 0 · 0:00–0:30

셋업 + 오프닝

오늘 여러분은 낭비가 심어진 실제 EKS 클러스터를 read-only로 분석하며, 상용 비용 도구의 "두뇌"를 자연어로 직접 만듭니다.

업계 평균 클러스터 CPU 사용률
8–13%
CAST AI, 2,100+개 조직 분석
유휴 상태인 컨테이너 지출
83%
Datadog Container Report
상용 도구 수수료
절감액의 15–20%
그 판단 로직은 전부 공개된 수식
오늘 만드는 스킬이 이 수식을 그대로 구현합니다 — 수수료 없이.

0.1 준비물 체크

  • 노트북 (관리자 권한, 외부 네트워크 접속 가능)
  • 배포 킷에서 받은 것: 참가자 Role ARN, Kiro 테스트 계정, mcp.json 스니펫
  • 터미널 도구: aws CLI v2, kubectl, (선택) jq
실습 0-1Kiro CLI 설치 + 로그인
curl -fsSL https://cli.kiro.dev/install | bash
kiro-cli login   # 배포 킷의 테스트 계정으로 로그인
예상 결과
브라우저가 열리고 로그인 후 Logged in 메시지. kiro-cli --version으로 2.x 확인.
실습 0-2클러스터 연결 (read-only Role)
aws configure  # 배포 킷의 액세스 키 입력 (리전: ap-northeast-2)
aws eks update-kubeconfig --name cost-workshop --region ap-northeast-2 \
  --role-arn <배포 킷의 WorkshopParticipant Role ARN>
kubectl get nodes
예상 결과
m5.xlarge 노드 8대가 Ready로 보입니다. kubectl delete는 Forbidden — 여러분은 오늘 진단만 합니다.

0.2 3계층 낭비 모델 — 오늘의 지도

CAST AI·Kubecost·Karpenter를 분해하면, 생태계 전체가 같은 3계층 낭비를 다른 방식으로 다룹니다. 오늘의 모든 실습이 이 지도를 따라갑니다.

Provisioned — 노드가 가진 전체 용량100%
Requested — 파드가 예약한 양 ← L2 bin-packing slack62%
Used — 실제 사용량 ← L1 over-provisioning13%
L3(용량 단가)는 이 전체 스택의 "단가"를 낮추는 축 — Spot / Graviton. L4(숨은 낭비)는 이 그림 밖에 버려진 리소스.
계층낭비핵심 신호여러분 스킬이 구현할 계산
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: 노드에 예약조차 안 된 빈 공간)
Chapter 0.5 · 0:30–1:15

Kiro CLI 부트캠프

45분 안에 오늘 쓸 무기를 전부 장전합니다: 셸 실행, 스킬, 컨텍스트, MCP.

0.5.1 셸 실행과 권한 — read-only 안전 운영

실습 B-1Kiro 안에서 kubectl 실행하기
kiro-cli
> !kubectl get nodes
> /tools
예상 결과
! 접두어는 셸 직접 실행. /tools에서 도구별 권한 상태가 보입니다. /tools trust로 read-only 커맨드를 신뢰 목록에 올리면 매번 승인하지 않아도 됩니다.
💡
실무 팁
agent 설정의 toolsSettings.allowedCommandskubectl get *, kubectl top *만 등록하면 "읽기만 허용되는 에이전트"를 만들 수 있습니다. 오늘 클러스터는 IAM 수준에서도 read-only라 이중 안전장치입니다.

0.5.2 첫 스킬 — Hello World

스킬 = .kiro/skills/<이름>/SKILL.md 파일 하나. frontmatter의 description자동 발동 트리거라 구체적으로 쓰는 게 핵심이고, 슬래시 이름(/cluster-hello)은 디렉토리명에서 옵니다. 오늘은 이 파일을 직접 손으로 쓰지 않습니다 — Kiro에게 자연어로 "이런 스킬을 만들어줘"라고 요청하면 Kiro가 SKILL.md를 생성합니다. 그게 이 워크샵의 핵심입니다.

실습 B-2Warm-up 스킬 만들기 (자연어로)
kiro-cli
> .kiro/skills/cluster-hello 에 스킬을 하나 만들어줘.
  이 클러스터의 노드 수 · 네임스페이스 수 · 총 파드 수를 각각 kubectl로 세서
  "노드 N대, 네임스페이스 M개, 파드 P개" 한 줄로 답하는 스킬이야.
  description은 "클러스터를 한 줄로 요약해달라고 하면 사용"으로 써줘.

# Kiro가 SKILL.md를 만들면 열어서 확인 → 그 다음 발동:
> /cluster-hello              # 또는 그냥 "클러스터 요약해줘"
예상 결과
Kiro가 .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종 연결

실습 B-3AWS Docs MCP + Context7
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 문서에서 찾아줘
예상 결과
aws-docs MCP가 검색 도구를 호출해 extended support가 클러스터 시간당 요금이 큰 폭으로 높다는 문서를 인용합니다. 이렇게 "문서 검증된 답"을 스킬 안에서 요구할 수 있습니다. (이 Extended Support 요금은 4.3에서 실제 진단 항목으로 다시 다룹니다.)
🪤
함정 카드 — Context7 rate limit
Context7은 API 키 없이 쓰면 IP당 월 200요청으로 제한됩니다. 워크샵장은 다들 같은 공유 IP(NAT)로 나가므로, 키 없이 쓰면 10명의 호출이 한 IP 몫(200)을 나눠 쓰다 금방 rate limit에 막힙니다. 각자 무료 키를 발급하세요 — context7.com/dashboard에서 카드 없이 가입 → 키는 IP가 아니라 키 단위 한도라 서로 간섭하지 않습니다.
⚠️
알아두기
Kiro CLI는 주 단위로 릴리즈됩니다. 이 교재의 명령은 2.12.0 기준이며, 동작이 다르면 /help를 먼저 확인하세요. 2.12.0에는 v3 엔진이 내장돼 있지만 기본은 v2kiro-cli로 그냥 실행하면 교재대로 동작합니다 (--v3는 오늘 쓰지 마세요 — 5.5에서 소개). 헤드리스 파이프(--no-interactive)는 유료 티어 전용이라 오늘은 진행자 데모로만 봅니다.
✅ 체크포인트
  • !kubectl/tools trust를 사용했다
  • /cluster-hello 스킬이 발동된다
  • MCP 2종이 kiro-cli mcp list에 보인다
Chapter 1 · 1:15–2:15

자연어 클러스터 탐험

스킬을 만들기 전에, 먼저 이 클러스터에 얼마가 들어가고 있는지 못 박고 시작합니다. 모든 절감액은 이 숫자의 몇 %입니다.

1.1 베이스라인 — 이 클러스터는 매달 얼마인가

탐험 1-1현재 비용 스냅샷
이 클러스터의 노드 인스턴스 타입과 대수를 확인하고, AWS Pricing API로
서울 리전 온디맨드 단가를 조회해서 월 예상 비용을 계산해줘.
노드 외에 NAT Gateway, EBS 볼륨도 있으면 포함해줘.
주의: 계정 전체 말고 이 클러스터의 VPC와 클러스터 태그가 붙은 리소스만 집계해줘.
💭 먼저 직접 예측해보고 → 클릭해서 비교
m5.xlarge 8대 × 서울 온디맨드 단가($0.236) × 730h ≈ 월 $1,378 + NAT/EBS. 이 숫자를 적어두세요 — 오늘 찾을 모든 낭비를 이 분모로 나눠 "몇 %"로 말하게 됩니다.
💡
왜 베이스라인부터?
실무에서 비용 리포트가 설득력을 가지려면 "총 지출 대비 몇 %"가 필요합니다. Cost Explorer가 비어 있는 신규 클러스터에서도 Pricing API × 리소스 목록으로 지금처럼 직접 계산할 수 있습니다 — 이것이 오늘 스킬의 최종 리포트 1번 섹션이 됩니다.

1.2 탐험 프롬프트 시퀀스

아래 프롬프트를 순서대로 넣고, 결과에서 이상한 것을 최소 3개 메모하세요. 그것이 오후 미션의 표적입니다.

탐험 1-2노드 사용률
노드별 CPU/메모리 사용률을 보여줘. kubectl top nodes 결과와
각 노드의 allocatable 대비 requests 합계를 표로 정리해줘.
kubectl top이 안 되면 Prometheus로 대체해줘 (예: node CPU
100 - avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m]))*100).
💭 먼저 직접 예측해보고 → 클릭해서 비교
사용률(Used)은 한 자릿수 %인데 requests 합계는 그보다 훨씬 높은 노드들 — Provisioned ⊃ Requested ⊃ Used 3단계 갭이 눈으로 보입니다.
탐험 1-3요청 대비 실사용 갭
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 재시작 흔적).
탐험 1-4문제 징후 스캔
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개 찾았다
Chapter 2 · 2:15–3:00

스킬 v1 — L1 라이트사이징

아침에 손으로 한 분석을 스킬로 굳힙니다. KRR이 하는 계산 그대로: 권장 request = p95 ÷ 0.7.

2.1 공식

1
p95 수집
7일 사용량 백분위
2
÷ 0.7
목표 사용률 70%
!
함정 검사
OOM·스로틀 제외
3
절감액 $
Δrequest × 단가
4
YAML 패치
월요일에 PR
주황 게이트가 오늘의 채점 포인트 — 신뢰성 검사 없는 라이트사이징은 감점입니다.

2.2 스킬 작성

실습 2-1rightsize 스킬 v1 (자연어로 만들기)

아래 요구사항을 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단계와 게이트가 다 들어갔는지 확인
💡
받아쓰기가 아니라 "설계 지시"
여기서 여러분이 하는 일은 요구사항과 검증 기준을 말로 정의하는 것이고, SKILL.md 파일 작성은 Kiro가 합니다. 실무에서 팀 표준 스킬을 만드는 방식이 정확히 이겁니다 — 규칙을 사람이 정하고, 구현·문서화는 에이전트가. 막히면 배포 킷 expected-skills/rightsize/SKILL.md(예상 형태 — 정답 아님)와 비교해 보완하세요.
실습 2-2실행 + 검증
> /rightsize
# 또는: store-front 네임스페이스 라이트사이징 분석해줘
💭 먼저 직접 예측해보고 → 클릭해서 비교
payment-api 권장 CPU ≈ 185m (7일 p95 ~130m ÷ 0.7), 현재 1000m → 워크로드 하나로 ~4.9 vCPU 절감. checkout-worker·report-gen은 "늘려야 함" 쪽에 있어야 정답.
💬
Kiro에게 판단 근거를 되물어보기
숫자만 받지 말고, 왜 그 값인지를 자연어로 캐물으세요 — 상용 도구도 "왜 이 권장값인가"를 설명하는 게 신뢰의 핵심입니다. 목표 사용률을 70% 대신 85%로 잡으면 권장값과 절감액이 어떻게 달라져? 어느 쪽이 이 워크로드(payment-api)에 더 안전해?
🪤
함정 카드 — OOMKill 워크로드
checkout-worker는 request가 이미 과소(128Mi)라 주기적으로 OOMKilled 됩니다. 사용량 그래프만 보면 "메모리 여유"로 오판하기 쉽습니다 — 죽기 직전 순간만 높기 때문. 사용량이 낮다 ≠ 줄여도 된다. 종료 이유(last_terminated_reason)를 반드시 함께 봐야 합니다. 이 워크로드를 "줄여라"라고 리포트하면 감점입니다.
✅ 체크포인트
  • /rightsize가 표 + 절감액 + 제외 목록을 출력한다
  • payment-api 권장값이 100~200m 범위다
  • checkout-worker, report-gen이 축소 목록에 없다
Chapter 3 · 4:00–5:30

스킬 v2 — L2 통합 · L3 단가

L1이 파드 단위 절약이라면, L2·L3는 노드 단위 절약 — 금액이 큰 쪽입니다.

3.1 Bin-packing — "8대가 5대면 된다"를 증명하기

현재 — 8 노드에 흩어짐
node-1
node-2
node-3
…8
통합 후 — 5 노드로
node-1
node-2
node-7 ✕
node-8 ✕
초록 = 이주한 파드. 빈 노드 3대 = 월 베이스라인의 ~37.5% 절감. 단, 이주를 막는 것들이 있는지 먼저 검사해야 합니다.
실습 3-1consolidate 스킬 (자연어로)
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               # 또는 "노드 몇 대까지 줄일 수 있어?"
💭 먼저 직접 예측해보고 → 클릭해서 비교
"8대 → 5대 가능" + 차단 요소 2개: payment-api-pdb(maxUnavailable: 0)와 pinned-job(do-not-disrupt). 라이트사이징(v1) 이후에 통합하면 더 줄어든다는 관찰이 나오면 상위권.
🪤
함정 카드 — 차단 요소 무시
PDB 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) — 4 vCPU 노드 5대
xlarge4 vCPU
xlarge4 vCPU
크기 축소 (3.2) — 2 vCPU 노드 다수
large2
large2
large2
large2
두 방식은 같은 목표(빈 vCPU 제거)의 다른 손잡이입니다. 작은 노드는 DaemonSet·kubelet 같은 고정 오버헤드 비율이 커지고, 큰 단일 파드가 안 들어갈 수 있습니다. "절반 크기 = 절반 비용"이 아닌 이유입니다.
실습 3-2nodesize 스킬 (자연어로)

고객이 자주 묻는 질문 — "노드를 절반 크기로 줄이면 얼마 아껴?" — 을 스킬로 답하게 합니다. 대수 감축(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 단가로 계산해 대수 감축과 중복이 아닌 순 절감을 분리해 제시합니다.
💬
Kiro에게 판단 근거를 되물어보기
"절반 크기 = 절반 비용"이라는 직관을 그대로 믿지 말고 제약을 캐물으세요 — 고객에게 금액을 제시하기 전에 반드시 넘어야 할 관문입니다. 노드를 xlarge에서 large로 절반으로 줄이면, 스케줄링에 어떤 제약이 새로 생겨? DaemonSet 오버헤드와 allocatable 여유를 감안하면 실제 절감은 이론치의 몇 %쯤이야? 대수를 줄이는 것(3.1)과 겹치는 부분은 어디야?
🪤
함정 카드 — "절반 크기 = 절반 비용" 착각
노드를 절반 크기로 줄여도 절감이 절반이 안 되는 3가지 이유: ① allocatable 여유 — kube/system-reserved·eviction threshold는 노드마다 고정이라 작은 노드일수록 비율이 커집니다(large는 xlarge의 절반보다 적게 쓸 수 있는 vCPU). ② 단일 파드 벽 — 라이트사이징 전 payment-api(1000m)는 large allocatable(~1.7 vCPU)의 60%를 혼자 먹어 노드 하나를 사실상 독점(+DaemonSet). 여러 개를 못 얹으니 빈패킹 밀도가 급락해 대수가 폭증합니다. request가 큰 워크로드가 있으면 아예 스케줄이 실패할 수도 있습니다. ③ DaemonSet 세금 — 노드 수가 2배면 로깅·모니터링 DaemonSet 사본도 2배라 고정비가 늘어납니다. 고객에게 "절반 아낀다"고 답하면 실측에서 어긋나 신뢰를 잃습니다 — 반드시 시뮬레이션으로 실제 대수를 구하세요.

3.3 용량 단가 — 같은 용량을 더 싸게

실습 3-3Spot / Graviton 시나리오
이 클러스터 노드(m5.xlarge, 서울)를 기준으로:
1. aws ec2 describe-spot-price-history로 최근 Spot 가격을 조회하고
2. Pricing API로 m6g.large(Graviton) 온디맨드 단가를 조회해서
3. [현재 온디맨드 / Spot 전환 / Graviton 전환 / Spot+Graviton] 4개 시나리오의
   월 비용을 표로 비교해줘. 통합 후 5대 기준으로도 계산해줘.
💭 먼저 직접 예측해보고 → 클릭해서 비교
Spot ~60-70% 할인, Graviton ~20% 할인이 관측됩니다. "5대 × Spot+Graviton"이 최저가 시나리오. 워크로드 이미지가 multi-arch인지(docker manifest inspect) 확인하는 답변이 나오면 보너스.
💬
Kiro에게 판단 근거를 되물어보기
시나리오 표를 받은 뒤 바로 적용하지 말고 리스크를 캐물으세요 — "어느 게 더 싼가"와 "어느 게 안전한가"는 다른 질문입니다. Spot으로 전환하면 회수(interruption) 위험이 가장 큰 워크로드는 뭐야? PDB 없이 지금 바로 적용하면 어떤 사고가 날 수 있어?
💡
실무 팁
Spot은 "언제든 회수될 수 있는" 용량입니다. 스테이트리스·복제본 많은 워크로드부터 적용하고, PDB(이번엔 올바른 용도!)로 동시 중단을 제한하는 것이 Karpenter의 기본 전략입니다.
✅ 체크포인트
  • /consolidate가 "8→5" + 차단 요소 2개를 찾는다
  • /nodesize가 "크기 축소"를 시뮬레이션하고, 대수 감축(3.1)과 겹치는 부분을 구분한다
  • "절반 크기 = 절반 비용"이 왜 틀린지 3가지 이유를 댈 수 있다
  • Spot/Graviton 4-시나리오 표를 만들었다
  • 모든 절감액이 챕터 1의 베이스라인 대비 %로도 표현된다
Chapter 4 · 5:30–6:30

미션 — 나만의 스킬 완성

지금까지 만든 조각을 하나의 스킬로 합쳐, 실행 한 번에 Available Savings Report를 생성합니다.

🎯 미션: 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️⃣ Consolidation8→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
미션 프롬프트HTML 리포트로 뽑기
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도 같이 만들어줘.
예상 결과
sample-report.html 같은 대시보드가 생성됩니다 — KPI 타일 + 9섹션 + 차트 5개 + 함정 빨간 카드 + YAML 패치. 이게 팀 발표 자료이자 "월요일에 그대로 PR 올릴" 산출물입니다. 스킬 하나가 진단→계산→시각화→패치 생성까지 한 번에 하는 것이 오늘의 도착점입니다.
💬
Kiro에게 판단 근거를 되물어보기
리포트가 나오면 그대로 발표하지 말고 팀장이 물어볼 질문을 먼저 던져보세요 — 숫자 뒤의 "왜"를 설명 못 하면 발표에서 막힙니다. 이 8개 항목 중에 가장 리스크가 낮으면서 절감액이 큰 것부터 순서를 다시 짜줘. 그리고 왜 그 순서인지 한 줄씩 이유를 붙여줘.

4.1 네트워크 — 크로스-AZ "chatty pair" 찾기

노드·파드 낭비 말고 트래픽 낭비도 있습니다. 서로 다른 AZ에 떨어진 두 서비스가 계속 통신하면 cross-AZ 요금($0.01/GB, 양방향)이 붙습니다. 이 클러스터엔 이미 X-Ray 서비스맵이 구축돼 있으니, 서비스맵 + 파드 zone을 겹쳐 봅니다.

실습 4-1크로스-AZ 트래픽 탐지
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. 소액이지만 "고칠 수 있는 아키텍처 낭비"로 리포트에 넣으면 가점.
💡
왜 X-Ray를 겹쳐 보나
Prometheus 트래픽 rate는 "누가 얼마나 보내는지"는 알려주지만 "누구에게"는 모릅니다. X-Ray 서비스맵이 그 방향(A→B)을 채워줘서, 트래픽 상위 파드가 실제로 서로 통신하는 쌍인지 확인됩니다. 두 신호를 겹쳐야 크로스-AZ 낭비가 확정됩니다.

4.2 워밍업 — 숨은 낭비 5종 (각각 CLI 한 줄)

워밍업L4 스캔 프롬프트
다음 숨은 낭비를 전부 찾아줘:
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
   → 표준 지원 종료일까지 남은 개월수와 함께 "언제까지 올려야 하나" 제시
💭 먼저 직접 예측해보고 → 클릭해서 비교
이 클러스터는 1.31로 지금은 STANDARD_SUPPORT추가 비용 0원입니다. 핵심은 "표준 지원 종료일"을 확인해 그 전에 업그레이드 계획을 세우는 것. 방치해 Extended로 넘어가면 클러스터당 월 +$365(6배). SmartThings처럼 클러스터가 수십 개면 × 클러스터 수 — "EOL 임박 클러스터 목록"이 곧 리스크 리포트입니다. 진단은 describe-cluster-versions가 실제 종료일을 반환하므로 오늘 바로 됩니다.
💡
왜 이게 FinOps인가
비용 최적화는 "지금 새는 돈"만이 아니라 "곧 샐 돈을 막는 것"도 포함합니다. 컨트롤플레인 버전 관리는 보안 패치 측면에서도 해야 하는 일인데, 안 하면 비용 페널티까지 붙는다는 걸 숫자로 보여주면 업그레이드 우선순위를 올리는 강력한 근거가 됩니다. 멀티클러스터 조직에서 특히 큽니다.

4.4 채점 기준

배점기준
커버리지40%정답지 낭비 항목 중 몇 개를 찾았나 (L4 5종 필수 + 컨트롤플레인 버전 리스크)
정확도30%절감액 추정이 정답지 대비 ±30% 이내인가, 베이스라인 % 표기
신뢰성30%OOMKill·스로틀링을 "늘려라"로 분류했나, 차단 요소를 명시했나. 줄여라 하면 감점

심화 보너스(상위권 변별): CloudWatch 로그 비용 감사, 비용 추이 그래프 생성.

💡
아티팩트까지
리포트와 함께 patches/right-size-*.yaml, pdb-fix-*.yaml을 생성하게 하세요 — "월요일에 그대로 PR 올릴 수 있는" 파일이 오늘의 진짜 산출물입니다.
Chapter 5 · 6:30–7:00

발표 + 클로징

팀별 리포트 공유 후, 오늘 만든 것이 실무에서 어디에 서 있는지 확인합니다.

5.1 현장 적용 — 두 개의 실제 질문에 답하기

오늘 만든 스킬은 교보재가 아니라 현장에서 바로 받는 질문에 답하는 도구입니다. 실제로 이런 요청이 들어옵니다 — "Graviton 전환은 이미 많이 했는데, ① 노드를 절반 크기로 줄이면 얼마 아끼나? ② 파드 최적화로는 얼마 아끼나?" 오늘 배운 흐름에 그대로 매핑됩니다:

현장 질문오늘의 어느 스킬로 답하나답하는 방식
① 노드 크기 절반화
(예: xlarge→large)
/nodesize (3.2) + /consolidate (3.1)요청합을 후보 노드 allocatable로 나눠 실제 필요 대수를 시뮬레이션. "절반 크기≠절반 비용" 3함정을 짚고, 라이트사이징 後 기준으로 순 절감을 제시. 이미 Graviton이면 m6g 단가로 계산.
② 파드 최적화
(Graviton과 별개)
/rightsize (2장) + 신뢰성 게이트7일 p95 ÷ 0.7로 워크로드별 권장 request·절감액. OOMKill·스로틀 워크로드는 "늘려라"로 분리해 안전한 숫자만 제시.
⚠️
두 축은 겹칩니다 — 이중 계산 주의
①(노드 크기)과 통합(대수)은 같은 빈 용량을 노리므로 더하면 안 됩니다. 그리고 ②(파드 최적화)를 먼저 해야 ①의 필요 대수가 줄어 진짜 절감이 나옵니다. 고객에게 금액을 제시할 땐 반드시 "적용 순서 + 순 절감"으로 답하세요 — 리포트 8번(적용 순서) 섹션이 그 자리입니다.

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로 "언제 예산 초과"
💡
예시 리포트에서 이미 봤습니다
sample-report.html 상단의 예산 게이지(④)6개월 예측 차트(⑤)가 바로 이 확장의 프리뷰입니다. 오늘은 ①②를 손에 익히고, ③④⑤는 "다음 주 과제"로 가져가세요 — 전부 오늘 만든 스킬에 프롬프트 몇 줄을 더하는 일입니다.
🔁
이게 CAST AI·Kubecost가 파는 것
상용 도구가 월 구독료로 파는 게 정확히 이 5축 사이클입니다. 여러분은 오늘 그 엔진의 핵심(①②)을 직접 만들었고, 데이터 소스(Prometheus·Pricing API·Cost Explorer)도 이미 손에 있습니다. 남은 건 자동화(Hooks)와 알림 연결뿐입니다.

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/(개인)에 두고, toolsread/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섹션 절감 리포트를 생성한다...
💡
왜 좋은가
오늘은 IAM 수준 read-only(이중 안전장치)였지만, 실무 클러스터에선 에이전트 자체가 파괴적 명령을 거부하도록 파일로 박아두면 팀원 누가 쓰든 안전합니다. 이 .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 스킬을 헤드리스로 돌려 절감 리포트를 코멘트"를 걸 수 있습니다 — 오늘 만든 스킬이 사람 없이도 도는 지점입니다.
⚠️
v3는 아직 Early Access
세션 포맷이 v2와 호환되지 않고(v3 세션은 v2에서 못 이어감), /tools trust·--trust-all-tools·supervised 모드가 제거되고 permissions로 대체됐습니다. Amazon Linux 2 미지원. 스킬(.kiro/skills/) 마이그레이션 가이드는 아직 준비 중이라 오늘 실습은 v2로 하고, v3는 돌아가서 실험해보세요. 상세: kiro.dev/docs/cli/v3/feature-overview
✅ 오늘의 최종 체크
  • 내 스킬이 9섹션 리포트를 생성한다
  • 총 절감액을 베이스라인 대비 %로 말할 수 있다
  • "줄이면 안 되는 것"이 뭔지, 왜인지 설명할 수 있다