Amazon EKS 업그레이드 퀴즈
이 퀴즈는 Amazon EKS 클러스터 업그레이드 프로세스, 모범 사례, 문제 해결 및 관련 고려 사항에 대한 이해를 테스트합니다.
퀴즈 개요
- EKS 클러스터 업그레이드 계획
- 컨트롤 플레인 업그레이드
- 노드 그룹 업그레이드
- 애드온 및 구성 요소 업그레이드
- 업그레이드 테스트 및 검증
- 업그레이드 문제 해결
객관식 문제
1. Amazon EKS 클러스터 업그레이드를 계획할 때 가장 중요한 첫 번째 단계는 무엇인가요?
A. 즉시 컨트롤 플레인 업그레이드 수행
B. 모든 워크로드를 한 번에 업그레이드
C. 업그레이드 호환성 검토 및 테스트 계획 수립
D. 모든 노드 그룹 동시 업그레이드
정답 및 설명
정답: C. 업그레이드 호환성 검토 및 테스트 계획 수립
설명: Amazon EKS 클러스터 업그레이드를 계획할 때 가장 중요한 첫 번째 단계는 업그레이드 호환성을 검토하고 테스트 계획을 수립하는 것입니다. 이 단계는 업그레이드 과정에서 발생할 수 있는 문제를 미리 식별하고, 워크로드 중단을 최소화하며, 성공적인 업그레이드를 위한 기반을 마련합니다.
업그레이드 호환성 검토 및 테스트 계획의 주요 구성 요소:
버전 호환성 검토:
- Kubernetes 버전 간 API 변경 사항 확인
- 사용 중인 API 버전 및 기능의 지원 여부 검토
- 더 이상 사용되지 않거나 제거된 API 식별
워크로드 호환성 평가:
- 애플리케이션 매니페스트의 API 버전 검토
- 사용 중인 컨트롤러 및 운영자 호환성 확인
- 커스텀 리소스 정의(CRD) 및 웹훅 호환성 검토
애드온 및 도구 호환성 확인:
- CNI, CoreDNS, kube-proxy 버전 호환성
- 인그레스 컨트롤러, 서비스 메시 등의 호환성
- 모니터링, 로깅, 백업 도구 호환성
테스트 계획 수립:
- 비프로덕션 환경에서의 업그레이드 테스트
- 주요 워크로드 기능 테스트 계획
- 롤백 절차 및 기준 정의
구현 방법:
업그레이드 경로 및 호환성 검토:
bash# 현재 EKS 클러스터 버전 확인 aws eks describe-cluster --name my-cluster --query "cluster.version" # 사용 가능한 EKS 버전 확인 aws eks describe-addon-versions --kubernetes-version 1.28 # 더 이상 사용되지 않는 API 확인 kubectl get --raw /metrics | grep "deprecated_api_requests_total" # 사용 중인 API 버전 검토 kubectl get deployment,statefulset,daemonset,cronjob,job -A -o json | jq '.items[].apiVersion' | sort | uniq워크로드 호환성 검사 도구 사용:
bash# pluto를 사용하여 더 이상 사용되지 않는 API 버전 검사 pluto detect-helm --output wide pluto detect-kubectl --output wide # kube-no-trouble 사용 kubectl-no-trouble테스트 클러스터 생성 및 업그레이드 테스트:
bash# 테스트 클러스터 생성 eksctl create cluster \ --name test-upgrade \ --version 1.27 \ --region us-west-2 \ --nodegroup-name standard-workers \ --node-type m5.large \ --nodes 2 # 테스트 클러스터 업그레이드 eksctl upgrade cluster \ --name test-upgrade \ --version 1.28 \ --approve업그레이드 계획 문서 작성:
markdown# EKS 클러스터 업그레이드 계획 ## 현재 상태 - 클러스터 버전: 1.27 - 노드 그룹: 3개 (시스템: 1.27, 앱: 1.27, 배치: 1.27) - 주요 애드온: AWS VPC CNI 1.12.0, CoreDNS 1.8.7, kube-proxy 1.27.1 ## 대상 상태 - 클러스터 버전: 1.28 - 노드 그룹: 3개 (시스템: 1.28, 앱: 1.28, 배치: 1.28) - 주요 애드온: AWS VPC CNI 1.13.0, CoreDNS 1.9.3, kube-proxy 1.28.1 ## 호환성 검토 결과 - 더 이상 사용되지 않는 API: batch/v1beta1 CronJob -> batch/v1 CronJob - 애드온 호환성: 모두 호환됨 - 커스텀 리소스: 업데이트 필요 없음 ## 업그레이드 단계 1. 비프로덕션 환경 업그레이드 및 테스트 2. 컨트롤 플레인 업그레이드 3. 애드온 업그레이드 4. 노드 그룹 순차적 업그레이드 5. 검증 및 모니터링 ## 롤백 계획 - 롤백 기준: 중요 워크로드 장애 발생 시 - 롤백 절차: 새 노드 그룹 생성 (이전 버전), 워크로드 마이그레이션
업그레이드 호환성 검토 주요 영역:
API 변경 사항:
- Kubernetes 1.22: 많은 베타 API가 제거됨
- Kubernetes 1.25: PodSecurityPolicy 제거
- Kubernetes 1.26: HorizontalPodAutoscaler v2beta2 제거
- Kubernetes 1.27: FlowSchema 및 PriorityLevelConfiguration API 변경
- Kubernetes 1.28: 일부 베타 API 제거 및 변경
노드 구성 요소 호환성:
- kubelet 버전은 컨트롤 플레인보다 최대 2개 마이너 버전 이전까지 지원
- kube-proxy는 컨트롤 플레인과 동일한 버전으로 유지 권장
- 컨테이너 런타임 호환성 확인
애드온 호환성:
- CNI 플러그인 버전 호환성
- CoreDNS 버전 호환성
- 인그레스 컨트롤러, 서비스 메시 등의 호환성
테스트 계획 수립 모범 사례:
단계적 테스트 접근 방식:
- 개발 환경 먼저 업그레이드
- 스테이징 환경에서 전체 테스트 수행
- 프로덕션 환경 업그레이드 전 최종 검증
주요 워크로드 기능 테스트:
- 핵심 비즈니스 기능 테스트
- 성능 및 확장성 테스트
- 장애 복구 테스트
모니터링 및 알림 강화:
- 업그레이드 중 추가 모니터링 구성
- 주요 메트릭 및 로그 모니터링
- 신속한 대응을 위한 알림 설정
롤백 절차 정의:
- 명확한 롤백 기준 설정
- 롤백 절차 문서화 및 테스트
- 데이터 일관성 보장 방안 마련
실제 구현 예시:
업그레이드 호환성 검토 스크립트:
bash#!/bin/bash # EKS 클러스터 업그레이드 호환성 검토 스크립트 CLUSTER_NAME="my-cluster" TARGET_VERSION="1.28" echo "=== EKS 클러스터 업그레이드 호환성 검토 ===" echo "클러스터: $CLUSTER_NAME" echo "대상 버전: $TARGET_VERSION" echo # 현재 클러스터 버전 확인 CURRENT_VERSION=$(aws eks describe-cluster --name $CLUSTER_NAME --query "cluster.version" --output text) echo "현재 클러스터 버전: $CURRENT_VERSION" # 애드온 버전 확인 echo echo "=== 현재 애드온 버전 ===" aws eks describe-addon --cluster-name $CLUSTER_NAME --addon-name vpc-cni --query "addon.addonVersion" --output text aws eks describe-addon --cluster-name $CLUSTER_NAME --addon-name coredns --query "addon.addonVersion" --output text aws eks describe-addon --cluster-name $CLUSTER_NAME --addon-name kube-proxy --query "addon.addonVersion" --output text echo echo "=== 대상 버전에서 사용 가능한 애드온 버전 ===" aws eks describe-addon-versions --kubernetes-version $TARGET_VERSION --query "addons[?addonName=='vpc-cni'].addonVersions[].addonVersion" --output text aws eks describe-addon-versions --kubernetes-version $TARGET_VERSION --query "addons[?addonName=='coredns'].addonVersions[].addonVersion" --output text aws eks describe-addon-versions --kubernetes-version $TARGET_VERSION --query "addons[?addonName=='kube-proxy'].addonVersions[].addonVersion" --output text # 더 이상 사용되지 않는 API 확인 echo echo "=== 더 이상 사용되지 않는 API 사용 현황 ===" kubectl get --raw /metrics | grep "deprecated_api_requests_total" || echo "더 이상 사용되지 않는 API 요청이 없습니다." # 사용 중인 API 버전 검토 echo echo "=== 사용 중인 API 버전 ===" kubectl get deployment,statefulset,daemonset,cronjob,job -A -o json | jq '.items[].apiVersion' | sort | uniq echo echo "=== 업그레이드 호환성 검토 완료 ==="업그레이드 테스트 계획 템플릿:
markdown# EKS 클러스터 업그레이드 테스트 계획 ## 테스트 환경 - 클러스터 이름: test-upgrade - 현재 버전: 1.27 - 대상 버전: 1.28 ## 테스트 범위 ### 인프라 테스트 - [ ] 컨트롤 플레인 업그레이드 성공 - [ ] 노드 그룹 업그레이드 성공 - [ ] 애드온 업그레이드 성공 - [ ] 클러스터 상태 확인 ### 워크로드 테스트 - [ ] 배포 생성 및 확장 - [ ] 스테이트풀셋 기능 - [ ] 인그레스 및 서비스 기능 - [ ] 크론잡 및 잡 실행 - [ ] 커스텀 리소스 생성 및 관리 ### 성능 테스트 - [ ] 노드 리소스 사용량 - [ ] 파드 시작 시간 - [ ] API 서버 응답 시간 - [ ] 네트워크 성능 ### 장애 복구 테스트 - [ ] 노드 장애 시 파드 재스케줄링 - [ ] 네트워크 중단 시 동작 - [ ] 리소스 압박 상황에서의 동작 ## 테스트 결과 및 관찰 사항 ## 결론 및 권장 사항
다른 옵션들의 문제점:
- A. 즉시 컨트롤 플레인 업그레이드 수행: 호환성 검토 및 테스트 없이 바로 업그레이드를 수행하면 예상치 못한 문제가 발생할 수 있으며, 워크로드 중단 위험이 높아집니다.
- B. 모든 워크로드를 한 번에 업그레이드: 이는 위험한 접근 방식으로, 문제 발생 시 전체 시스템에 영향을 미칠 수 있습니다. 단계적 접근이 더 안전합니다.
- D. 모든 노드 그룹 동시 업그레이드: 모든 노드를 동시에 업그레이드하면 전체 워크로드가 중단될 위험이 있으며, 문제 발생 시 롤백이 어려워집니다.
A. 노드 그룹을 먼저 업그레이드한 후 컨트롤 플레인 업그레이드
B. 컨트롤 플레인을 업그레이드한 후 노드 그룹 업그레이드
C. 컨트롤 플레인과 노드 그룹을 동시에 업그레이드
D. 업그레이드 없이 새 클러스터를 생성하고 워크로드 마이그레이션
정답 및 설명
정답: B. 컨트롤 플레인을 업그레이드한 후 노드 그룹 업그레이드
설명: Amazon EKS 클러스터의 컨트롤 플레인을 업그레이드할 때 가장 올바른 접근 방식은 컨트롤 플레인을 먼저 업그레이드한 후 노드 그룹을 업그레이드하는 것입니다. 이 접근 방식은 Kubernetes의 버전 호환성 모델을 따르며, 업그레이드 과정에서 발생할 수 있는 문제를 최소화합니다.
컨트롤 플레인 먼저 업그레이드하는 이유:
Kubernetes 버전 호환성 모델:
- 컨트롤 플레인은 노드보다 최대 2개 마이너 버전까지 앞설 수 있음
- 노드는 컨트롤 플레인보다 앞설 수 없음
- 이 모델은 하위 호환성을 보장하기 위함
API 서버 호환성:
- 새 버전의 API 서버는 이전 버전의 kubelet과 통신 가능
- 반대로 새 버전의 kubelet은 이전 버전의 API 서버와 호환성 문제 발생 가능
점진적 업그레이드 가능:
- 컨트롤 플레인 업그레이드 후 노드 그룹을 점진적으로 업그레이드 가능
- 문제 발생 시 영향 범위 제한 및 롤백 용이
구현 방법:
컨트롤 플레인 업그레이드:
bash# AWS CLI를 사용한 컨트롤 플레인 업그레이드 aws eks update-cluster-version \ --name my-cluster \ --kubernetes-version 1.28 # 업그레이드 상태 확인 aws eks describe-update \ --name my-cluster \ --update-id <update-id>bash# eksctl을 사용한 컨트롤 플레인 업그레이드 eksctl upgrade cluster \ --name my-cluster \ --version 1.28 \ --approve컨트롤 플레인 업그레이드 완료 확인:
bash# 클러스터 버전 확인 aws eks describe-cluster \ --name my-cluster \ --query "cluster.version" \ --output text # 클러스터 상태 확인 kubectl get componentstatuses kubectl get nodes노드 그룹 업그레이드 준비:
bash# 현재 노드 그룹 확인 aws eks list-nodegroups \ --cluster-name my-cluster # 노드 그룹 버전 확인 aws eks describe-nodegroup \ --cluster-name my-cluster \ --nodegroup-name my-nodegroup \ --query "nodegroup.version" \ --output text
컨트롤 플레인 업그레이드 프로세스:
업그레이드 전 준비:
- 클러스터 상태 확인
- 백업 수행
- 중요 워크로드 확인
업그레이드 시작:
- AWS Management Console, AWS CLI 또는 eksctl 사용
- 업그레이드 진행 상황 모니터링
업그레이드 중 모니터링:
- 컨트롤 플레인 엔드포인트 가용성
- 시스템 워크로드 상태
- 로그 및 이벤트 모니터링
업그레이드 완료 후 검증:
- 컨트롤 플레인 구성 요소 상태 확인
- API 서버 기능 테스트
- 시스템 워크로드 정상 작동 확인
컨트롤 플레인 업그레이드 시 고려 사항:
업그레이드 시간:
- 일반적으로 20-30분 소요
- 클러스터 크기 및 복잡성에 따라 다름
- 유지 관리 기간 중 수행 권장
업그레이드 중 API 서버 가용성:
- 업그레이드 중 일시적인 API 서버 중단 가능
- 기존 워크로드는 계속 실행됨
- 새로운 배포 및 구성 변경은 지연될 수 있음
업그레이드 실패 시 대응:
- AWS 지원팀에 문의
- 클러스터 상태 및 로그 수집
- 대체 계획 실행
모범 사례:
업그레이드 전 클러스터 상태 확인:
bash# 클러스터 상태 확인 kubectl get nodes kubectl get pods --all-namespaces kubectl get componentstatuses # 이벤트 확인 kubectl get events --all-namespaces --sort-by='.lastTimestamp' # 리소스 사용량 확인 kubectl top nodes kubectl top pods --all-namespaces업그레이드 전 etcd 백업:
bash# etcd 백업 (자체 관리 클러스터의 경우) ETCDCTL_API=3 etcdctl snapshot save snapshot.db # EKS의 경우 주요 리소스 백업 kubectl get all --all-namespaces -o yaml > all-resources.yaml점진적 노드 그룹 업그레이드 계획:
bash# 노드 그룹 업그레이드 계획 # 1. 중요도가 낮은 노드 그룹부터 시작 # 2. 한 번에 하나의 노드 그룹만 업그레이드 # 3. 각 노드 그룹 업그레이드 후 검증업그레이드 후 시스템 구성 요소 확인:
bash# 시스템 파드 상태 확인 kubectl get pods -n kube-system # CoreDNS 상태 확인 kubectl get pods -n kube-system -l k8s-app=kube-dns # CNI 플러그인 상태 확인 kubectl get pods -n kube-system -l k8s-app=aws-node
실제 구현 예시:
컨트롤 플레인 업그레이드 스크립트:
bash#!/bin/bash # EKS 컨트롤 플레인 업그레이드 스크립트 CLUSTER_NAME="my-cluster" TARGET_VERSION="1.28" echo "=== EKS 클러스터 컨트롤 플레인 업그레이드 ===" echo "클러스터: $CLUSTER_NAME" echo "대상 버전: $TARGET_VERSION" echo # 현재 클러스터 버전 확인 CURRENT_VERSION=$(aws eks describe-cluster --name $CLUSTER_NAME --query "cluster.version" --output text) echo "현재 클러스터 버전: $CURRENT_VERSION" # 클러스터 상태 확인 echo echo "=== 클러스터 상태 확인 ===" kubectl get nodes kubectl get pods --all-namespaces | grep -v "Running\|Completed" # 사용자 확인 echo read -p "클러스터 업그레이드를 시작하시겠습니까? (y/n): " confirm if [[ $confirm != "y" ]]; then echo "업그레이드가 취소되었습니다." exit 1 fi # 업그레이드 시작 echo echo "=== 컨트롤 플레인 업그레이드 시작 ===" UPDATE_ID=$(aws eks update-cluster-version \ --name $CLUSTER_NAME \ --kubernetes-version $TARGET_VERSION \ --query "update.id" \ --output text) echo "업그레이드 ID: $UPDATE_ID" # 업그레이드 상태 모니터링 echo echo "=== 업그레이드 상태 모니터링 ===" STATUS="InProgress" while [ "$STATUS" == "InProgress" ]; do echo "업그레이드 진행 중... $(date)" sleep 60 STATUS=$(aws eks describe-update \ --name $CLUSTER_NAME \ --update-id $UPDATE_ID \ --query "update.status" \ --output text) done echo echo "업그레이드 상태: $STATUS" if [ "$STATUS" == "Successful" ]; then echo echo "=== 컨트롤 플레인 업그레이드 완료 ===" echo "새 버전: $(aws eks describe-cluster --name $CLUSTER_NAME --query "cluster.version" --output text)" echo echo "=== 클러스터 상태 확인 ===" kubectl get nodes kubectl get pods -n kube-system else echo echo "=== 업그레이드 실패 ===" aws eks describe-update \ --name $CLUSTER_NAME \ --update-id $UPDATE_ID fiTerraform을 사용한 EKS 클러스터 버전 관리:
hcl# EKS 클러스터 정의 resource "aws_eks_cluster" "main" { name = "my-cluster" role_arn = aws_iam_role.eks_cluster.arn version = "1.28" # 대상 버전 지정 vpc_config { subnet_ids = var.subnet_ids security_group_ids = [aws_security_group.eks_cluster.id] } # 버전 업그레이드 시 새 버전이 적용될 때까지 대기 lifecycle { ignore_changes = [] } depends_on = [ aws_iam_role_policy_attachment.eks_cluster_policy ] }업그레이드 후 검증 스크립트:
bash#!/bin/bash # EKS 클러스터 업그레이드 후 검증 스크립트 CLUSTER_NAME="my-cluster" echo "=== EKS 클러스터 업그레이드 검증 ===" echo "클러스터: $CLUSTER_NAME" echo # 클러스터 버전 확인 CLUSTER_VERSION=$(aws eks describe-cluster --name $CLUSTER_NAME --query "cluster.version" --output text) echo "클러스터 버전: $CLUSTER_VERSION" # 컨트롤 플레인 상태 확인 echo echo "=== 컨트롤 플레인 상태 ===" kubectl get componentstatuses # 시스템 파드 상태 확인 echo echo "=== 시스템 파드 상태 ===" kubectl get pods -n kube-system # 노드 상태 확인 echo echo "=== 노드 상태 ===" kubectl get nodes # API 서버 기능 테스트 echo echo "=== API 서버 기능 테스트 ===" kubectl create namespace test-upgrade kubectl run nginx --image=nginx -n test-upgrade kubectl get pods -n test-upgrade kubectl delete namespace test-upgrade echo echo "=== 검증 완료 ==="
다른 옵션들의 문제점:
- A. 노드 그룹을 먼저 업그레이드한 후 컨트롤 플레인 업그레이드: 이는 Kubernetes 버전 호환성 모델에 위배되며, 노드의 kubelet 버전이 API 서버 버전보다 앞서게 되어 호환성 문제가 발생할 수 있습니다.
- C. 컨트롤 플레인과 노드 그룹을 동시에 업그레이드: 동시 업그레이드는 위험하며, 문제 발생 시 전체 클러스터에 영향을 미칠 수 있습니다. 또한 점진적인 검증이 어렵습니다.
- D. 업그레이드 없이 새 클러스터를 생성하고 워크로드 마이그레이션: 이 방법은 가능하지만, 리소스 중복, 복잡한 마이그레이션 절차, 추가 비용 등의 문제가 있어 일반적인 업그레이드에는 권장되지 않습니다.
A. 모든 노드를 동시에 종료하고 새 버전으로 교체
B. 관리형 노드 그룹 업그레이드 또는 블루/그린 배포 전략 사용
C. 노드 그룹 업그레이드 없이 컨트롤 플레인만 업그레이드
D. 수동으로 각 노드의 kubelet 버전 업그레이드
정답 및 설명
정답: B. 관리형 노드 그룹 업그레이드 또는 블루/그린 배포 전략 사용
설명: Amazon EKS 노드 그룹을 업그레이드하는 가장 안전하고 효과적인 방법은 관리형 노드 그룹 업그레이드 기능을 사용하거나 블루/그린 배포 전략을 구현하는 것입니다. 이러한 접근 방식은 워크로드 중단을 최소화하면서 노드를 안전하게 업그레이드할 수 있게 해줍니다.
관리형 노드 그룹 업그레이드 및 블루/그린 배포의 주요 이점:
관리형 노드 그룹 업그레이드:
- AWS에서 관리하는 롤링 업그레이드 프로세스
- 파드 중단 예산(PDB) 존중
- 자동 드레이닝 및 코드온
- 업그레이드 실패 시 자동 롤백
블루/그린 배포 전략:
- 새 버전의 노드 그룹 생성
- 워크로드 점진적 마이그레이션
- 검증 후 이전 노드 그룹 제거
- 문제 발생 시 빠른 롤백 가능
구현 방법:
관리형 노드 그룹 업그레이드:
bash# AWS CLI를 사용한 관리형 노드 그룹 업그레이드 aws eks update-nodegroup-version \ --cluster-name my-cluster \ --nodegroup-name my-nodegroup \ --kubernetes-version 1.28 # 업그레이드 상태 확인 aws eks describe-update \ --name my-cluster \ --nodegroup-name my-nodegroup \ --update-id <update-id>bash# eksctl을 사용한 관리형 노드 그룹 업그레이드 eksctl upgrade nodegroup \ --cluster my-cluster \ --name my-nodegroup \ --kubernetes-version 1.28블루/그린 배포 전략:
bash# 새 노드 그룹 생성 eksctl create nodegroup \ --cluster my-cluster \ --name my-nodegroup-v2 \ --node-type m5.large \ --nodes 3 \ --nodes-min 3 \ --nodes-max 6 \ --node-labels "kubernetes.io/role=worker,environment=production,version=v2" \ --node-ami auto \ --kubernetes-version 1.28 # 워크로드 마이그레이션 (노드 선호도 사용) kubectl apply -f - <<EOF apiVersion: apps/v1 kind: Deployment metadata: name: my-app spec: replicas: 3 template: spec: affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 preference: matchExpressions: - key: version operator: In values: - v2 EOF # 이전 노드 그룹 제거 eksctl delete nodegroup \ --cluster my-cluster \ --name my-nodegroup-v1
노드 그룹 업그레이드 프로세스:
관리형 노드 그룹 업그레이드 프로세스:
- 최대 사용 불가능 노드 수 설정
- 새 노드 생성 및 클러스터 조인
- 기존 노드 드레이닝 및 종료
- 모든 노드가 업그레이드될 때까지 반복
블루/그린 배포 프로세스:
- 새 버전의 노드 그룹 생성
- 새 노드 그룹에 테스트 워크로드 배포
- 점진적으로 워크로드 마이그레이션
- 모든 워크로드 마이그레이션 후 이전 노드 그룹 제거
노드 그룹 업그레이드 시 고려 사항:
파드 중단 예산(PDB) 구성:
yamlapiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: app-pdb spec: minAvailable: 2 # 또는 maxUnavailable: 1 selector: matchLabels: app: my-app노드 선호도 및 반선호도 설정:
yamlapiVersion: apps/v1 kind: Deployment metadata: name: my-app spec: template: spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - my-app topologyKey: "kubernetes.io/hostname"테인트 및 톨러레이션 활용:
yaml# 새 노드 그룹에 테인트 적용 eksctl create nodegroup \ --cluster my-cluster \ --name my-nodegroup-v2 \ --node-labels "version=v2" \ --taints "upgrade=v2:NoSchedule" \ --kubernetes-version 1.28 # 특정 워크로드에 톨러레이션 적용 apiVersion: apps/v1 kind: Deployment metadata: name: my-app spec: template: spec: tolerations: - key: "upgrade" operator: "Equal" value: "v2" effect: "NoSchedule"
모범 사례:
업그레이드 전 준비:
bash# 노드 상태 확인 kubectl get nodes # 파드 분포 확인 kubectl get pods -o wide --all-namespaces # 리소스 사용량 확인 kubectl top nodes kubectl top pods --all-namespaces점진적 업그레이드:
- 한 번에 하나의 노드 그룹만 업그레이드
- 중요도가 낮은 워크로드부터 시작
- 각 단계 검증 후 진행
업그레이드 중 모니터링 강화:
- 노드 상태 모니터링
- 파드 이벤트 모니터링
- 애플리케이션 성능 및 가용성 모니터링
롤백 계획 수립:
- 명확한 롤백 기준 정의
- 롤백 절차 문서화
- 빠른 롤백을 위한 준비
실제 구현 예시:
관리형 노드 그룹 업그레이드 스크립트:
bash#!/bin/bash # EKS 관리형 노드 그룹 업그레이드 스크립트 CLUSTER_NAME="my-cluster" NODEGROUP_NAME="my-nodegroup" TARGET_VERSION="1.28" echo "=== EKS 관리형 노드 그룹 업그레이드 ===" echo "클러스터: $CLUSTER_NAME" echo "노드 그룹: $NODEGROUP_NAME" echo "대상 버전: $TARGET_VERSION" echo # 현재 노드 그룹 버전 확인 CURRENT_VERSION=$(aws eks describe-nodegroup \ --cluster-name $CLUSTER_NAME \ --nodegroup-name $NODEGROUP_NAME \ --query "nodegroup.version" \ --output text) echo "현재 노드 그룹 버전: $CURRENT_VERSION" # 노드 상태 확인 echo echo "=== 노드 상태 확인 ===" kubectl get nodes -l eks.amazonaws.com/nodegroup=$NODEGROUP_NAME # 파드 분포 확인 echo echo "=== 파드 분포 확인 ===" NODE_NAMES=$(kubectl get nodes -l eks.amazonaws.com/nodegroup=$NODEGROUP_NAME -o jsonpath='{.items[*].metadata.name}') for NODE in $NODE_NAMES; do echo "노드: $NODE" kubectl get pods --all-namespaces -o wide | grep $NODE | wc -l done # 사용자 확인 echo read -p "노드 그룹 업그레이드를 시작하시겠습니까? (y/n): " confirm if [[ $confirm != "y" ]]; then echo "업그레이드가 취소되었습니다." exit 1 fi # 업그레이드 시작 echo echo "=== 노드 그룹 업그레이드 시작 ===" UPDATE_ID=$(aws eks update-nodegroup-version \ --cluster-name $CLUSTER_NAME \ --nodegroup-name $NODEGROUP_NAME \ --kubernetes-version $TARGET_VERSION \ --query "update.id" \ --output text) echo "업그레이드 ID: $UPDATE_ID" # 업그레이드 상태 모니터링 echo echo "=== 업그레이드 상태 모니터링 ===" STATUS="InProgress" while [ "$STATUS" == "InProgress" ]; do echo "업그레이드 진행 중... $(date)" sleep 60 STATUS=$(aws eks describe-update \ --name $CLUSTER_NAME \ --nodegroup-name $NODEGROUP_NAME \ --update-id $UPDATE_ID \ --query "update.status" \ --output text) done echo echo "업그레이드 상태: $STATUS" if [ "$STATUS" == "Successful" ]; then echo echo "=== 노드 그룹 업그레이드 완료 ===" echo "새 버전: $(aws eks describe-nodegroup \ --cluster-name $CLUSTER_NAME \ --nodegroup-name $NODEGROUP_NAME \ --query "nodegroup.version" \ --output text)" echo echo "=== 노드 상태 확인 ===" kubectl get nodes -l eks.amazonaws.com/nodegroup=$NODEGROUP_NAME else echo echo "=== 업그레이드 실패 ===" aws eks describe-update \ --name $CLUSTER_NAME \ --nodegroup-name $NODEGROUP_NAME \ --update-id $UPDATE_ID fi블루/그린 배포 스크립트:
bash#!/bin/bash # EKS 노드 그룹 블루/그린 업그레이드 스크립트 CLUSTER_NAME="my-cluster" OLD_NODEGROUP="my-nodegroup-v1" NEW_NODEGROUP="my-nodegroup-v2" TARGET_VERSION="1.28" NODE_TYPE="m5.large" NODE_COUNT=3 echo "=== EKS 노드 그룹 블루/그린 업그레이드 ===" echo "클러스터: $CLUSTER_NAME" echo "이전 노드 그룹: $OLD_NODEGROUP" echo "새 노드 그룹: $NEW_NODEGROUP" echo "대상 버전: $TARGET_VERSION" echo # 현재 노드 그룹 확인 echo "=== 현재 노드 그룹 확인 ===" aws eks list-nodegroups --cluster-name $CLUSTER_NAME # 새 노드 그룹 생성 echo echo "=== 새 노드 그룹 생성 ===" eksctl create nodegroup \ --cluster $CLUSTER_NAME \ --name $NEW_NODEGROUP \ --node-type $NODE_TYPE \ --nodes $NODE_COUNT \ --nodes-min $NODE_COUNT \ --nodes-max $(($NODE_COUNT * 2)) \ --node-labels "kubernetes.io/role=worker,environment=production,version=v2" \ --node-ami auto \ --kubernetes-version $TARGET_VERSION # 새 노드 그룹 상태 확인 echo echo "=== 새 노드 그룹 상태 확인 ===" kubectl get nodes -l eks.amazonaws.com/nodegroup=$NEW_NODEGROUP # 워크로드 마이그레이션 echo echo "=== 워크로드 마이그레이션 ===" echo "1. 노드 선호도를 사용하여 새 노드 그룹으로 워크로드 마이그레이션" echo "2. 다음 명령으로 파드 분포 확인:" echo " kubectl get pods -o wide --all-namespaces | grep <node-name>" # 사용자 확인 echo read -p "모든 워크로드가 새 노드 그룹으로 마이그레이션되었습니까? (y/n): " confirm if [[ $confirm != "y" ]]; then echo "이전 노드 그룹 삭제가 취소되었습니다. 수동으로 마이그레이션을 완료하세요." exit 1 fi # 이전 노드 그룹에 코드온 설정 echo echo "=== 이전 노드 그룹에 코드온 설정 ===" kubectl cordon -l eks.amazonaws.com/nodegroup=$OLD_NODEGROUP # 이전 노드 그룹 드레이닝 echo echo "=== 이전 노드 그룹 드레이닝 ===" kubectl drain --ignore-daemonsets --delete-emptydir-data -l eks.amazonaws.com/nodegroup=$OLD_NODEGROUP # 이전 노드 그룹 삭제 echo echo "=== 이전 노드 그룹 삭제 ===" eksctl delete nodegroup \ --cluster $CLUSTER_NAME \ --name $OLD_NODEGROUP echo echo "=== 블루/그린 업그레이드 완료 ===" echo "현재 노드 그룹:" aws eks list-nodegroups --cluster-name $CLUSTER_NAMETerraform을 사용한 블루/그린 배포:
hcl# 현재 활성 노드 그룹 버전 변수 variable "active_version" { description = "현재 활성 노드 그룹 버전 (blue 또는 green)" default = "blue" } # 블루 노드 그룹 resource "aws_eks_node_group" "blue" { cluster_name = aws_eks_cluster.main.name node_group_name = "blue-nodegroup" node_role_arn = aws_iam_role.node_role.arn subnet_ids = var.private_subnet_ids scaling_config { desired_size = var.active_version == "blue" ? var.desired_nodes : 0 min_size = var.active_version == "blue" ? var.min_nodes : 0 max_size = var.active_version == "blue" ? var.max_nodes : 0 } version = "1.27" # 현재 버전 labels = { "environment" = "production" "version" = "blue" } lifecycle { ignore_changes = [scaling_config[0].desired_size] } } # 그린 노드 그룹 (새 버전) resource "aws_eks_node_group" "green" { cluster_name = aws_eks_cluster.main.name node_group_name = "green-nodegroup" node_role_arn = aws_iam_role.node_role.arn subnet_ids = var.private_subnet_ids scaling_config { desired_size = var.active_version == "green" ? var.desired_nodes : 0 min_size = var.active_version == "green" ? var.min_nodes : 0 max_size = var.active_version == "green" ? var.max_nodes : 0 } version = "1.28" # 새 버전 labels = { "environment" = "production" "version" = "green" } lifecycle { ignore_changes = [scaling_config[0].desired_size] } }
다른 옵션들의 문제점:
- A. 모든 노드를 동시에 종료하고 새 버전으로 교체: 이 방법은 모든 워크로드가 동시에 중단되어 서비스 가용성에 심각한 영향을 미칩니다.
- C. 노드 그룹 업그레이드 없이 컨트롤 플레인만 업그레이드: 노드 그룹을 업그레이드하지 않으면 새로운 Kubernetes 기능을 완전히 활용할 수 없으며, 버전 차이가 커질수록 호환성 문제가 발생할 수 있습니다.
- D. 수동으로 각 노드의 kubelet 버전 업그레이드: EKS 관리형 노드에서는 이 방법이 권장되지 않으며, 오류 가능성이 높고 일관성을 유지하기 어렵습니다.
A. 애드온 업그레이드 무시
B. 컨트롤 플레인 업그레이드 전에 모든 애드온 업그레이드
C. 컨트롤 플레인 업그레이드 후 호환되는 애드온 버전으로 업그레이드
D. 모든 애드온 제거 후 재설치
정답 및 설명
정답: C. 컨트롤 플레인 업그레이드 후 호환되는 애드온 버전으로 업그레이드
설명: Amazon EKS 클러스터 업그레이드 중 애드온 관리에 대한 가장 올바른 접근 방식은 컨트롤 플레인 업그레이드 후 호환되는 애드온 버전으로 업그레이드하는 것입니다. 이 접근 방식은 Kubernetes 버전과 애드온 간의 호환성을 보장하고, 업그레이드 과정에서 발생할 수 있는 문제를 최소화합니다.
컨트롤 플레인 업그레이드 후 애드온 업그레이드의 주요 이점:
버전 호환성 보장:
- 각 Kubernetes 버전에 맞는 호환 애드온 버전 선택 가능
- 컨트롤 플레인 API와 애드온 간의 호환성 문제 방지
- 안정적인 업그레이드 경로 제공
단계적 업그레이드 가능:
- 컨트롤 플레인 업그레이드 검증 후 애드온 업그레이드
- 문제 발생 시 원인 격리 용이
- 각 단계별 검증 가능
EKS 관리형 애드온 활용:
- AWS에서 관리하는 애드온 수명 주기
- 호환성이 검증된 버전 제공
- 자동 보안 패치 및 업데이트
구현 방법:
EKS 관리형 애드온 업그레이드:
bash# 사용 가능한 애드온 버전 확인 aws eks describe-addon-versions \ --addon-name vpc-cni \ --kubernetes-version 1.28 # 애드온 업그레이드 aws eks update-addon \ --cluster-name my-cluster \ --addon-name vpc-cni \ --addon-version v1.13.0-eksbuild.1 \ --resolve-conflicts PRESERVE주요 EKS 애드온 업그레이드:
bash# VPC CNI 업그레이드 aws eks update-addon \ --cluster-name my-cluster \ --addon-name vpc-cni \ --addon-version v1.13.0-eksbuild.1 # CoreDNS 업그레이드 aws eks update-addon \ --cluster-name my-cluster \ --addon-name coredns \ --addon-version v1.9.3-eksbuild.3 # kube-proxy 업그레이드 aws eks update-addon \ --cluster-name my-cluster \ --addon-name kube-proxy \ --addon-version v1.28.1-eksbuild.1자체 관리형 애드온 업그레이드:
bash# Helm을 사용한 애드온 업그레이드 helm repo update helm upgrade --install metrics-server metrics-server/metrics-server \ --namespace kube-system \ --version 3.8.2 \ --set apiService.create=true
주요 EKS 애드온 및 호환성:
Amazon VPC CNI:
- 네트워크 인터페이스 관리
- 파드 IP 할당
- 버전 호환성 중요
CoreDNS:
- 클러스터 내 DNS 서비스
- 서비스 디스커버리
- Kubernetes 버전별 권장 버전 존재
kube-proxy:
- 네트워크 프록시
- 서비스 IP 라우팅
- 컨트롤 플레인 버전과 일치 권장
기타 일반 애드온:
- Cluster Autoscaler
- Metrics Server
- AWS Load Balancer Controller
- External DNS
애드온 업그레이드 시 고려 사항:
충돌 해결 전략:
- OVERWRITE: 기존 설정 덮어쓰기
- PRESERVE: 기존 사용자 지정 설정 유지
- NONE: 충돌 시 업그레이드 실패
업그레이드 순서:
- 중요도 및 의존성에 따른 순서 결정
- 일반적으로 CNI → CoreDNS → kube-proxy → 기타 애드온
업그레이드 검증:
- 각 애드온 업그레이드 후 기능 검증
- 로그 및 이벤트 모니터링
- 워크로드 영향 확인
모범 사례:
애드온 버전 호환성 확인:
bash# 각 Kubernetes 버전에 대한 호환 애드온 버전 확인 aws eks describe-addon-versions \ --kubernetes-version 1.28 \ --query "addons[].{Name:addonName,LatestVersion:addonVersions[0].addonVersion}"업그레이드 전 애드온 상태 확인:
bash# 현재 애드온 상태 확인 aws eks describe-addon \ --cluster-name my-cluster \ --addon-name vpc-cni # 애드온 파드 상태 확인 kubectl get pods -n kube-system -l k8s-app=aws-node단계적 애드온 업그레이드:
- 한 번에 하나의 애드온만 업그레이드
- 각 업그레이드 후 검증
- 문제 발생 시 롤백 준비
사용자 지정 설정 백업:
bash# 애드온 구성 백업 kubectl get configmap aws-node -n kube-system -o yaml > vpc-cni-configmap-backup.yaml
실제 구현 예시:
애드온 업그레이드 스크립트:
bash#!/bin/bash # EKS 애드온 업그레이드 스크립트 CLUSTER_NAME="my-cluster" KUBERNETES_VERSION="1.28" echo "=== EKS 애드온 업그레이드 ===" echo "클러스터: $CLUSTER_NAME" echo "Kubernetes 버전: $KUBERNETES_VERSION" echo # 현재 애드온 버전 확인 echo "=== 현재 애드온 버전 ===" aws eks describe-addon \ --cluster-name $CLUSTER_NAME \ --addon-name vpc-cni \ --query "addon.addonVersion" \ --output text aws eks describe-addon \ --cluster-name $CLUSTER_NAME \ --addon-name coredns \ --query "addon.addonVersion" \ --output text aws eks describe-addon \ --cluster-name $CLUSTER_NAME \ --addon-name kube-proxy \ --query "addon.addonVersion" \ --output text # 호환되는 애드온 버전 확인 echo echo "=== 호환되는 애드온 버전 ===" VPC_CNI_VERSION=$(aws eks describe-addon-versions \ --addon-name vpc-cni \ --kubernetes-version $KUBERNETES_VERSION \ --query "addons[0].addonVersions[0].addonVersion" \ --output text) COREDNS_VERSION=$(aws eks describe-addon-versions \ --addon-name coredns \ --kubernetes-version $KUBERNETES_VERSION \ --query "addons[0].addonVersions[0].addonVersion" \ --output text) KUBE_PROXY_VERSION=$(aws eks describe-addon-versions \ --addon-name kube-proxy \ --kubernetes-version $KUBERNETES_VERSION \ --query "addons[0].addonVersions[0].addonVersion" \ --output text) echo "VPC CNI: $VPC_CNI_VERSION" echo "CoreDNS: $COREDNS_VERSION" echo "kube-proxy: $KUBE_PROXY_VERSION" # 사용자 확인 echo read -p "애드온 업그레이드를 시작하시겠습니까? (y/n): " confirm if [[ $confirm != "y" ]]; then echo "업그레이드가 취소되었습니다." exit 1 fi # VPC CNI 업그레이드 echo echo "=== VPC CNI 업그레이드 ===" aws eks update-addon \ --cluster-name $CLUSTER_NAME \ --addon-name vpc-cni \ --addon-version $VPC_CNI_VERSION \ --resolve-conflicts PRESERVE # VPC CNI 상태 확인 echo echo "=== VPC CNI 상태 확인 ===" sleep 30 kubectl get pods -n kube-system -l k8s-app=aws-node # CoreDNS 업그레이드 echo echo "=== CoreDNS 업그레이드 ===" aws eks update-addon \ --cluster-name $CLUSTER_NAME \ --addon-name coredns \ --addon-version $COREDNS_VERSION \ --resolve-conflicts PRESERVE # CoreDNS 상태 확인 echo echo "=== CoreDNS 상태 확인 ===" sleep 30 kubectl get pods -n kube-system -l k8s-app=kube-dns # kube-proxy 업그레이드 echo echo "=== kube-proxy 업그레이드 ===" aws eks update-addon \ --cluster-name $CLUSTER_NAME \ --addon-name kube-proxy \ --addon-version $KUBE_PROXY_VERSION \ --resolve-conflicts PRESERVE # kube-proxy 상태 확인 echo echo "=== kube-proxy 상태 확인 ===" sleep 30 kubectl get pods -n kube-system -l k8s-app=kube-proxy echo echo "=== 애드온 업그레이드 완료 ===" echo "현재 애드온 버전:" aws eks describe-addon \ --cluster-name $CLUSTER_NAME \ --addon-name vpc-cni \ --query "addon.addonVersion" \ --output text aws eks describe-addon \ --cluster-name $CLUSTER_NAME \ --addon-name coredns \ --query "addon.addonVersion" \ --output text aws eks describe-addon \ --cluster-name $CLUSTER_NAME \ --addon-name kube-proxy \ --query "addon.addonVersion" \ --output textTerraform을 사용한 애드온 관리:
hcl# EKS 클러스터 정의 resource "aws_eks_cluster" "main" { name = "my-cluster" role_arn = aws_iam_role.eks_cluster.arn version = "1.28" vpc_config { subnet_ids = var.subnet_ids security_group_ids = [aws_security_group.eks_cluster.id] } } # VPC CNI 애드온 resource "aws_eks_addon" "vpc_cni" { cluster_name = aws_eks_cluster.main.name addon_name = "vpc-cni" addon_version = "v1.13.0-eksbuild.1" # 1.28 호환 버전 resolve_conflicts = "PRESERVE" depends_on = [ aws_eks_cluster.main ] } # CoreDNS 애드온 resource "aws_eks_addon" "coredns" { cluster_name = aws_eks_cluster.main.name addon_name = "coredns" addon_version = "v1.9.3-eksbuild.3" # 1.28 호환 버전 resolve_conflicts = "PRESERVE" depends_on = [ aws_eks_cluster.main, aws_eks_node_group.main ] } # kube-proxy 애드온 resource "aws_eks_addon" "kube_proxy" { cluster_name = aws_eks_cluster.main.name addon_name = "kube-proxy" addon_version = "v1.28.1-eksbuild.1" # 1.28 호환 버전 resolve_conflicts = "PRESERVE" depends_on = [ aws_eks_cluster.main ] }자체 관리형 애드온 업그레이드 스크립트:
bash#!/bin/bash # 자체 관리형 애드온 업그레이드 스크립트 CLUSTER_NAME="my-cluster" KUBERNETES_VERSION="1.28" echo "=== 자체 관리형 애드온 업그레이드 ===" echo "클러스터: $CLUSTER_NAME" echo "Kubernetes 버전: $KUBERNETES_VERSION" echo # Helm 리포지토리 업데이트 echo "=== Helm 리포지토리 업데이트 ===" helm repo update # Metrics Server 업그레이드 echo echo "=== Metrics Server 업그레이드 ===" helm upgrade --install metrics-server metrics-server/metrics-server \ --namespace kube-system \ --version 3.8.2 \ --set apiService.create=true # AWS Load Balancer Controller 업그레이드 echo echo "=== AWS Load Balancer Controller 업그레이드 ===" helm upgrade --install aws-load-balancer-controller eks/aws-load-balancer-controller \ --namespace kube-system \ --set clusterName=$CLUSTER_NAME \ --set serviceAccount.create=false \ --set serviceAccount.name=aws-load-balancer-controller # Cluster Autoscaler 업그레이드 echo echo "=== Cluster Autoscaler 업그레이드 ===" helm upgrade --install cluster-autoscaler autoscaler/cluster-autoscaler \ --namespace kube-system \ --set autoDiscovery.clusterName=$CLUSTER_NAME \ --set awsRegion=$(aws configure get region) \ --set rbac.create=true \ --set extraArgs.skip-nodes-with-system-pods=false echo echo "=== 자체 관리형 애드온 업그레이드 완료 ===" kubectl get pods -n kube-system | grep -E 'metrics-server|aws-load-balancer-controller|cluster-autoscaler'
다른 옵션들의 문제점:
- A. 애드온 업그레이드 무시: 애드온을 업그레이드하지 않으면 Kubernetes 버전과의 호환성 문제가 발생할 수 있으며, 보안 패치나 버그 수정이 적용되지 않습니다.
- B. 컨트롤 플레인 업그레이드 전에 모든 애드온 업그레이드: 컨트롤 플레인 업그레이드 전에 애드온을 업그레이드하면 새 버전의 애드온이 이전 버전의 컨트롤 플레인과 호환되지 않을 수 있습니다.
- D. 모든 애드온 제거 후 재설치: 이 방법은 불필요하게 복잡하고 위험하며, 애드온 구성 및 설정이 손실될 수 있습니다.
A. 즉시 새 클러스터 생성
B. 문제 발생 시 AWS 지원팀에만 의존
C. 체계적인 문제 해결 접근 방식 및 로그 분석 사용
D. 업그레이드 문제 무시
정답 및 설명
정답: C. 체계적인 문제 해결 접근 방식 및 로그 분석 사용
설명: Amazon EKS 클러스터 업그레이드 중 발생할 수 있는 문제를 해결하기 위한 가장 효과적인 접근 방식은 체계적인 문제 해결 접근 방식 및 로그 분석을 사용하는 것입니다. 이 접근 방식은 문제의 근본 원인을 식별하고, 적절한 해결책을 적용하며, 유사한 문제의 재발을 방지하는 데 도움이 됩니다.
체계적인 문제 해결 접근 방식의 주요 구성 요소:
문제 식별 및 정의:
- 증상 및 영향 범위 파악
- 문제 발생 시점 및 조건 확인
- 정상 동작과의 차이점 식별
정보 수집 및 분석:
- 로그 및 이벤트 수집
- 리소스 상태 및 구성 확인
- 오류 메시지 및 패턴 분석
가설 수립 및 검증:
- 가능한 원인 식별
- 가설 테스트 및 검증
- 근본 원인 확인
해결책 구현 및 검증:
- 적절한 해결책 적용
- 해결책 효과 검증
- 문제 재발 방지 조치
구현 방법:
업그레이드 문제 진단:
bash# 클러스터 상태 확인 aws eks describe-cluster \ --name my-cluster \ --query "cluster.status" # 업그레이드 상태 확인 aws eks describe-update \ --name my-cluster \ --update-id <update-id> # 컨트롤 플레인 로그 확인 aws eks update-cluster-config \ --name my-cluster \ --logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}' # CloudWatch Logs에서 로그 확인 aws logs filter-log-events \ --log-group-name /aws/eks/my-cluster/cluster \ --filter-pattern "Error"노드 그룹 문제 진단:
bash# 노드 그룹 상태 확인 aws eks describe-nodegroup \ --cluster-name my-cluster \ --nodegroup-name my-nodegroup # 노드 상태 확인 kubectl get nodes kubectl describe node <node-name> # 노드 로그 확인 kubectl logs -n kube-system <node-agent-pod>애드온 문제 진단:
bash# 애드온 상태 확인 aws eks describe-addon \ --cluster-name my-cluster \ --addon-name vpc-cni # 애드온 파드 상태 확인 kubectl get pods -n kube-system -l k8s-app=aws-node kubectl describe pod -n kube-system <addon-pod-name> kubectl logs -n kube-system <addon-pod-name>
일반적인 업그레이드 문제 및 해결 방법:
컨트롤 플레인 업그레이드 실패:
- 증상: 업그레이드 상태가 "Failed"로 표시됨
- 원인: API 서버 구성 문제, 리소스 제약, 네트워크 문제
- 해결 방법:
- 업그레이드 오류 메시지 확인
- AWS 지원팀에 문의
- 클러스터 상태 및 로그 제공
노드 그룹 업그레이드 실패:
- 증상: 노드가 Ready 상태가 되지 않음, 파드 스케줄링 실패
- 원인: 인스턴스 시작 문제, kubelet 구성 오류, CNI 문제
- 해결 방법:
- 노드 로그 확인
- 인스턴스 상태 확인
- 보안 그룹 및 IAM 권한 확인
애드온 업그레이드 문제:
- 증상: 애드온 파드가 CrashLoopBackOff 또는 Error 상태
- 원인: 버전 호환성 문제, 구성 충돌, 리소스 제약
- 해결 방법:
- 파드 로그 확인
- 구성 충돌 해결
- 호환되는 버전으로 다시 시도
워크로드 호환성 문제:
- 증상: 애플리케이션 파드 시작 실패, API 오류
- 원인: 더 이상 사용되지 않는 API 사용, 호환되지 않는 기능
- 해결 방법:
- 매니페스트 업데이트
- 애플리케이션 로그 확인
- 호환성 문제 해결
모범 사례:
문제 해결을 위한 로그 수집:
bash# 클러스터 정보 수집 kubectl cluster-info dump > cluster-info.txt # 노드 정보 수집 kubectl describe nodes > nodes-info.txt # 시스템 파드 로그 수집 kubectl logs -n kube-system -l k8s-app=aws-node > vpc-cni-logs.txt kubectl logs -n kube-system -l k8s-app=kube-dns > coredns-logs.txt kubectl logs -n kube-system -l k8s-app=kube-proxy > kube-proxy-logs.txt # 이벤트 수집 kubectl get events --all-namespaces --sort-by='.lastTimestamp' > events.txt롤백 절차 준비:
bash# 노드 그룹 롤백 (새 노드 그룹 생성) eksctl create nodegroup \ --cluster my-cluster \ --name rollback-nodegroup \ --node-type m5.large \ --nodes 3 \ --nodes-min 3 \ --nodes-max 6 \ --node-ami auto \ --kubernetes-version 1.27 # 이전 버전 # 워크로드 마이그레이션 kubectl cordon -l eks.amazonaws.com/nodegroup=problematic-nodegroup kubectl drain --ignore-daemonsets --delete-emptydir-data -l eks.amazonaws.com/nodegroup=problematic-nodegroup문제 해결 문서화:
markdown# 업그레이드 문제 해결 보고서 ## 문제 설명 - 증상: 노드 그룹 업그레이드 후 CoreDNS 파드가 CrashLoopBackOff 상태 - 영향: 서비스 디스커버리 실패, 애플리케이션 연결 문제 - 발생 시점: 2023-07-15 14:30 UTC, 노드 그룹 업그레이드 직후 ## 조사 과정 1. CoreDNS 파드 상태 확인 2. CoreDNS 로그 분석 3. 노드 상태 및 리소스 확인 4. 네트워크 정책 검토 ## 발견 사항 - CoreDNS 파드 로그에서 구성 오류 발견 - 업그레이드 중 CoreDNS ConfigMap이 잘못 수정됨 ## 해결 방법 1. CoreDNS ConfigMap 복원 2. CoreDNS 파드 재시작 3. 서비스 연결 확인 ## 예방 조치 1. 업그레이드 전 중요 구성 백업 2. 자동화된 검증 테스트 구현 3. 단계적 업그레이드 프로세스 개선AWS 지원팀과 효과적으로 협력:
- 명확한 문제 설명 제공
- 관련 로그 및 오류 메시지 공유
- 수행한 문제 해결 단계 설명
실제 구현 예시:
업그레이드 문제 해결 스크립트:
bash#!/bin/bash # EKS 업그레이드 문제 해결 스크립트 CLUSTER_NAME="my-cluster" PROBLEM_TYPE=$1 # control-plane, nodegroup, addon echo "=== EKS 업그레이드 문제 해결 ===" echo "클러스터: $CLUSTER_NAME" echo "문제 유형: $PROBLEM_TYPE" echo # 진단 정보 디렉토리 생성 TIMESTAMP=$(date +%Y%m%d-%H%M%S) DIAG_DIR="eks-diag-$TIMESTAMP" mkdir -p $DIAG_DIR # 클러스터 정보 수집 echo "=== 클러스터 정보 수집 ===" aws eks describe-cluster --name $CLUSTER_NAME > $DIAG_DIR/cluster-info.json kubectl cluster-info dump > $DIAG_DIR/cluster-info-dump.txt kubectl get nodes -o wide > $DIAG_DIR/nodes.txt kubectl get pods --all-namespaces -o wide > $DIAG_DIR/pods.txt kubectl get events --all-namespaces --sort-by='.lastTimestamp' > $DIAG_DIR/events.txt # 문제 유형별 진단 case $PROBLEM_TYPE in control-plane) echo "=== 컨트롤 플레인 문제 진단 ===" # 업그레이드 상태 확인 aws eks list-updates --name $CLUSTER_NAME > $DIAG_DIR/updates.json # 컨트롤 플레인 로그 확인 echo "컨트롤 플레인 로그를 확인하려면 CloudWatch Logs 콘솔에서 다음 로그 그룹을 확인하세요:" echo "/aws/eks/$CLUSTER_NAME/cluster" ;; nodegroup) echo "=== 노드 그룹 문제 진단 ===" # 노드 그룹 목록 및 상태 aws eks list-nodegroups --cluster-name $CLUSTER_NAME > $DIAG_DIR/nodegroups.json # 각 노드 그룹 상세 정보 for NG in $(aws eks list-nodegroups --cluster-name $CLUSTER_NAME --query 'nodegroups[*]' --output text); do aws eks describe-nodegroup --cluster-name $CLUSTER_NAME --nodegroup-name $NG > $DIAG_DIR/nodegroup-$NG.json done # 노드 상태 및 정보 kubectl describe nodes > $DIAG_DIR/nodes-describe.txt # 노드 관련 파드 로그 kubectl logs -n kube-system -l k8s-app=aws-node > $DIAG_DIR/vpc-cni-logs.txt ;; addon) echo "=== 애드온 문제 진단 ===" # 애드온 목록 및 상태 aws eks list-addons --cluster-name $CLUSTER_NAME > $DIAG_DIR/addons.json # 각 애드온 상세 정보 for ADDON in $(aws eks list-addons --cluster-name $CLUSTER_NAME --query 'addons[*]' --output text); do aws eks describe-addon --cluster-name $CLUSTER_NAME --addon-name $ADDON > $DIAG_DIR/addon-$ADDON.json done # 주요 애드온 파드 로그 kubectl logs -n kube-system -l k8s-app=kube-dns > $DIAG_DIR/coredns-logs.txt kubectl logs -n kube-system -l k8s-app=kube-proxy > $DIAG_DIR/kube-proxy-logs.txt kubectl logs -n kube-system -l k8s-app=aws-node > $DIAG_DIR/vpc-cni-logs.txt ;; *) echo "알 수 없는 문제 유형입니다. control-plane, nodegroup, addon 중 하나를 지정하세요." exit 1 ;; esac echo echo "=== 진단 정보 수집 완료 ===" echo "진단 정보가 $DIAG_DIR 디렉토리에 저장되었습니다." echo "이 정보를 사용하여 문제를 분석하거나 AWS 지원팀에 제공하세요."업그레이드 롤백 스크립트:
bash#!/bin/bash # EKS 업그레이드 롤백 스크립트 CLUSTER_NAME="my-cluster" PREVIOUS_VERSION="1.27" PROBLEMATIC_NODEGROUP="my-nodegroup" echo "=== EKS 업그레이드 롤백 ===" echo "클러스터: $CLUSTER_NAME" echo "이전 버전: $PREVIOUS_VERSION" echo "문제 노드 그룹: $PROBLEMATIC_NODEGROUP" echo # 롤백 노드 그룹 생성 echo "=== 롤백 노드 그룹 생성 ===" eksctl create nodegroup \ --cluster $CLUSTER_NAME \ --name rollback-nodegroup \ --node-type m5.large \ --nodes 3 \ --nodes-min 3 \ --nodes-max 6 \ --node-ami auto \ --kubernetes-version $PREVIOUS_VERSION # 롤백 노드 그룹 상태 확인 echo echo "=== 롤백 노드 그룹 상태 확인 ===" kubectl get nodes -l eks.amazonaws.com/nodegroup=rollback-nodegroup # 워크로드 마이그레이션 echo echo "=== 워크로드 마이그레이션 ===" echo "문제 노드 그룹에 코드온 설정..." kubectl cordon -l eks.amazonaws.com/nodegroup=$PROBLEMATIC_NODEGROUP echo "파드 드레이닝..." kubectl drain --ignore-daemonsets --delete-emptydir-data -l eks.amazonaws.com/nodegroup=$PROBLEMATIC_NODEGROUP # 파드 재배포 확인 echo echo "=== 파드 재배포 확인 ===" kubectl get pods --all-namespaces -o wide | grep -v "Running\|Completed" # 문제 노드 그룹 삭제 echo read -p "문제 노드 그룹을 삭제하시겠습니까? (y/n): " confirm if [[ $confirm == "y" ]]; then echo "문제 노드 그룹 삭제..." eksctl delete nodegroup \ --cluster $CLUSTER_NAME \ --name $PROBLEMATIC_NODEGROUP else echo "문제 노드 그룹 삭제를 건너뜁니다." fi echo echo "=== 롤백 완료 ===" echo "현재 노드 상태:" kubectl get nodes업그레이드 문제 해결 가이드:
markdown# EKS 업그레이드 문제 해결 가이드 ## 컨트롤 플레인 업그레이드 문제 ### 증상 - 업그레이드 상태가 "Failed"로 표시됨 - API 서버 응답 지연 또는 오류 - 클러스터 작업 불가 ### 진단 단계 1. 업그레이드 상태 확인: ``` aws eks describe-update --name my-cluster --update-id <update-id> ``` 2. 컨트롤 플레인 로그 확인: - CloudWatch Logs에서 `/aws/eks/my-cluster/cluster` 로그 그룹 검토 - 오류 메시지 및 패턴 식별 3. 클러스터 상태 확인: ``` kubectl get componentstatuses kubectl get nodes kubectl get pods --all-namespaces ``` ### 해결 방법 1. AWS 지원팀에 문의 2. 진단 정보 제공 3. 지원팀 지침에 따라 조치 ## 노드 그룹 업그레이드 문제 ### 증상 - 노드가 Ready 상태가 되지 않음 - 파드 스케줄링 실패 - 노드 그룹 업그레이드 상태가 "Failed"로 표시됨 ### 진단 단계 1. 노드 그룹 상태 확인: ``` aws eks describe-nodegroup --cluster-name my-cluster --nodegroup-name my-nodegroup ``` 2. 노드 상태 및 이벤트 확인: ``` kubectl describe node <node-name> kubectl get events --field-selector involvedObject.name=<node-name> ``` 3. 인스턴스 상태 확인: - EC2 콘솔에서 인스턴스 상태 확인 - 인스턴스 시작 문제 식별 ### 해결 방법 1. 롤백 노드 그룹 생성 2. 워크로드 마이그레이션 3. 문제 노드 그룹 삭제 ## 애드온 업그레이드 문제 ### 증상 - 애드온 파드가 CrashLoopBackOff 또는 Error 상태 - 네트워크 또는 DNS 문제 - 애드온 업그레이드 상태가 "Failed"로 표시됨 ### 진단 단계 1. 애드온 상태 확인: ``` aws eks describe-addon --cluster-name my-cluster --addon-name <addon-name> ``` 2. 애드온 파드 상태 및 로그 확인: ``` kubectl get pods -n kube-system -l k8s-app=<addon-label> kubectl logs -n kube-system <addon-pod-name> ``` 3. 구성 충돌 확인: - 사용자 지정 구성과 기본 구성 비교 - 충돌 식별 ### 해결 방법 1. 이전 버전으로 롤백: ``` aws eks update-addon --cluster-name my-cluster --addon-name <addon-name> --addon-version <previous-version> --resolve-conflicts OVERWRITE ``` 2. 구성 충돌 해결 후 다시 시도: ``` aws eks update-addon --cluster-name my-cluster --addon-name <addon-name> --addon-version <target-version> --resolve-conflicts PRESERVE ```
다른 옵션들의 문제점:
- A. 즉시 새 클러스터 생성: 이는 극단적인 접근 방식으로, 시간과 리소스가 많이 소요되며, 근본 원인을 해결하지 않고 회피하는 방법입니다.
- B. 문제 발생 시 AWS 지원팀에만 의존: AWS 지원팀은 중요한 리소스이지만, 기본적인 문제 해결 단계를 먼저 수행하면 해결 시간을 단축할 수 있습니다.
- D. 업그레이드 문제 무시: 업그레이드 문제를 무시하면 클러스터 안정성, 보안 및 성능에 장기적인 영향을 미칠 수 있습니다.
A. 노드 수 확인만 수행
B. 클러스터 버전 확인만 수행
C. 시스템 구성 요소, 워크로드 기능 및 성능 메트릭을 포함한 다단계 검증 수행
D. 업그레이드 후 검증 없이 즉시 프로덕션 사용
정답 및 설명
정답: C. 시스템 구성 요소, 워크로드 기능 및 성능 메트릭을 포함한 다단계 검증 수행
설명: Amazon EKS 클러스터 업그레이드 후 검증을 위한 가장 포괄적인 접근 방식은 시스템 구성 요소, 워크로드 기능 및 성능 메트릭을 포함한 다단계 검증을 수행하는 것입니다. 이 접근 방식은 업그레이드가 성공적으로 완료되었고 클러스터가 예상대로 작동하는지 확인하는 데 도움이 됩니다.
다단계 검증의 주요 구성 요소:
시스템 구성 요소 검증:
- 컨트롤 플레인 구성 요소 상태
- 노드 상태 및 버전
- 시스템 파드 및 애드온 상태
워크로드 기능 검증:
- 애플리케이션 배포 및 확장
- 서비스 연결 및 라우팅
- 스토리지 및 볼륨 기능
성능 메트릭 검증:
- 리소스 사용량 및 효율성
- 지연 시간 및 처리량
- 오류율 및 가용성
구현 방법:
시스템 구성 요소 검증:
bash# 클러스터 버전 확인 aws eks describe-cluster \ --name my-cluster \ --query "cluster.version" \ --output text # 컨트롤 플레인 구성 요소 상태 확인 kubectl get componentstatuses # 노드 상태 및 버전 확인 kubectl get nodes -o wide # 시스템 파드 상태 확인 kubectl get pods -n kube-system워크로드 기능 검증:
bash# 테스트 배포 생성 kubectl create deployment nginx-test --image=nginx # 배포 확장 kubectl scale deployment nginx-test --replicas=3 # 서비스 생성 및 연결 테스트 kubectl expose deployment nginx-test --port=80 --type=ClusterIP kubectl run -it --rm --restart=Never busybox --image=busybox -- wget -O- nginx-test # 볼륨 기능 테스트 kubectl apply -f - <<EOF apiVersion: v1 kind: PersistentVolumeClaim metadata: name: test-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi EOF kubectl apply -f - <<EOF apiVersion: v1 kind: Pod metadata: name: volume-test spec: containers: - name: volume-test image: busybox command: ["sh", "-c", "echo 'test' > /data/test.txt && sleep 3600"] volumeMounts: - name: data mountPath: /data volumes: - name: data persistentVolumeClaim: claimName: test-pvc EOF성능 메트릭 검증:
bash# 노드 리소스 사용량 확인 kubectl top nodes # 파드 리소스 사용량 확인 kubectl top pods --all-namespaces # 로드 테스트 수행 kubectl run -it --rm --restart=Never loadtest --image=busybox -- sh -c "while true; do wget -q -O- http://nginx-test; done"
검증 영역 및 체크리스트:
컨트롤 플레인 검증:
- API 서버 응답성
- etcd 상태 및 성능
- 컨트롤러 관리자 및 스케줄러 기능
데이터 플레인 검증:
- 노드 상태 및 가용성
- kubelet 기능
- 컨테이너 런타임 상태
네트워킹 검증:
- 파드 간 통신
- 서비스 디스커버리
- 인그레스 및 이그레스 트래픽
스토리지 검증:
- 볼륨 프로비저닝
- 데이터 지속성
- 스토리지 클래스 기능
보안 검증:
- 인증 및 권한 부여
- 네트워크 정책
- 암호화 및 보안 컨텍스트
모범 사례:
단계적 검증 접근 방식:
bash# 1단계: 시스템 구성 요소 검증 ./validate-system-components.sh # 2단계: 기본 워크로드 기능 검증 ./validate-basic-workloads.sh # 3단계: 고급 기능 검증 ./validate-advanced-features.sh # 4단계: 성능 및 부하 테스트 ./validate-performance.sh자동화된 검증 테스트:
yaml# 검증 작업 정의 apiVersion: batch/v1 kind: Job metadata: name: cluster-validation spec: template: spec: containers: - name: validation image: validation-tools:latest command: ["/scripts/validate-cluster.sh"] restartPolicy: Never검증 결과 문서화:
bash# 검증 결과 수집 kubectl get nodes -o wide > validation-results/nodes.txt kubectl get pods --all-namespaces > validation-results/pods.txt kubectl get events --all-namespaces --sort-by='.lastTimestamp' > validation-results/events.txt # 성능 메트릭 수집 kubectl top nodes > validation-results/node-metrics.txt kubectl top pods --all-namespaces > validation-results/pod-metrics.txt점진적인 프로덕션 트래픽 전환:
- 카나리 배포 사용
- 트래픽 점진적 증가
- 지표 모니터링 및 이상 탐지
실제 구현 예시:
포괄적인 검증 스크립트:
bash#!/bin/bash # EKS 클러스터 업그레이드 후 포괄적인 검증 스크립트 CLUSTER_NAME="my-cluster" echo "=== EKS 클러스터 업그레이드 검증 ===" echo "클러스터: $CLUSTER_NAME" echo # 결과 디렉토리 생성 TIMESTAMP=$(date +%Y%m%d-%H%M%S) RESULTS_DIR="validation-results-$TIMESTAMP" mkdir -p $RESULTS_DIR # 1. 시스템 구성 요소 검증 echo "=== 1. 시스템 구성 요소 검증 ===" # 클러스터 버전 확인 echo "클러스터 버전 확인..." CLUSTER_VERSION=$(aws eks describe-cluster --name $CLUSTER_NAME --query "cluster.version" --output text) echo "클러스터 버전: $CLUSTER_VERSION" echo $CLUSTER_VERSION > $RESULTS_DIR/cluster-version.txt # 컨트롤 플레인 상태 확인 echo echo "컨트롤 플레인 상태 확인..." kubectl get componentstatuses > $RESULTS_DIR/component-status.txt cat $RESULTS_DIR/component-status.txt # 노드 상태 확인 echo echo "노드 상태 확인..." kubectl get nodes -o wide > $RESULTS_DIR/nodes.txt cat $RESULTS_DIR/nodes.txt # 시스템 파드 상태 확인 echo echo "시스템 파드 상태 확인..." kubectl get pods -n kube-system > $RESULTS_DIR/system-pods.txt cat $RESULTS_DIR/system-pods.txt # 2. 워크로드 기능 검증 echo echo "=== 2. 워크로드 기능 검증 ===" # 네임스페이스 생성 echo "테스트 네임스페이스 생성..." kubectl create namespace validation-test # 배포 테스트 echo echo "배포 테스트..." kubectl create deployment nginx-test --image=nginx -n validation-test sleep 10 kubectl get deployment -n validation-test > $RESULTS_DIR/deployment-test.txt cat $RESULTS_DIR/deployment-test.txt # 확장 테스트 echo echo "확장 테스트..." kubectl scale deployment nginx-test --replicas=3 -n validation-test sleep 10 kubectl get pods -n validation-test > $RESULTS_DIR/scaling-test.txt cat $RESULTS_DIR/scaling-test.txt # 서비스 테스트 echo echo "서비스 테스트..." kubectl expose deployment nginx-test --port=80 --type=ClusterIP -n validation-test sleep 5 kubectl run -it --rm --restart=Never busybox --image=busybox -n validation-test -- wget -O- nginx-test > $RESULTS_DIR/service-test.txt 2>&1 || true cat $RESULTS_DIR/service-test.txt # 볼륨 테스트 echo echo "볼륨 테스트..." cat <<EOF | kubectl apply -f - -n validation-test apiVersion: v1 kind: PersistentVolumeClaim metadata: name: test-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi EOF sleep 5 kubectl get pvc -n validation-test > $RESULTS_DIR/volume-test.txt cat $RESULTS_DIR/volume-test.txt # 3. 성능 메트릭 검증 echo echo "=== 3. 성능 메트릭 검증 ===" # 노드 메트릭 echo "노드 메트릭 수집..." kubectl top nodes > $RESULTS_DIR/node-metrics.txt cat $RESULTS_DIR/node-metrics.txt # 파드 메트릭 echo echo "파드 메트릭 수집..." kubectl top pods --all-namespaces > $RESULTS_DIR/pod-metrics.txt head -n 10 $RESULTS_DIR/pod-metrics.txt # 이벤트 확인 echo echo "클러스터 이벤트 확인..." kubectl get events --all-namespaces --sort-by='.lastTimestamp' > $RESULTS_DIR/events.txt tail -n 10 $RESULTS_DIR/events.txt # 정리 echo echo "테스트 리소스 정리..." kubectl delete namespace validation-test echo echo "=== 검증 완료 ===" echo "검증 결과가 $RESULTS_DIR 디렉토리에 저장되었습니다." echo echo "검증 요약:" echo "- 클러스터 버전: $CLUSTER_VERSION" echo "- 노드 수: $(kubectl get nodes --no-headers | wc -l)" echo "- 시스템 파드 수: $(kubectl get pods -n kube-system --no-headers | wc -l)" echo "- 오류 상태 파드: $(kubectl get pods --all-namespaces | grep -v "Running\|Completed" | wc -l)"Terraform을 사용한 검증 인프라 구성:
hcl# 검증 네임스페이스 resource "kubernetes_namespace" "validation" { metadata { name = "validation" } } # 검증 배포 resource "kubernetes_deployment" "validation_app" { metadata { name = "validation-app" namespace = kubernetes_namespace.validation.metadata[0].name } spec { replicas = 3 selector { match_labels = { app = "validation-app" } } template { metadata { labels = { app = "validation-app" } } spec { container { name = "nginx" image = "nginx:latest" resources { limits = { cpu = "200m" memory = "256Mi" } requests = { cpu = "100m" memory = "128Mi" } } liveness_probe { http_get { path = "/" port = 80 } initial_delay_seconds = 3 period_seconds = 3 } } } } } } # 검증 서비스 resource "kubernetes_service" "validation_service" { metadata { name = "validation-service" namespace = kubernetes_namespace.validation.metadata[0].name } spec { selector = { app = kubernetes_deployment.validation_app.spec[0].template[0].metadata[0].labels.app } port { port = 80 target_port = 80 } type = "ClusterIP" } } # 검증 PVC resource "kubernetes_persistent_volume_claim" "validation_pvc" { metadata { name = "validation-pvc" namespace = kubernetes_namespace.validation.metadata[0].name } spec { access_modes = ["ReadWriteOnce"] resources { requests = { storage = "1Gi" } } } }검증 대시보드 구성:
yaml# Grafana 대시보드 ConfigMap apiVersion: v1 kind: ConfigMap metadata: name: cluster-validation-dashboard namespace: monitoring data: cluster-validation.json: | { "title": "Cluster Validation Dashboard", "panels": [ { "title": "Node Status", "type": "stat", "datasource": "Prometheus", "targets": [ { "expr": "sum(kube_node_status_condition{condition=\"Ready\", status=\"true\"})", "legendFormat": "Ready Nodes" } ] }, { "title": "Pod Status", "type": "gauge", "datasource": "Prometheus", "targets": [ { "expr": "sum(kube_pod_status_phase{phase=\"Running\"}) / sum(kube_pod_status_phase) * 100", "legendFormat": "Running Pods (%)" } ] }, { "title": "API Server Requests", "type": "timeseries", "datasource": "Prometheus", "targets": [ { "expr": "sum(rate(apiserver_request_total[5m])) by (code)", "legendFormat": "{{code}}" } ] }, { "title": "Node Resource Usage", "type": "timeseries", "datasource": "Prometheus", "targets": [ { "expr": "sum(node_cpu_seconds_total{mode=\"user\"}) by (instance)", "legendFormat": "CPU - {{instance}}" }, { "expr": "sum(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) by (instance) / sum(node_memory_MemTotal_bytes) by (instance) * 100", "legendFormat": "Memory - {{instance}}" } ] } ] }
다른 옵션들의 문제점:
- A. 노드 수 확인만 수행: 노드 수 확인은 기본적인 검증이지만, 노드 상태, 시스템 구성 요소, 워크로드 기능 등 중요한 측면을 놓칠 수 있습니다.
- B. 클러스터 버전 확인만 수행: 클러스터 버전 확인은 업그레이드가 완료되었는지 확인하는 데 도움이 되지만, 기능적 검증이 부족합니다.
- D. 업그레이드 후 검증 없이 즉시 프로덕션 사용: 검증 없이 프로덕션에 사용하는 것은 위험하며, 잠재적인 문제가 사용자에게 영향을 미칠 수 있습니다.