EKS 클러스터 무중단 버전 업그레이드 핸즈온 (1.32 → 1.33)
EKS 버전 업그레이드는 순서를 잘못 지키면 버전 불일치로 장애가 발생합니다.
직접 실습하면서 각 단계에서 무슨 일이 일어나는지, 어떤 문제를 마주쳤는지 정리했습니다.
업그레이드 순서가 중요한 이유
Control Plane 업그레이드 (10~15분)
↓
애드온 업그레이드 (각 2~5분)
↓
노드 그룹 업그레이드 (노드 수 × 약 5분)
순서를 어기면 생기는 문제:
- 노드를 먼저 올리면 Control Plane이 구버전이라 새 kubelet API를 이해 못함
- 애드온을 먼저 올리면 Control Plane 버전과 호환되지 않는 기능 호출 가능
EKS는 1 마이너 버전씩만 업그레이드 가능합니다 (1.32 → 1.34 불가).
참고: Update an Amazon EKS cluster Kubernetes version — Amazon EKS User Guide
Step 1 — 사전 확인
# 현재 버전 확인
aws eks describe-cluster \
--name filedrop-prod \
--query 'cluster.{Version:version,Status:status}' \
--output table
# 노드 상태 확인
kubectl get nodes
체크리스트:
- 현재 버전이 1.32인지 (1.31이면 1.32 먼저)
- 모든 노드가 Ready 상태인지
Step 2 — PDB 설정 (워크로드 보호)
노드 교체 전에 PodDisruptionBudget을 반드시 설정합니다. 설정하지 않으면 노드 drain 시 Pod가 강제 종료될 수 있습니다.
cat <<EOF | kubectl apply -f -
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: filedrop-api-pdb
namespace: default
spec:
minAvailable: 1
selector:
matchLabels:
app: filedrop-api
EOF
kubectl get pdb
# NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS
# filedrop-api-pdb 1 N/A 1
ALLOWED DISRUPTIONS: 0이면 현재 최소 가용 Pod 수에 도달한 상태 → drain 시 중단됨.
참고: Specifying a Disruption Budget for your Application — Kubernetes Docs
Step 3 — Control Plane 업그레이드
aws eks update-cluster-version \
--name filedrop-prod \
--kubernetes-version 1.33
# 진행 상황 모니터링
watch -n 30 "aws eks describe-cluster \
--name filedrop-prod \
--query 'cluster.{Version:version,Status:status}' \
--output table"
# 완료 대기
aws eks wait cluster-active --name filedrop-prod
Control Plane(API 서버, etcd, 스케줄러)만 교체됩니다. 기존 노드의 Pod는 계속 실행되므로 서비스 영향은 없습니다. API 서버가 잠깐 응답 불가 상태가 될 수 있으나 수초 내 복구됩니다.
Step 4 — 애드온 버전 조회
Control Plane 업그레이드 완료 후 1.33 호환 최신 버전을 조회합니다.
for ADDON in coredns kube-proxy vpc-cni; do
LATEST=$(aws eks describe-addon-versions \
--addon-name $ADDON \
--kubernetes-version 1.33 \
--query 'addons[0].addonVersions[0].addonVersion' \
--output text)
echo "$ADDON → $LATEST"
done
버전을 직접 지정하기보다 자동 조회해서 적용하는 방식이 안전합니다. 버전을 잘못 지정하면 호환성 오류가 발생합니다.
Step 5 — 애드온 업그레이드
coredns → kube-proxy → vpc-cni 순서로 진행합니다.
# coredns
ADDON_VERSION=$(aws eks describe-addon-versions \
--addon-name coredns --kubernetes-version 1.33 \
--query 'addons[0].addonVersions[0].addonVersion' --output text)
aws eks update-addon \
--cluster-name filedrop-prod \
--addon-name coredns \
--addon-version $ADDON_VERSION \
--resolve-conflicts OVERWRITE
aws eks wait addon-active --cluster-name filedrop-prod --addon-name coredns
--resolve-conflicts OVERWRITE 옵션은 기존 애드온 설정이 기본값과 충돌할 때 덮어씁니다. 커스텀 설정이 있다면 PRESERVE로 변경해야 합니다.
kube-proxy, vpc-cni도 동일한 방식으로 순서대로 진행합니다.
Step 6 — 노드 그룹 업그레이드
가장 중요한 단계입니다. 실제로 노드가 교체됩니다.
# 노드 그룹 이름 확인
aws eks list-nodegroups --cluster-name filedrop-prod
# 업그레이드 시작
aws eks update-nodegroup-version \
--cluster-name filedrop-prod \
--nodegroup-name <노드그룹명> \
--kubernetes-version 1.33
# 교체 과정 실시간 모니터링
watch -n 10 kubectl get nodes
실습 중 관찰한 현상: 노드가 갑자기 6개로 늘어남
desired=2, max=2인데 업그레이드 중 노드가 6개까지 증가했습니다. 처음엔 문제라고 생각했지만 AWS 공식 문서 기준으로 완전히 정상 동작이었습니다.
EKS 관리형 노드 그룹 업그레이드 4단계 (AWS 공식 문서 기준)
참고: Managed node group update behavior — Amazon EKS User Guide
1단계 — 설정(Setup)
- ASG에 새 EC2 시작 템플릿 버전 생성
- updateConfig로 병렬 업그레이드 수 결정 (기본값: 1개, 최대: 100개)
2단계 — 확장(Scale-up)
ASG의 max_size와 desired_size를 직접 증가시킵니다. "초과"가 아니라 값 자체를 변경하는 것입니다.
증가량 = max(가용영역 수 × 2, maxUnavailable)
실습 환경: AZ=3, maxUnavailable=1 → max(3×2, 1) = 6개까지 증가 가능
새 노드가 모든 AZ에 최소 1개 이상 Ready 상태가 되어야 다음 단계로 진행합니다.
NodeCreationFailure 원인: AZ 용량 부족 / EC2 인스턴스 쿼터 초과 / 부트스트랩 15분 초과
3단계 — 업그레이드(Upgrade)
기본 전략(Default): 새 노드 먼저 생성 → 구 노드 drain → terminate
- maxUnavailable만큼 구 노드 무작위 선택
- Pod drain (15분 이내 완료 안 되면 PodEvictionFailure)
- 노드 cordon + 60초 대기 (로드밸런서 제거 목적)
- ASG에 종료 요청
- 구 버전 노드가 없을 때까지 반복
최소 전략(Minimal): 구 노드 먼저 종료 후 새 노드 생성 (GPU 등 리소스 제약 환경)
PodEvictionFailure 원인: 적극적인 PDB 설정 / 모든 Taint를 허용하는 Deployment
4단계 — 축소(Scale-down)
ASG의 max_size와 desired_size를 원래 값으로 하나씩 감소.
주의 (공식 문서): Cluster Autoscaler가 활성화된 경우, 축소 단계에서 scale-out이 필요하다고 판단하면 원래 크기로 되돌리지 않고 즉시 종료됩니다. 업그레이드 후 노드가 예상보다 많이 남아있다면 이 케이스를 의심하세요.
Step 7 — 완료 확인
kubectl get nodes
# NAME STATUS VERSION
# ip-10-... Ready v1.33.x
# ip-10-... Ready v1.33.x
kubectl get pods -A | grep -v Running | grep -v Completed
# 결과 없으면 모든 Pod 정상
추가 트러블슈팅: ASG 자동 축소 중 노드 stuck
상황: GUI에서 desired=2로 줄였는데 노드가 SchedulingDisabled 상태로 멈춤
kubectl get nodes
# ip-10-0-2-xxx Ready,SchedulingDisabled ← 멈춤
kubectl get pdb -n kube-system
# ebs-csi-controller N/A 1 0 ← ALLOWED DISRUPTIONS=0
원인:
- ASG가 노드 cordon 처리
- ebs-csi-controller Pod를 drain하려 했으나 PDB가 eviction 차단
- 노드가 cordon 상태에서 stuck
교훈: ASG 자동 축소는 kube-system PDB를 인식하지 못합니다. 노드 수를 줄일 때는 kubectl drain 먼저 실행 후 ASG 축소해야 합니다.
# 올바른 순서
kubectl drain <node-name> \
--ignore-daemonsets \
--delete-emptydir-data \
--grace-period=60
# drain 완료 후 ASG desired 축소
체크포인트
Q. EKS 버전 업그레이드 순서는?
Control Plane → 애드온(coredns/kube-proxy/vpc-cni) → 노드 그룹 순서가 필수입니다. 순서를 어기면 버전 불일치로 API 호환성 오류가 발생합니다.
Q. 업그레이드 중 서비스 영향은?
Control Plane 교체 중 API 서버가 수초간 응답 불가 상태가 될 수 있으나 워크로드에는 영향 없습니다. 노드 교체 단계가 실질적인 서비스 위험 구간이므로 PDB를 반드시 사전 설정해야 합니다.
Q. 노드 업그레이드 중 노드 수가 늘어나는 이유는?
EKS가 롤링 업그레이드 확장 단계에서 ASG의 max_size와 desired_size를 직접 증가시킵니다. 증가량은 max(AZ 수 × 2, maxUnavailable) 공식으로 결정되며, 업그레이드 완료 후 원래 desired로 수렴합니다. (AWS 공식 문서: Managed node group update behavior)
'cloud' 카테고리의 다른 글
| ECS Task 생명주기 — 상태 전이, 교체, Graceful Shutdown (0) | 2026.04.05 |
|---|---|
| EKS IAM 핸즈온 — IRSA, Pod Identity, Access Entry (0) | 2026.04.02 |
| EKS 운영 트러블슈팅 핸즈온 — Pending, CrashLoop, NetworkPolicy (0) | 2026.04.01 |
| EKS 노드 Drain 핸즈온 — PDB가 없으면 운영 사고난다 (0) | 2026.04.01 |
| Terraform으로 EKS + ECS 운영 환경 한 번에 구축하기 (0) | 2026.03.31 |