업그레이드 전략
5부의 마지막 챕터입니다. K8s 마이너 릴리스 (14개월 지원)를 안전하게 따라가는 운영 매뉴얼입니다. 컨트롤 플레인 → 데이터 플레인 (노드) → 애드온의 순서, deprecated API 검출 (pluto · kubent · apiserver 메트릭), 매니페스트 / Helm / Operator CR의 API 버전 마이그레이션, EKS의 노드 그룹 / Karpenter NodePool drift 흐름, 노드 drain의 안전장치 (PDB · terminationGracePeriodSeconds), blast radius 최소화, 롤백 시나리오, RPO / RTO 별 백업 선택, 그리고 업그레이드 전 1주 / 당일 / 후 1주 체크리스트까지 한 사이클로 다룹니다.
5부 (운영 · 디버깅 · 비용)의 마지막 챕터입니다. 27장 kubectl 디버깅 패턴이 사고의 결을, 28장 비용 최적화가 청구서의 결을, 29장 시크릿 운영이 보안의 결을 다뤘다면, 이번 챕터는 시간의 결을 다룹니다. K8s는 분기마다 마이너 버전이 나오고, EKS의 표준 지원 기간은 14개월입니다. 운영 클러스터가 표준 지원 안에 있도록 유지하려면 1년에 최소 한 번의 마이너 업그레이드가 필수 사이클이고, 그 사이클을 안전하게 굴리는 매뉴얼이 본 챕터의 본문입니다.
26장 운영 체크리스트 §“EKS 업그레이드"에서 짧게 짚었던 흐름이 본 챕터에서 본격적으로 전개됩니다. 이번 챕터의 목표는 업그레이드 전 1주 / 당일 / 후 1주 체크리스트가 한 페이지에 들어가고, 분기마다 한 번의 마이너 업그레이드가 사고 없이 돌아가는 운영 모델을 만드는 것입니다.
K8s 릴리스 사이클 — 1년의 시간표 #
K8s 자체의 버전 정책을 다시 짚습니다.
릴리스 주기: 약 4 개월
지원 기간 (upstream): 12 ~ 14 개월
EKS 표준 지원: 14 개월
EKS 확장 지원: 추가 12 개월 (유료)
deprecated 표시: 한 마이너 릴리스 이전
removed 시점: 2 ~ 3 마이너 릴리스 후이 시간표에서 운영 클러스터에 들어오는 신호는 두 가지입니다.
- deprecated 알림 — 한 마이너 릴리스에서 “이 API는 곧 제거됩니다"가 표시됩니다. 보통 2~3 마이너 후 (8~12개월 뒤) 실제 제거됩니다.
- 표준 지원 만료 — EKS 콘솔에 “이 클러스터는 X 개월 후 표준 지원이 만료됩니다"가 표시됩니다. 그 시점부터 새 패치가 들어오지 않고, 확장 지원으로 넘어가면 비용이 가산됩니다.
운영 클러스터에서는 이 두 신호를 분기 캘린더에 미리 잡아 두는 게 표준입니다. deprecated → removed 사이의 8~12개월이 매니페스트를 정리할 수 있는 시간 창입니다. 이 창을 놓치면 새 클러스터에서 매니페스트가 거부되어 다운타임이 발생합니다.
업그레이드 순서의 원칙 #
K8s의 업그레이드는 정해진 순서를 따라야 합니다.
1. 컨트롤 플레인 (control plane) -- API server, controller manager, scheduler, etcd
2. 데이터 플레인 (node) -- kubelet, kube-proxy, container runtime
3. 애드온 -- VPC CNI, CoreDNS, kube-proxy, EBS CSI, Karpenter, ArgoCD, ...이 순서의 이유는 K8s의 호환성 정책입니다.
- kubelet의 버전은 API server의 같은 마이너 ± 1 마이너 안에 있어야 합니다.
- kube-proxy의 버전은 kubelet의 마이너와 같아야 합니다.
- 애드온은 K8s 마이너 버전에 따라 호환 매트릭스가 있습니다.
이 호환성 때문에 컨트롤 플레인 → 데이터 플레인의 순서가 강제됩니다. 컨트롤 플레인을 1.32로 올린 뒤 노드가 1.31 인 상태가 한동안 유지되는 건 정상이지만 (skew 1), 노드를 먼저 1.32로 올리고 컨트롤 플레인이 1.31 인 상태는 안 됩니다.
한 마이너씩 — skip 금지의 이유 #
EKS는 한 마이너씩만 업그레이드 할 수 있습니다. 1.30 → 1.32의 직접 점프는 불가능하고, 1.30 → 1.31 → 1.32의 두 단계를 거쳐야 합니다.
이 제약의 이유는 다음 둘입니다.
- etcd 마이그레이션의 안전성 — 마이너마다 etcd의 데이터 형식이 일부 변할 수 있습니다. 단계별 마이그레이션이 안전합니다.
- API conversion — 각 마이너에서 변환할 수 있는 API 버전이 정해져 있습니다. 두 마이너를 한 번에 건너뛰면 변환이 불가능한 객체가 생길 수 있습니다.
운영 클러스터가 표준 지원 만료에 임박했고 두 마이너 뒤떨어진 상태라면, 두 번의 업그레이드를 한 분기 안에 마쳐야 합니다. 한 번 미루면 다음 분기에 두 배의 작업량이 됩니다.
deprecated API 검출 — 매니페스트와 클러스터 두 곳 #
업그레이드의 가장 큰 위험은 매니페스트에 옛 API가 들어 있는 것입니다. 두 곳을 모두 점검해야 합니다.
1. 매니페스트 — pluto #
pluto detect-files -d charts/ --target-versions k8s=v1.32
pluto detect-helm --target-versions k8s=v1.32charts/의 모든 YAML을 스캔해 1.32에서 deprecated 또는 removed 된 API를 찾습니다. 20장 GitOps의 매니페스트 repo 한 곳만 스캔하면 모든 환경의 deprecated가 한 번에 잡힙니다 — git 단일 소스 모델의 운영 가치 중 하나입니다.
2. 클러스터 — kubent #
kubent --target-version 1.32 --context myshop-prodkubent (kube-no-trouble)는 클러스터의 실제 상태를 점검합니다. 매니페스트는 정리했지만 누가 콘솔에서 직접 만든 객체, 또는 Operator가 생성한 객체에 deprecated가 남아 있을 수 있습니다.
두 도구의 결합으로 “내 매니페스트와 내 클러스터 둘 다에서” deprecated가 사라진 상태가 확보됩니다.
3. apiserver 메트릭 — 마지막 신호 #
apiserver_requested_deprecated_apis이 메트릭이 0이 아니면 누군가 (또는 어떤 컴포넌트가) 지금도 deprecated API를 호출하고 있다는 신호입니다. 25장 모니터링 · 알람의 Prometheus가 이 메트릭을 스크랩하므로, 분기 점검 룰로 추가해 두는 게 표준입니다.
- alert: K8sDeprecatedApisInUse
expr: |
sum(rate(apiserver_requested_deprecated_apis[7d])) > 0
for: 1h
labels:
severity: warning
team: platform
annotations:
summary: "Deprecated K8s API 가 호출되고 있음"
runbook_url: "https://runbooks.myshop.example.com/k8s-deprecated"이 알람이 평소에 잠잠하면 다음 업그레이드의 매니페스트 정리는 거의 끝난 상태입니다.
API 버전 마이그레이션 패턴 #
deprecated가 발견된 객체의 API 버전을 어떻게 옮기는지가 다음 결입니다.
매니페스트 직접 변환 #
kubectl convert -f old.yaml --output-version networking.k8s.io/v1kubectl convert는 K8s 1.14 까지의 빌트인이었고, 이후 별도 플러그인입니다. 자동 변환이 가능한 API는 이 명령으로 한 번에 풀립니다.
Helm 차트의 API 버전 #
Helm 차트의 templates 안에 적힌 API 버전은 차트 자체의 새 릴리스로 풀립니다. 의존 차트 (예: ingress-nginx, cert-manager)가 K8s 1.32를 지원하는 새 버전으로 올라가야 합니다.
helm outdated -n monitoring # 일부 환경의 별도 플러그인
helm list --all-namespaces22장 앱 배포 골격의 myshop-api 차트는 본 책의 표준 매니페스트라 K8s 호환성이 일정 시점까지 보장되지만, 외부 차트 (예: aws-load-balancer-controller, external-secrets, kube-prometheus-stack)는 업그레이드 전에 새 버전이 K8s 1.32를 지원하는지 확인해야 합니다.
Operator CR의 API 버전 #
18장 CRD와 Operator의 CRD 자체에도 버전이 있습니다 (v1alpha1 → v1beta1 → v1). Operator의 새 버전이 CRD의 새 버전을 정의하면, 옛 CR을 새 형식으로 마이그레이션해야 합니다. **conversion webhook**이 그 변환을 자동화하는 도구이지만, 모든 Operator가 이를 구현하지는 않습니다 — 도입한 Operator의 업그레이드 노트를 사전에 확인하는 게 표준입니다.
EKS의 업그레이드 흐름 #
1. 컨트롤 플레인 — Terraform 한 줄 #
module "eks" {
# ...
cluster_version = "1.32" # 1.31 -> 1.32
}terraform apply가 EKS 컨트롤 플레인의 마이너 업그레이드를 트리거합니다. EKS는 컨트롤 플레인을 무중단으로 업그레이드합니다 — 약 30분~1시간 정도 걸립니다. 그 시간 동안 사용자 워크로드는 영향받지 않고 kubectl도 계속 작동합니다.
다만 그 시간 동안 일부 액션이 잠시 멈춥니다 — 새 객체 생성, scale 변경 등의 API 호출이 일시적으로 지연됩니다. prod 컨트롤 플레인 업그레이드 시점에는 의도적으로 배포를 멈추는 게 안전 합니다.
2. 데이터 플레인 — 두 패턴 #
EKS 노드의 업그레이드는 26장에서 두 패턴으로 짚었습니다 — in-place rolling과 blue-green입니다.
Managed Node Group의 in-place는 EKS가 자동으로 다음 사이클을 돕니다.
1. 새 launch template (새 AMI) 생성
2. ASG 의 desired capacity + 1 -> 새 노드 한 대 join
3. 옛 노드 한 대 cordon -> drain (Pod 이전)
4. 옛 노드 ASG 에서 제거
5. 다음 노드로 반복이 사이클이 노드 수 × 5~10분 정도 걸립니다. 10 노드 클러스터의 한 번의 노드 그룹 업그레이드가 1시간~1시간 반 정도입니다.
Karpenter NodePool drift는 자동 갱신의 결입니다. NodePool의 template.spec.requirements의 일부가 변하면 (예: 새 AMI가 반영되면), Karpenter가 점진적으로 옛 노드를 새 노드로 교체합니다 — drift detection이라 부르는 메커니즘입니다. 매니지드 노드 그룹의 in-place와 결과는 비슷하지만, Karpenter의 결정으로 진행됩니다.
spec:
disruption:
consolidationPolicy: WhenEmptyOrUnderutilized
consolidateAfter: 30s
budgets:
- nodes: "10%" # 한 번에 최대 10% 의 노드만 교체
duration: 10m
schedule: "0 9 * * mon-fri" # 평일 오전 9시부터만budgets가 업그레이드의 blast radius를 제어하는 도구입니다. 한 번에 10% 이하 + 평일 업무 시간에만 두는 게 prod의 표준 패턴입니다.
3. 애드온 — 호환 매트릭스 #
cluster_addons = {
vpc-cni = {
addon_version = "v1.18.1-eksbuild.3" # 1.32 호환
}
coredns = {
addon_version = "v1.11.1-eksbuild.9"
}
kube-proxy = {
addon_version = "v1.32.0-eksbuild.2"
}
aws-ebs-csi-driver = {
addon_version = "v1.30.0-eksbuild.1"
}
}AWS의 EKS Addon 페이지에 각 K8s 마이너별 호환 버전이 매트릭스로 정리되어 있습니다. most_recent = true로 둬도 EKS가 호환되는 최신 버전을 자동으로 선택하지만, 운영 환경에서는 명시적 버전 핀 + 분기마다 수동 갱신의 결이 변화 통제에 안전합니다.
15장 CNI 깊이의 VPC CNI가 가장 까다로운 애드온입니다 — Pod의 네트워크 IP 할당을 담당하므로, 잘못 업그레이드되면 새 Pod가 IP를 받지 못합니다. 사전에 dev에서 한 주 굴려 본 뒤 prod에 반영하는 게 표준입니다.
노드 drain의 안전장치 #
업그레이드의 가장 잘 알려진 사고는 drain 중 다운타임입니다. 세 안전장치가 결합되어야 안전합니다.
1. PodDisruptionBudget (PDB) #
22장 앱 배포 골격에서 만든 PDB 한 줄이 본격적으로 활약하는 시점입니다.
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: myshop-api
spec:
minAvailable: 2
selector:
matchLabels:
app.kubernetes.io/name: myshop-apiminAvailable: 2가 핵심 — drain 시 동시에 evict 가능한 Pod의 수가 현재 ready - 2로 제한됩니다. EKS의 drain이 PDB를 존중하므로, 5분 동안 drain이 못 끝나면 EKS가 알람을 띄우고 사람의 결정을 기다립니다.
14장 RBAC / NetworkPolicy / ResourceQuota의 ResourceQuota와 마찬가지로 PDB도 선언적 가드레일의 한 종류입니다. 매니페스트에 한 줄 적어 두면 1년 뒤 업그레이드의 안전선으로 자동 작동합니다.
2. terminationGracePeriodSeconds #
spec:
template:
spec:
terminationGracePeriodSeconds: 60 # 기본 30
containers:
- name: api
# ...drain 시 Pod가 받는 SIGTERM부터 SIGKILL 까지의 유예 시간입니다. 12장 헬스 체크 §“graceful shutdown"에서 다룬 내용이 본 절에서 실제 운영 관점으로 이어집니다.
myshop-api가 진행 중인 HTTP 요청을 마치고, DB 연결을 close 하고, in-flight 작업을 마무리할 시간을 30~60초 정도로 잡아 두는 게 운영 표준입니다. 너무 짧으면 사용자에게 500 응답이 떨어지고, 너무 길면 drain 자체가 멈춥니다.
3. preStop hook #
containers:
- name: api
lifecycle:
preStop:
exec:
command: ["sh", "-c", "sleep 10"]preStop hook이 SIGTERM 전에 실행됩니다. 10초 동안 sleep 하는 동안 readiness가 false가 되어 Service의 endpoints에서 제외되고, 그 사이에 들어오던 새 요청이 다른 Pod로 가게 됩니다. 연결 중인 요청과 새 요청을 분리 하는 데 결정적인 결입니다.
--disable-eviction의 위험
#
kubectl drain <node> --disable-eviction --force이 옵션은 PDB를 무시하고 강제로 evict 합니다. 운영에서 절대 쓰지 말아야 할 옵션입니다. PDB가 막힌 이유는 보통 정당하고, 강제 drain은 다운타임의 직접 원인이 됩니다.
blast radius 최소화 #
업그레이드의 영향 범위를 줄이는 표준 패턴은 다음과 같습니다.
1. dev 에서 한 주 굴려 보기
- 컨트롤 플레인 + 노드 + 애드온 모두 업그레이드
- 일주일 동안 동작 관찰
2. staging 에서 prod 시나리오 시뮬레이션
- 부하 테스트 (k6, locust)
- DB 연결, 외부 API 호출까지 한 사이클
3. prod 컨트롤 플레인 업그레이드 (워크로드 영향 거의 없음)
4. prod 노드 그룹의 카나리 부분부터
- 새 노드 그룹을 작게 만들어 일부 워크로드를 옮김
- 한 주 관찰 후 점진 확대
5. 마지막에 모든 노드 그룹 + 애드온 일제 정렬이 흐름이 분기마다 한 번씩 돌아가는 것이 운영의 목표입니다. 한 번에 모든 환경을 같은 날 업그레이드하지 않는 것이 가장 큰 안전선입니다.
롤백 시나리오 #
업그레이드가 실패하면 무엇을 할 수 있는가의 결입니다.
컨트롤 플레인 — 다운그레이드 불가 #
EKS 컨트롤 플레인의 마이너 다운그레이드는 불가능 합니다. 1.32로 올라간 뒤 1.31로 내릴 수 없습니다. 이 제약 때문에 컨트롤 플레인 업그레이드 전에 dev / staging에서 충분히 검증 하는 게 필수입니다.
다운그레이드가 필요한 시점이라면 대안은 두 가지입니다.
- 새 클러스터 (옛 버전)를 만들고 워크로드 이전 — 20장 GitOps의 매니페스트 단일 소스 모델 덕분에 새 클러스터에 같은 매니페스트를 적용하면 워크로드가 그대로 떠오릅니다. RDS와 같은 stateful 시스템은 그대로 둡니다.
- 확장 지원 모드로 옛 버전 유지 — 비용은 가산되지만 시간을 법니다.
노드 — 옛 노드 그룹으로 복귀 #
1. 옛 버전의 노드 그룹을 미리 유지 (옛 launch template)
2. 새 노드 그룹에 문제 발견
3. Karpenter NodePool 또는 taint 조정으로 옛 노드로 워크로드 이전
4. 새 노드 그룹 비우기옛 노드 그룹을 한 주 동안 유지하는 패턴이 노드 레벨의 롤백 안전선입니다. 컨트롤 플레인은 못 내려도 노드는 옛 버전으로 되돌릴 수 있다는 결이 핵심입니다.
애드온 — 명시적 버전 핀 #
애드온의 롤백은 가장 단순합니다. Terraform의 addon_version을 옛 값으로 되돌려 apply 하면 됩니다. 그래서 본 챕터 앞 §“애드온"에서 명시적 버전 핀을 권장한 결입니다.
백업과 RPO / RTO #
업그레이드 자체로 데이터가 손실되는 일은 드물지만, 사고 시 복구를 빠르게 하려면 백업의 결도 묶여야 합니다.
- RDS PITR
RPO: 5 초 ~ 1 분 (트랜잭션 로그 기반)
RTO: 5 ~ 30 분 (인스턴스 복구 시간)
- Velero (S3 백업)
RPO: 일 1 회 백업이면 24 시간 평균
RTO: 클러스터 재구성 + restore = 1 ~ 4 시간
- EBS Snapshot
RPO: snapshot 주기에 따름 (보통 일 1 회)
RTO: 새 PV 프로비저닝 + 마운트 = 10 ~ 30 분
- etcd snapshot (self-managed K8s 만)
RPO: snapshot 주기 (보통 시간 단위)
RTO: K8s 컨트롤 플레인 복원 = 1 ~ 2 시간EKS는 컨트롤 플레인의 etcd가 매니지드라 사용자가 직접 백업할 필요가 없습니다. 그래서 본 챕터의 백업 대상은 RDS + EBS + Velero의 세 축입니다. 26장 운영 체크리스트 §“백업과 복구"에서 짚었던 분기 복구 훈련이 본 절의 RTO 검증과 직접 묶입니다.
업그레이드 직전에는 다음 세 백업이 모두 최신 상태인지 확인하는 게 표준입니다.
1. RDS — 자동 스냅샷의 최신성, manual snapshot 추가 권장
2. Velero — 마지막 백업의 시점, 성공/실패 상태
3. EBS Snapshot — 중요 PV 의 수동 snapshot업그레이드 체크리스트 #
업그레이드 전 1주 / 당일 / 후 1주의 표준 체크리스트입니다.
전 1주 #
[준비]
- 릴리스 노트 검토 (deprecated / removed API, breaking changes)
- pluto + kubent 로 deprecated API 정리
- apiserver_requested_deprecated_apis 메트릭이 0 인지 확인
- 외부 차트 (LB Controller, ESO, kube-prometheus-stack 등) 새 버전 호환 확인
- Operator 의 CRD 마이그레이션 노트 확인
[검증]
- dev 클러스터 업그레이드 + 한 주 동안 굴려 보기
- staging 부하 테스트
- 모든 알람 룰이 새 버전에서도 작동하는지 확인
[준비물]
- RDS / Velero / EBS 백업 최신 확인
- 옛 노드 그룹의 launch template 보존 확인
- 변경 통지 (사용자 / 사내 공지)
- Slack 사고 채널 준비당일 #
[순서]
1. 변경 freeze (배포 일시 중단)
2. 마지막 manual snapshot (RDS, EBS)
3. 컨트롤 플레인 업그레이드 (Terraform)
4. 한 시간 모니터링 (kubectl, 알람, 사용자 메트릭)
5. 카나리 노드 그룹 업그레이드 (10 ~ 20%)
6. 한 시간 모니터링
7. 나머지 노드 그룹 업그레이드 (PDB + drain budgets)
8. 애드온 업그레이드 (vpc-cni 마지막)
9. 변경 freeze 해제
[관찰]
- Pod 의 상태 변화 (Running 비율)
- 5xx 비율 (myshop-api 의 핵심 SLI)
- P95 latency
- 노드의 Ready 비율
- ALB target 의 healthy 수후 1주 #
[검증]
- 알람 발화 빈도 (평소 대비)
- 비용 변화 (Karpenter / 노드 가격 변화)
- 잔재 자원 정리 (옛 launch template, 옛 노드)
- 신규 deprecated 알림 등장 여부 (다음 분기 준비)
[문서화]
- 업그레이드 회고 (잘된 점, 사고 / 개선 포인트)
- runbook 의 업데이트 (다음 분기 적용 가능한 패턴)
- 다음 분기 업그레이드 예상 일정이 체크리스트가 한 페이지에 들어가는 것이 운영 팀의 목표입니다. 26장의 정기 운영 캘린더에서 분기 업그레이드 항목의 본격적인 기준으로 이 체크리스트를 둡니다.
연습문제 #
- dev EKS 클러스터의 K8s 버전을 한 단계 마이너 업그레이드해 봅니다. §“전 1주” 체크리스트의 항목을 위에서부터 따라가고, 각 항목에 실제 소요 시간을 기록합니다.
pluto와kubent의 출력 차이 (매니페스트 vs 클러스터 실제 상태)가 어디서 발생하는지를 한 단락으로 정리하고, 25장 모니터링 · 알람에apiserver_requested_deprecated_apis알람 룰을 추가합니다. - myshop-api의 PDB와 terminationGracePeriodSeconds의 효과를 측정하는 실험을 합니다. preStop hook의 sleep 시간을 0초 / 10초 / 30초 세 가지로 바꿔 가며, 노드 drain 중에 사용자가 받는 5xx 비율의 차이를 측정합니다 (k6로 부하를 주면서 노드를 cordon → drain). 어느 조합이 최적이었는지, 그 이유가 12장 헬스 체크의 readiness probe 모델과 어떻게 묶이는지 한 단락으로 정리합니다.
- 본인의 운영 (또는 학습) 클러스터에 §“업그레이드 체크리스트"의 한 페이지를 적용합니다. 가장 직전 업그레이드가 무엇이었는지 git history로 확인하고, 그때 빠뜨린 항목 또는 사후 사고로 이어진 결을 본 챕터의 체크리스트에 매핑합니다. 다음 업그레이드 일정과 담당자를 26장의 정기 운영 캘린더에 추가합니다.
한 줄 요약: K8s는 분기마다 마이너 버전이 나오고 EKS 표준 지원은 14개월이라 1년에 최소 한 번의 업그레이드가 필수다. 순서는 컨트롤 플레인 → 데이터 플레인 → 애드온이고, 한 마이너씩만 갈 수 있으며, deprecated API 정리가 가장 큰 작업이다. 매니페스트는 pluto, 클러스터는 kubent, 실시간은
apiserver_requested_deprecated_apis메트릭의 세 도구가 deprecated 여부를 함께 잡는다. drain의 안전장치는 PDB + terminationGracePeriodSeconds + preStop hook의 셋이고,--disable-eviction은 절대 쓰지 않는다. blast radius 최소화는 dev 한 주 → staging 부하 → prod 카나리 노드 그룹 → 점진 확대의 흐름이고, 컨트롤 플레인은 다운그레이드 불가 · 노드는 옛 그룹으로 복귀 가능 · 애드온은 버전 핀 되돌리기 의 롤백 매트릭스를 머릿속에 둔다. 업그레이드 전 1주 / 당일 / 후 1주 체크리스트가 한 페이지에 들어가는 것이 운영의 목표다.
다음 챕터 — 6부의 캡스톤 #
이번 챕터로 5부 (운영 · 디버깅 · 비용)의 4장이 마무리됐고, 본 책의 30장이 모두 손에 들어왔습니다. 다음 챕터이자 책의 마지막 챕터에서는 그 30장의 모든 도구가 한 시스템 안에서 어떻게 맞물리는지를 한 프로젝트로 묶습니다.
31장 풀스택 앱 EKS 배포에서는 리액트의 Next.js 앱과 모던 파이썬의 FastAPI 앱을 한 EKS 클러스터에 함께 배포합니다. Terraform + Karpenter + IRSA + ALB Controller + ExternalDNS + cert-manager의 클러스터 셋업부터, RDS + External Secrets + IRSA RDS IAM auth의 DB 연동, Helm + ArgoCD ApplicationSet의 환경별 배포, Prometheus + OpenTelemetry의 옵저버빌리티, k6 부하 테스트 + OpenCost 비용 추정까지의 한 사이클을 13개의 PR로 정리합니다. 1~30장의 모든 도구가 한 시스템 안에서 어떻게 맞물리는지는 본 캡스톤에서 확인할 수 있습니다.
마지막으로 부록 A — docker-compose에서 K8s로가 입문 독자를 위한 마이그레이션 가이드 역할을 하며 책을 마무리합니다.