:bulb: 운영 중인 클러스터에서 Error, Pending, CrashLoopBackOff, Init:0/1 같은 비정상 Pod만 빠르게 걸러내는 kubectl 명령어를 정리한다. 핵심 명령어는 Completed 포함과 비포함 두 가지로 제공한다.


[01] STATUS 컬럼의 구성

kubectl get podsSTATUS 컬럼에는 두 종류의 값이 섞여 있다. 이 차이를 모르면 필터가 의도와 다르게 동작한다.

1-1. phase와 컨테이너 reason

STATUS 표시 실제 정체 --field-selector로 잡히나?
Pending phase
Running phase
Completed phase = Succeeded
Error phase = Failed
CrashLoopBackOff 컨테이너 reason ❌ (phase는 Running)
Init:0/1 컨테이너 reason ❌ (phase는 Pending)
ImagePullBackOff 컨테이너 reason
Terminating deletionTimestamp 존재

:warning: CrashLoopBackOff, Init:0/1, ImagePullBackOffphase가 아니라 컨테이너 reason이다. 그래서 --field-selector=status.phase!=Running으로는 걸러지지 않는다. 가장 흔한 착오다.

이 때문에 텍스트 기반 grep 방식이 실무에서 더 안전하다. 아래에서 두 방법을 모두 다룬다.


[02] 전체 Pod 보기 (기준점)

먼저 모든 네임스페이스의 모든 Pod를 본다.

1
2
# 모든 네임스페이스의 모든 Pod (노드/IP 등 추가 정보 포함)
kubectl get pods -A -o wide
옵션 의미
-A --all-namespaces — 전체 네임스페이스
-o wide NODE, IP, NOMINATED NODE 등 추가 컬럼 표시

:bulb: --sort-by는 정렬만 하고 필터링은 하지 않는다. kubectl get pods -A --sort-by='.status.phase'Running을 포함한 모든 Pod를 그대로 보여준다. 문제 Pod만 보려면 아래의 필터링이 필요하다.


[03] 비정상 Pod만 걸러내기

3-1. 케이스 A: Completed 비포함 (정상으로 간주)

CronJob/Job이 정상적으로 끝낸 Completed Pod까지 제외하고 문제 Pod만 보고 싶을 때 쓴다.

1
2
# Running, Completed 둘 다 제외 → 나머지(문제 Pod)만
kubectl get pods -A -o wide | grep -v -E 'Running|Completed'
  • grep -v : 매칭되는 줄을 제외한다
  • Running(정상 동작) + Completed(정상 완료)를 모두 빼므로 → Error, Pending, CrashLoopBackOff, Init, ImagePullBackOff 등만 남는다.

:warning: 단점: -v는 헤더(NAMESPACE NAME ...)줄도 같이 지운다. 헤더를 살리려면 아래 “헤더 보존 버전”을 쓴다.

헤더 보존 + Completed 비포함:

1
2
# 헤더(NAMESPACE)는 남기고, Running/Completed만 제외
kubectl get pods -A -o wide | grep -E 'NAMESPACE|Error|CrashLoopBackOff|Pending|Init|ImagePullBackOff|Terminating|OOMKilled|ErrImagePull'

→ 허용 목록 방식. 헤더인 NAMESPACE와 문제 상태만 통과시킨다. Completed는 목록에 없으므로 제외된다.

3-2. 케이스 B: Completed 포함 (점검 대상)

Completed까지 포함해서 “Running이 아닌 모든 Pod”를 보고 싶을 때 쓴다. 예를 들어 Deployment의 Pod가 Completed로 빠진 비정상 상황까지 잡아내려면 이 방식이 필요하다. [05]를 참고한다.

1
2
# Running만 제외 → Completed 포함 나머지 전부
kubectl get pods -A -o wide | grep -v 'Running'

헤더 보존 + Completed 포함:

1
2
# 헤더는 남기고 Running만 제외
kubectl get pods -A -o wide | grep -v -w 'Running' | grep -E 'NAMESPACE|[A-Za-z]'

또는 더 단순하게, field-selector로 phase 필터:

1
2
# phase가 Running이 아닌 Pod (Completed=Succeeded, Error=Failed, Pending 포함)
kubectl get pods -A -o wide --field-selector=status.phase!=Running

:warning: 이 field-selector는 phase가 RunningCrashLoopBackOff를 걸러내지 못한다. 정확히 잡으려면 grep 케이스 B를 쓴다.


[04] 특정 상태만 골라 보기

1
2
3
4
5
6
kubectl get pods -A -o wide | grep CrashLoopBackOff
kubectl get pods -A -o wide | grep -E 'Error|CrashLoopBackOff|ImagePullBackOff'
kubectl get pods -A -o wide | grep Pending
kubectl get pods -A -o wide | grep Init          # Init:0/1 등 초기화 멈춤
kubectl get pods -A -o wide | grep Terminating   # 종료 안 되고 매달린 Pod
kubectl get pods -A -o wide | grep Completed

phase 기준(정확한 필터):

1
2
3
kubectl get pods -A --field-selector=status.phase=Pending    -o wide
kubectl get pods -A --field-selector=status.phase=Failed     -o wide   # Error
kubectl get pods -A --field-selector=status.phase=Succeeded  -o wide   # Completed

[05] Completed 상태의 판단 기준

Completed는 상황에 따라 정상일 수도 있고 비정상 상태를 나타낼 수도 있다. 판단 기준은 하나다. 이 Pod가 원래 종료되도록 설계됐는지 확인한다.

소유자(Controller) Completed의 의미
Job / CronJob ✅ 정상 (작업 완료, exit 0)
Init Container ✅ 정상 (초기화 후 종료)
Deployment / ReplicaSet ⚠️ 비정상 (계속 실행돼야 하는데 종료됨)
StatefulSet / DaemonSet ⚠️ 비정상 (메인 프로세스가 종료됨)

소유자 확인 명령어:

1
2
3
# 이 Pod를 누가 만들었는지(소유 컨트롤러 종류) 확인
kubectl get pod <pod-name> -n <namespace> \
  -o jsonpath='{.metadata.ownerReferences[0].kind}'
  • 결과가 Job이면 Completed는 정상이다.
  • 결과가 ReplicaSet, 즉 Deployment 소유이거나 StatefulSet이면 Completed는 비정상 신호다. 엔트리포인트가 foreground로 실행되지 않고 종료됐을 가능성이 크다.

:bulb: CronJob은 successfulJobsHistoryLimit 설정에 따라 성공한 Pod를 남겨둔다. Completed Pod가 여러 개 쌓여 있는 것은 대개 정상이다. 그래서 평소 점검에서는 Completed를 제외하는 케이스 A가 불필요한 출력이 적다.


[06] 문제 Pod 원인 진단

비정상 Pod를 찾았다면 원인을 본다.

1
2
3
4
5
6
7
8
9
10
11
# Events 섹션에서 원인 확인 (스케줄링 실패, 이미지 못 받음 등)
kubectl describe pod <pod-name> -n <namespace>

# 로그 확인
kubectl logs <pod-name> -n <namespace>

# CrashLoopBackOff 디버깅의 핵심 — 이전(크래시된) 컨테이너 로그
kubectl logs <pod-name> -n <namespace> --previous

# 재시작 횟수가 많은 Pod 찾기 (RESTARTS 컬럼 정렬)
kubectl get pods -A --sort-by='.status.containerStatuses[0].restartCount' -o wide

[07] 핵심 요약

# 요약
1 STATUS 컬럼은 phase(Pending/Running/Succeeded/Failed)와 컨테이너 reason(CrashLoopBackOff/Init 등)이 섞여 있다
2 --field-selector=status.phase!=RunningCrashLoopBackOff를 놓친다 — phase가 Running이기 때문
3 케이스 A, Completed 비포함: kubectl get pods -A -o wide \| grep -v -E 'Running\|Completed'
4 케이스 B, Completed 포함: kubectl get pods -A -o wide \| grep -v 'Running'
5 --sort-by는 정렬만 할 뿐 Running을 걸러주지 않는다. 필터링은 grep이나 field-selector로 한다
6 Completed가 정상인지는 소유 컨트롤러로 판단 — Job/CronJob이면 정상, Deployment/StatefulSet이면 의심

:bulb: 가장 자주 쓰는 한 줄은 kubectl get pods -A -o wide | grep -v -E 'Running|Completed' 이다. 정상이 아닌 모든 Pod를 한 번에 확인한다.