도입부: 운영하다 보면 Pod 장애는 피할 수 없고, 결국 승부는 “얼마나 빨리 원인을 좁히느냐(MTTR)”에서 납니다. 이 글에서는 대표적인 Pod 오류 상태의 의미를 정리하고, 제가 현장에서 가장 재현성 있게 먹혔던 **진단 순서(워크플로)**와 트러블슈팅을 가속하는 툴까지 한 번에 정리합니다.
Pod 오류 진단의 핵심: “순서”가 MTTR을 줄입니다
Pod 장애를 마주하면 사람은 보통 바로 로그부터 봅니다. 그런데 쿠버네티스는 스케줄링/이미지 풀/어드미션/네트워크/리소스 제한 등 장애 지점이 다양해서, 로그만으로는 삽질이 길어지기 쉽습니다.
제가 추천하는 기본 워크플로는 아래 순서입니다.
- Pod Status 확인
kubectl describe pod- Logs 확인
- Events 확인
- 리소스/네트워크/Secrets/ConfigMaps 검증
이 흐름은 “관측 가능한 사실 → 원인 후보 좁히기 → 증거 확보 → 재발 방지 포인트 확인”으로 이어지기 때문에, 결과적으로 MTTR을 줄이는 데 효과적입니다.
대표 Pod 상태/오류 빠른 해석(원인 방향성 잡기)
장애 진단은 “정확한 원인” 이전에 “올바른 방향”을 잡는 게 중요합니다. 아래는 현장에서 자주 보는 대표 상태들입니다.
1) ImagePullBackOff / ErrImagePull
- 의미: 노드가 이미지를 pull 하지 못해서 컨테이너 시작이 안 됨
- 주요 원인
- 이미지 이름/태그 오타, 레지스트리 권한 문제
imagePullSecrets누락/오류- 레지스트리 네트워크 접근 불가(프록시/방화벽/DNS)
- 첫 확인 포인트:
describe의 Events에 pull 실패 사유가 거의 다 나옵니다.
2) CrashLoopBackOff
- 의미: 컨테이너가 뜨긴 뜨는데 곧바로 종료되고 재시작을 반복
- 주요 원인
- 앱 설정 오류(ENV/ConfigMap/Secret), 의존성(DB 등) 연결 실패
- entrypoint/command 오류
- 헬스체크 설정이 과격해서 정상인데도 죽는 경우
- 첫 확인 포인트: “현재 로그” + “이전 로그”를 같이 봐야 합니다.
3) Pending
- 의미: 스케줄러가 노드에 배치하지 못함(혹은 배치 후 이미지 pull/볼륨 단계에서 지연)
- 주요 원인
- 리소스 부족(CPU/Memory), taint/toleration, affinity/anti-affinity
- PVC 바인딩 실패/스토리지 문제
- 첫 확인 포인트:
describe의 “Events: FailedScheduling” 메시지.
4) OOMKilled
- 의미: 메모리 초과로 커널이 컨테이너를 강제 종료
- 주요 원인
- limit이 너무 낮거나, 메모리 릭/버퍼 폭증
- 첫 확인 포인트:
kubectl describe pod에서 Last State/Reason, 그리고 리소스 requests/limits 설정.
바로 써먹는 조사 명령어(워크플로 템플릿)
1) 상태 빠르게 훑기: get
kubectl get pod -n <ns> -o wide
kubectl get pod -n <ns> <pod> -o jsonpath='{.status.containerStatuses[*].state}'
- 어디 노드에 떠 있는지, 상태가 무엇인지, 재시작 횟수가 급증했는지부터 봅니다.
2) 원인 메시지의 보고: describe
kubectl describe pod -n <ns> <pod>
Events섹션이 핵심입니다.- Image pull 실패, 스케줄링 실패, 프로브 실패, 볼륨 마운트 실패는 대부분 여기서 1차 결론이 납니다.
3) 로그: 현재 + 이전(중요)
kubectl logs -n <ns> <pod> -c <container>
kubectl logs -n <ns> <pod> -c <container> --previous
CrashLoopBackOff는--previous를 안 보면 결정적 로그를 놓치는 경우가 많습니다.
4) 이벤트만 모아서 보기(클러스터 “증거”)
kubectl get events -n <ns> --sort-by=.lastTimestamp
- 장애가 복합적일수록(예: 스케줄링 실패 후 이미지 풀 실패) 시간순 이벤트가 큰 힌트를 줍니다.
5) 리소스/설정 검증
kubectl get deploy -n <ns> <deploy> -o yaml | less
kubectl get cm,secret -n <ns> | grep <keyword>
kubectl top pod -n <ns>
- ConfigMap/Secret 참조 이름이 틀린 경우, “앱 로그는 친절하지 않은데 쿠버네티스 이벤트는 친절한” 케이스가 많습니다.
kubectl만으로 부족할 때: 트러블슈팅을 가속하는 툴 추천
장애를 빨리 푸는 데 유용한 도구는 보통 두 부류입니다.
- 즉시 원인 파악(관측/디버깅)
- 재발 방지(정책/품질/검증)
아래는 제가 “kubectl 다음 단계”로 자주 추천하는 조합입니다.
1) 로그 수집이 고통이면: stern
- 여러 Pod/컨테이너 로그를 한 번에 tailing 해주는 도구입니다.
- Replica가 많거나 롤링 중일 때 “어느 Pod가 문제인지” 찾는 시간을 줄여줍니다.
2) 컨테이너 안에서 확인이 필요하면: kubectl debug(ephemeral container)
- 프로덕션 컨테이너 이미지에 디버깅 도구(curl, dig 등)가 없을 때 유용합니다.
- 네트워크/DNS/파일 존재 여부 같은 기본 점검이 빨라집니다.
3) “무슨 일이 일어났는지” 흐름이 안 보이면: Pixie(eBPF)
- 애플리케이션 코드 수정 없이도 요청 흐름/지연/에러를 관측하는 접근입니다.
- 복잡한 마이크로서비스에서 “어디서 막히는지”를 빠르게 좁힐 때 강력합니다.
4) 리소스 설정이 자주 문제라면: Goldilocks(VPA 추천)
- requests/limits 튜닝이 반복되는 조직이라면 체감이 큽니다.
- OOMKilled/과한 스로틀링의 재발 방지에 도움 됩니다.
5) 클러스터 위생 점검: Popeye
- 리소스 구성의 이상 징후(부정합, 권장되지 않는 패턴)를 스캔해줍니다.
- “당장 장애는 아니지만 곧 장애가 날 구성”을 찾아내는 데 유용합니다.
“정책이 복잡해서 비논리/충돌이 걱정”할 때의 현실적인 해법
대화에서 나온 포인트처럼, Admission/RBAC/NetworkPolicy/서비스메시까지 포함하면 정책 비논리를 한 방에 증명해주는 만능 툴은 드뭅니다. 대신 효과가 좋았던 접근은 이 조합입니다.
- 정적 분석 + 테스트(시뮬레이션) + 런타임 관측을 계층별로 겹치기
Admission(OPA Gatekeeper / Kyverno / PSA)
- Kyverno:
validate정책 +PolicyReport로 위반 사유 축적 - Gatekeeper: audit로 기존 리소스의 위반 스캔
- 핵심은 “정책을 코드로 두고, 샘플 리소스로 CI에서 테스트”하는 피드백 루프입니다.
RBAC
- “누가 무엇을 할 수 있는지”는 체감 난이도가 높습니다.
- RBAC 조회/요약 도구(rakkess, rbac-lookup 계열) + 감사 로그를 함께 보면 의도치 않은 허용/거부를 빨리 찾습니다.
NetworkPolicy
- 정책만 보고는 결론이 안 나는 경우가 많아 “실제 트래픽 verdict(허용/차단) 증거”가 중요합니다.
- Cilium(Hubble), Calico 흐름 로그 등 관측 기능이 비논리를 드러내는 데 도움이 됩니다.
Service Mesh(Istio 등)
- 예: Istio는
istioctl analyze로 구성 정합성 문제를 빠르게 잡습니다. - 여기에 요청 단위 텔레메트리(트레이싱/메트릭)를 더하면 AuthZ 정책의 의도치 않은 거부를 좁히기 쉬워집니다.
마무리: “구조화된 진단 + 적절한 도구”가 결국 신뢰성을 만듭니다
Pod 장애는 흔하지만, 진단 방식은 습관이 됩니다. Status → describe → logs(특히 previous) → events → 설정/리소스/네트워크 검증의 루틴을 팀에 정착시키고, 병목 지점에 맞는 툴(stern, kubectl debug, eBPF 관측, 정책 테스트/리포트)을 붙이면 MTTR이 눈에 띄게 줄어듭니다.
