클러스터 생성과 동일하게 variables.tf 수정 → terraform apply 흐름으로 업그레이드를 진행합니다.
eksctl이나 AWS CLI로 직접 업그레이드하면 실제 클러스터 상태와 Terraform state 사이에 버전 불일치가 생김.
이 경우 다음 terraform apply 시 Terraform이 현재 상태(1.31)와 코드상 desired 상태(1.30)의 차이를 감지하고 다운그레이드를 시도하면서 에러가 발생합니다. 처음부터 Terraform으로 일관되게 관리하는 것이 state drift를 방지하는 올바른 방법입니다.
📌 컨트롤 프레인 업그레이드 전 사전 준비:
1) 현재 파드 컨테이너 이미지 버전 스냅샷
업그레이드 전후 비교를 위해 현재 클러스터에서 실행 중인 모든 파드의 컨테이너 이미지 목록을 파일로 저장!
컨트롤 플레인 업그레이드 후 동일한 명령으로 1.31.txt를 만들어 diff로 비교할 예정입니다.
2) 서비스 가용성 모니터링 세팅
업그레이드 진행 중 UI 서비스가 중단 없이 응답하는지 확인하기 위해 반복 호출을 걸어둡니다.
컨트롤 플레인 업그레이드는 노드를 건드리지 않아 이론상 워크로드에 영향이 없어야 하는데,
실제로 그런지 눈으로 검증하는 과정입니다.
export UI_WEB=$(kubectl get svc -n ui ui-nlb \
-o jsonpath='{.status.loadBalancer.ingress[0].hostname}'/actuator/health/liveness)
# 서비스 응답 상태 반복 확인
while true; do curl -s $UI_WEB; echo; date; sleep 1; echo; done
동시에 클러스터 메타데이터도 polling합니다.
version 필드가 1.30에서 1.31로 바뀌는 시점을 실시간으로 관찰할 수 있습니다.
while true; do
date
aws eks describe-cluster --name $EKS_CLUSTER_NAME \
| egrep 'version|endpoint"|issuer|platformVersion'
echo; sleep 2
done
업그레이드 전 초기 상태값을 미리 기록해둡니다.
특히 endpoint와 issuer 값이 업그레이드 후에도 동일하게 유지되는지가 핵심 관찰 포인트입니다.
plan 결과를 보면 aws_eks_cluster 리소스의 version 속성 변경이 확인됩니다.
중요한 점은 Terraform 파일에 노드그룹의 특정 AMI나 버전이 명시되어 있지 않은 경우, 컨트롤 플레인 버전 변경이 연쇄적으로 관련 Addon 업데이트까지 plan에 포함된다는 것입니다. 이번 실습에서는 컨트롤 플레인 업그레이드만 먼저 보는 단계이므로, plan 내용을 충분히 검토한 뒤 진행합니다.
여기서 중요한 관찰 포인트는 endpoint와 OIDC issuer가 업그레이드 전과 완전히 동일하다는 점입니다.
In-Place 업그레이드에서는 동일한 클러스터를 그대로 올리기 때문에 클러스터 식별자가 바뀌지 않습니다. 이 말은 IRSA를 사용하는 컴포넌트들(ALB Controller, EBS CSI Driver, Karpenter 등)의 IAM Role 신뢰 정책에 등록된 OIDC issuer가 그대로 유효하다는 의미입니다. 별도 재설정 작업 없이 4개의 IRSA 사용 앱이 업그레이드 전후 동일하게 동작합니다.
전 포스팅에서 Blue/Green 방식의 단점으로 다뤘던 OIDC issuer 재설정 문제가
In-Place에서는 발생하지 않는다는 것이 여기서 직접 확인됩니다.
kubectl로도 확인할 수 있습니다. 'kubectl get nodes'에는 EKS 컨트롤 플레인이 표시되지 않습니다.
AWS가 컨트롤 플레인을 완전히 관리하기 때문에 노드 목록에 나타나지 않습니다.
컨트롤 플레인 버전은 kubectl version의 Server Version으로 확인합니다.
kubectl version
Client Version: v1.31.0
Kustomize Version: v5.4.2
Server Version: v1.31.14-eks-40737a8
클러스터 버전이 1.31로 올랐는데 왜 kube-proxy나 coredns 이미지 버전이 그대로일까요?
이건 컨트롤 플레인 업그레이드의 범위를 정확히 보여주는 결과입니다.
컨트롤 플레인 업그레이드는 AWS가 관리하는 API 서버, etcd, 스케줄러, 컨트롤러 매니저를 교체하는 작업입니다.
노드 위에 떠 있는 파드들은 건드리지 않습니다.
kube-proxy는 각 노드에서 DaemonSet으로 실행되는 컴포넌트이고,
coredns는 EKS Addon으로 관리되는 Deployment입니다.
이 둘은 컨트롤 플레인과 별개로 동작하기 때문에 이 단계에서는 여전히 1.30 기준 이미지를 사용하고 있습니다.
Addon 업그레이드는 다음 섹션에서 별도로 진행합니다.
Step3. 파드 재생성 여부 확인
kubectl get pod -A
모든 파드의 AGE가 업그레이드 이전과 동일합니다.
컨트롤 플레인 업그레이드 과정에서 파드가 재시작되거나 재생성된 케이스는 없습니다. 모니터링으로 걸어둔 UI 서비스 curl도 업그레이드 10분 내내 {"status":"UP"} 응답이 끊기지 않은 것을 확인할 수 있습니다.
02. EKS Add-on Upgrade
왜 Addon을 별도로 업그레이드해야 하는가?
컨트롤 플레인 업그레이드가 끝난 시점에 클러스터는 어정쩡한 상태입니다.
API 서버는 1.31인데 노드 위에서 돌고 있는 kube-proxy는 여전히 v1.30.14입니다. CoreDNS도 마찬가지입니다.
EKS Addon은 컨트롤 플레인과 독립적으로 버전이 관리됩니다.
컨트롤 플레인을 올린다고 해서 자동으로 따라 올라가지 않습니다.
각 Addon은 K8s 버전별 호환 버전이 따로 정의되어 있고, 컨트롤 플레인 업그레이드 후 해당 버전에 맞는
Addon 버전으로 명시적으로 올려줘야 합니다.
이번 실습에서 업그레이드하는 대상은 네 가지입니다.
Add-on
역할
CoreDNS
클러스터 내부 DNS 서비스
kube-proxy
각 노드의 네트워크 규칙 관리 (iptables/ipvs)
VPC CNI
파드에 VPC IP 할당
EBS CSI Driver
EBS 볼륨 프로비저닝 및 마운트
현재 설치된 Add-on 상태 확인
eksctl get addon --cluster $CLUSTER_NAME
NAME VERSION STATUS ISSUES UPDATE AVAILABLE
aws-ebs-csi-driver v1.58.0-eksbuild.1 ACTIVE 0 v1.59.0-eksbuild.1
coredns v1.11.4-eksbuild.32 ACTIVE 0
kube-proxy v1.30.14-eksbuild.28 ACTIVE 0 v1.31.14-eksbuild.9, ...
vpc-cni v1.21.1-eksbuild.7 ACTIVE 0
컨트롤 플레인이 1.31로 올라간 시점에서 UPDATE AVAILABLE 컬럼을 보면 kube-proxy와
EBS CSI Driver에 업그레이드 가능한 버전이 표시됩니다.
EKS가 컨트롤 플레인 버전을 기준으로 호환 가능한 Addon 버전을 자동으로 감지해 알려주는 것입니다.
1.31 호환 버전 확인
eksctl get addon 출력에서 제안해주는 버전 외에도, EKS API로 특정 K8s 버전에서 사용 가능한