9. EKS 활용 사례 3 (Troubleshooting)
Update : 2025.08.07
EKS 디버깅 워크샵 – Amazon Q 기반 Kubernetes 문제 해결
이 가이드는 Amazon Q와 함께 마이크로서비스 기반 Kubernetes 애플리케이션에서 자주 발생하는 문제들을 어떻게 진단하고 수정하는지를 실습 중심으로 설명합니다.
각 시나리오는 다음 요소로 구성됩니다:
초기 정상 상태
문제를 의도적으로 유발하는 방법
증상 및 에러 메시지
문제 해결을 위한 Amazon Q 프롬프트
kubectl을 통한 결과 검증
1. Kubernetes 문제 해결 시나리오
1.1 Scenario 1: 잘못된 Service Selector
초기 상태
UI 서비스가 정상적으로 Catalog 서비스에 연결되어 상품 목록을 불러옵니다.
문제 유발 프롬프트:
cd ~/environment/eks-workshop-v2/
# 현재 catalog 서비스 정의 추출
kubectl get service catalog -n catalog -o yaml > catalog-service.yaml
# selector 값을 잘못된 값으로 변경
sed -i 's/app.kubernetes.io\/name: catalog/app.kubernetes.io\/name: catalog-wrong/g' catalog-service.yaml
# 변경된 서비스 적용
kubectl apply -f catalog-service.yaml
증상
UI에서 상품 목록을 로드할 때 오류 발생
UI 파드 로그에서 catalog 서비스 연결 거부 메시지
catalog 서비스는 존재하지만, 트래픽이 파드로 전달되지 않음
Amazon Q 프롬프트 예시 :
Kubernetes 애플리케이션의 UI가 EKS 클러스터 내 catalog 서비스에 연결되지 않습니다.
catalog 파드는 실행 중이지만, 서비스가 트래픽을 해당 파드로 라우팅하지 않고 있습니다.
서비스 셀렉터(selector) 불일치 여부를 어떻게 확인하고, 이를 어떻게 수정할 수 있을까요?
실행 결과는 아래와 같습니다:
## ✅ Catalog 서비스 연결 문제 해결 완료!
UI가 catalog 서비스에 연결되지 않는 문제를 성공적으로 해결했습니다.
### 🔍 발견된 문제
서비스 셀렉터 불일치:
• **파드 레이블**: app.kubernetes.io/name: catalog ✅
• **서비스 셀렉터**: app.kubernetes.io/name: catalog-wrong ❌
### 🛠️ 해결 과정
1. 문제 진단: 파드 레이블과 서비스 셀렉터 비교
2. 엔드포인트 확인: <none> 상태로 파드 연결 안됨 확인
3. YAML 재적용: kubectl apply -k 명령어로 올바른 설정 적용
4. 연결 테스트: HTTP 200 응답으로 정상 동작 확인
### 📊 수정 결과
수정 전:
NAME ENDPOINTS AGE
catalog <none> 72m
수정 후:
NAME ENDPOINTS AGE
catalog 10.11.74.186:8080 72m
### 🧪 연결 테스트 성공
bash
kubectl exec -n ui deployment/ui -- curl -s -o /dev/null -w "%{http_code}" http://catalog.catalog.svc:80/health
# 결과: 200 ✅
### 📋 진단 체크리스트
향후 유사한 문제 발생 시 사용할 수 있는 체크리스트:
1. 파드 레이블 확인: kubectl get pods -n <namespace> --show-labels
2. 서비스 셀렉터 확인: kubectl get service <name> -n <namespace> -o yaml
3. 엔드포인트 상태 확인: kubectl get endpoints <name> -n <namespace>
4. 연결 테스트: curl 명령어로 실제 연결 확인
📝 상세한 문제 해결 과정과 예방 조치는 ~/output/catalog-service-selector-fix.md 파일에 저장되었습니다.
이제 UI 애플리케이션이 catalog 서비스와 정상적으로 통신할 수 있습니다! 🎉
문제 검증 및 복구
# 서비스의 selector 확인
kubectl get service catalog -n catalog -o jsonpath='{.spec.selector}' | jq
# 파드 라벨 확인
kubectl get pods -n catalog -l app.kubernetes.io/name=catalog -o jsonpath='{.items[0].metadata.labels}' | jq
# 서비스에 바인딩된 엔드포인트 확인
kubectl get endpoints catalog -n catalog
1.2 Scenario 2: 리소스 제약 (Resource Constraints)
초기 상태 : Carts 서비스가 충분한 CPU 및 메모리 리소스를 갖고 정상적으로 동작함.
문제 유발 프롬프트:
# carts 디플로이먼트 추출
kubectl get deployment carts -n carts -o yaml > carts-deployment.yaml
# 리소스 제한을 극단적으로 낮게 설정
sed -i 's/memory: 1Gi/memory: 1Mi/g' carts-deployment.yaml
sed -i 's/cpu: 250m/cpu: 1m/g' carts-deployment.yaml
# 변경 적용
kubectl apply -f carts-deployment.yaml
증상
carts 파드가 CrashLoopBackOff 상태로 반복 재시작됨
이벤트에 OOMKilled(메모리 부족으로 종료) 로그 발생
애플리케이션 응답 지연 또는 중단
실행 결과는 아래와 같습니다:
명령을 실행했고, carts 디플로이먼트의 리소스 제한을 극단적으로 낮게 설정했습니다. 그 결과 새로운 파드가 시작되지 못하고 있습니다.
## 실행 결과 분석
1. 리소스 제한 변경:
• 메모리 제한: 1Gi → 1Mi (1024MB에서 1MB로 감소)
• CPU 요청: 250m → 1m (250밀리코어에서 1밀리코어로 감소)
2. 디플로이먼트 상태:
• 롤링 업데이트 중: 새 ReplicaSet carts-bc5d58f66가 생성됨
• 이전 파드 carts-7c95cd549d-4mjjb는 여전히 실행 중
• 새 파드 carts-bc5d58f66-2bhsz는 Pending 상태
3. 새 파드 문제:
• 이벤트 로그에서 중요한 오류 발견:
Failed to create pod sandbox: rpc error: code = Unknown desc = failed to create containerd task:
failed to create shim task: OCI runtime create failed: runc create failed:
unable to start container process: container init was OOM-killed (memory limit too low?): unknown
## 문제 원인
새 파드가 시작되지 못하는 이유는 메모리 제한이 너무 낮기 때문입니다. 1Mi(1MB)는 Java 애플리케이션이 실행되기에 극단적으로 부족한 메모리입니다. 컨테이너 초기화 과
정에서 OOM(Out Of Memory) 오류가 발생하여 파드가 시작되지 못하고 있습니다.
이로 인해 롤링 업데이트가 완료되지 못하고, 이전 파드와 새 파드가 동시에 존재하는 상태가 되었습니다. 이전 파드는 여전히 정상 작동하지만, 새 파드는 시작되지 못하고
있습니다.
이러한 상황은 실제 환경에서 리소스 제한을 잘못 설정했을 때 발생할 수 있는 전형적인 문제입니다. 특히 Java 애플리케이션은 최소한의 메모리가 필요하며, 1MB는 JVM이
시작하기에도 부족한 양입니다.
Amazon Q 프롬프트 예시 :
EKS 클러스터의 carts 파드가 계속 OOMKilled 오류로 크래시되고 있습니다.
파드 이벤트를 확인해보니 메모리 문제로 종료되고 있는 것으로 보입니다.
현재 설정된 리소스 제한을 확인하고, 적절한 값으로 업데이트하려면 어떻게 해야 하나요?
실행 결과는 아래와 같습니다:
## ✅ Carts 파드 OOMKilled 오류 해결 완료!
EKS 클러스터의 carts 파드가 OOMKilled 오류로 크래시되는 문제를 성공적으로 해결했습니다.
### 🔍 발견된 문제
극도로 부족한 메모리 할당:
• **현재 설정**: 1Mi (1 메가바이트) ❌
• **Java 애플리케이션 최소 요구량**: ~300Mi
• **권장 설정**: 1Gi (1 기가바이트) ✅
### 🚨 OOMKilled 발생 원인
Failed to create pod sandbox: OCI runtime create failed:
runc create failed: unable to start container process:
container init was OOM-killed (memory limit too low?)
Java Spring Boot 애플리케이션이 JVM 초기화 과정에서 1Mi 메모리 제한을 초과하여 Linux OOM Killer에 의해 강제 종료되었습니다.
### 🛠️ 해결 과정
1. 문제 진단: 이벤트 로그에서 OOMKilled 오류 확인
2. 리소스 설정 확인: 현재 메모리 제한이 1Mi로 설정됨 발견
3. 원본 파일 확인: YAML 파일에는 올바른 1Gi 설정이 있음 확인
4. 설정 재적용: kubectl apply -k 명령어로 올바른 설정 적용
### 📊 수정 결과
✅ 업데이트된 리소스 설정:
json
{
"limits": {
"memory": "1Gi"
},
"requests": {
"cpu": "250m",
"memory": "1Gi"
}
}
✅ 현재 실제 사용량:
• **메모리**: 262Mi (할당량의 25.6%)
• **CPU**: 2m (할당량의 0.8%)
• **상태**: Running ✅
• **헬스 체크**: 200 OK ✅
### 🎯 주요 성과
| 지표 | 개선 전 | 개선 후 |
|------|---------|---------|
| 파드 시작 성공률 | 0% | 100% |
| 메모리 가용성 | 0Mi | 762Mi |
| 애플리케이션 응답 | 실패 | 200 OK |
| 시스템 안정성 | 불안정 | 안정 |
### 📋 Java 애플리케이션 리소스 권장사항
메모리 할당 가이드라인:
• **최소 요구량**: 512Mi
• **권장 설정**: 1Gi
• **JVM 힙 비율**: 75% (MaxRAMPercentage=75.0)
• **안전 마진**: 실제 사용량의 2-3배
📝 상세한 문제 해결 과정과 예방 조치는 ~/output/carts-oom-fix.md 파일에 저장되었습니다.
이제 carts 파드가 안정적으로 실행되며 충분한 메모리 여유를 확보했습니다! 🎉
검증 명령어
# carts 네임스페이스 내 파드 상태 확인
kubectl get pods -n carts
# 현재 설정된 리소스 제한 확인
kubectl get deployment carts -n carts -o jsonpath='{.spec.template.spec.containers[0].resources}' | jq
# 파드 재시작 횟수 확인 (복구되었을 경우 낮아야 함)
kubectl get pods -n carts -o jsonpath='{.items[*].status.containerStatuses[0].restartCount}'
결과 확인
NAME READY STATUS RESTARTS AGE
carts-7dc65cd8ff-lgl4z 1/1 Running 0 2m4s
carts-dynamodb-68bd8f6f6d-p7rmz 1/1 Running 0 25m
{
"limits": {
"memory": "1536Mi"
},
"requests": {
"cpu": "250m",
"memory": "1Gi"
}
}
1.3 Scenario 3: 의존성 누락 (Missing Dependencies)
초기 상태
Orders 서비스는 RabbitMQ 서비스에 의존하여 메시지 큐 기능을 수행.
문제 유발
# rabbitmq checkout을 0으로 스케일 다운
kubectl -n checkout scale deployment checkout --replicas=0
증상
checkout 서비스와 Redis연결 이슈 발생
Amazon Q 프롬프트 예시:
EKS 클러스터의 checkout 서비스에서 오류가 발생하고 있습니다.
checkout 파드가 실행 중인지 확인하고, 실행 중이 아니라면 어떻게 복구할 수 있을까요?
실행 결과는 아래와 같습니다:
## ✅ Checkout 서비스 복구 완료!
EKS 클러스터의 checkout 서비스 오류를 성공적으로 진단하고 복구했습니다.
### 🔍 발견된 문제
Checkout 애플리케이션 파드 완전 중단:
• **디플로이먼트 상태**: 0/0 (파드 없음) ❌
• **서비스 엔드포인트**: <none> (연결 불가) ❌
• **근본 원인**: 레플리카 수가 3에서 0으로 의도치 않게 축소됨
### 🚨 서비스 중단 영향
• **사용자 경험**: 결제 기능 완전 중단
• **연결 테스트**: Exit Code 7 (Connection Failed)
• **비즈니스 영향**: 주문 완료 불가
### 🛠️ 복구 과정
1. 문제 진단: 파드 상태 → 디플로이먼트 상태 → 이벤트 로그 순차 확인
2. 원인 파악: 디플로이먼트가 2분 전에 3개에서 0개로 스케일 다운됨
3. 설정 복구: kubectl apply -k 명령어로 올바른 설정 재적용
4. 결과 검증: 모든 파드 Ready 상태 및 서비스 연결 확인
### 📊 복구 결과
✅ 완전 복구 달성:
NAME READY UP-TO-DATE AVAILABLE AGE
checkout 3/3 3 3 149m
✅ 파드 상태:
• 3개 checkout 파드 모두 Running 상태
• 3개의 서로 다른 워커 노드에 분산 배치
• Redis 캐시와 정상 연결
✅ 서비스 연결:
• 엔드포인트: 3개 파드 IP 모두 등록
• 헬스 체크: 200 OK 응답
• 복구 시간: 약 30초
### 🎯 주요 성과
| 지표 | 복구 전 | 복구 후 |
|------|---------|---------|
| 서비스 가용성 | 0% | 100% |
| 실행 중인 파드 | 0개 | 3개 |
| 응답 성공률 | 0% | 100% |
| 복구 시간 | N/A | 30초 |
### 📋 체계적인 진단 체크리스트
향후 유사한 문제 발생 시 사용할 수 있는 진단 절차:
1. 파드 상태 확인: kubectl get pods -n checkout
2. 디플로이먼트 상태 확인: kubectl get deployment -n checkout
3. 상세 정보 확인: kubectl describe deployment checkout -n checkout
4. 이벤트 로그 분석: kubectl get events -n checkout
5. 연결 테스트: curl 명령어로 실제 연결 확인
📝 상세한 복구 과정과 예방 조치는 ~/output/checkout-service-recovery.md 파일에 저장되었습니다.
이제 checkout 서비스가 3개 레플리카로 고가용성을 확보하며 정상적으로 운영되고 있습니다! 🎉
검증 명령어:
# checkout 파드 상태 확인
kubectl get pods -n checkout
# 디플로이먼트 상태 확인
kubectl get deployment -n checkout
# 상세 정보 확인
kubectl describe deployment checkout -n checkout
# 이벤트 로그 분석
kubectl describe deployment checkout -n checkout | grep -A 20 "Events:"
실행 결과는 아래와 같습니다:
$kubectl get pods -n checkout
NAME READY STATUS RESTARTS AGE
checkout-54c6cd5685-h4vbh 1/1 Running 0 6m19s
checkout-54c6cd5685-scc5g 1/1 Running 0 6m19s
checkout-54c6cd5685-wf9q9 1/1 Running 0 6m19s
checkout-redis-7fb554999b-rrs4q 1/1 Running 0 156m
$ kubectl get deployment -n checkout
NAME READY UP-TO-DATE AVAILABLE AGE
checkout 3/3 3 3 156m
checkout-redis 1/1 1 1 156m
$ kubectl describe deployment checkout -n checkout | grep -A 20 "Events:"
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 12m deployment-controller Scaled down replica set checkout-54c6cd5685 to 0 from 3
Normal ScalingReplicaSet 9m41s deployment-controller Scaled up replica set checkout-54c6cd5685 to 3 from 0
Last updated