Kubernetes Pod CrashLoopBackOff 해결 가이드
Kubernetes Pod이 CrashLoopBackOff 상태가 되는 원인을 분석하고 해결하는 방법을 알아봅니다.
Kubernetes Pod CrashLoopBackOff 해결 가이드
CrashLoopBackOff는 Pod이 반복적으로 시작 실패 후 종료되는 상태입니다. 이 상태가 되면 Pod이 정상적으로 동작하지 않으며, 서비스에 영향을 줍니다.
Environment
$ kubectl version --client
Client Version: v1.28.4
Kustomize Version: v5.3.0
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane 30d v1.28.4
k8s-worker-1 Ready 30d v1.28.4 Problem: Pod이 계속 재시작됨
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-7d4b8c9f5-abc12 0/1 CrashLoopBackOff 5 (30s ago) 2m
$ kubectl describe pod myapp-7d4b8c9f5-abc12출력:
Events:
Type Reason Age From Message
---- ---- ---- ---- -------
Normal Pulled 2m kubelet Container image "myapp:latest" already present on machine
Normal Created 2m kubelet Created container myapp
Normal Started 2m kubelet Started container myapp
Warning BackOff 30s (x5 over 2m) kubelet Back-off restarting failed containerAnalysis: Pod 로그 분석
# Pod 로그 확인
$ kubectl logs myapp-7d4b8c9f5-abc12
2024-01-15 10:30:00 ERROR: Database connection refused
Traceback (most recent call last):
File "/app/main.py", line 10, in
connect_to_database()
ConnectionRefusedError: [Errno 111] Connection refused
# 이전 컨테이너 로그 확인
$ kubectl logs myapp-7d4b8c9f5-abc12 --previous
# Pod 상태 상세 확인
$ kubectl get pod myapp-7d4b8c9f5-abc12 -o yaml Solution: CrashLoopBackOff 해결 방법
방법 1: 로그 분석 후 설정 수정
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 1
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:latest
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: db-secret
key: url
ports:
- containerPort: 8000방법 2: Health Checks 설정
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 1
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:latest
ports:
- containerPort: 8000
# Liveness Probe - Is the container alive?
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 3
# Readiness Probe - Is the container ready?
readinessProbe:
httpGet:
path: /ready
port: 8000
initialDelaySeconds: 5
periodSeconds: 5방법 3: 리소스 제한 설정
containers:
- name: myapp
image: myapp:latest
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"방법 4: 커맨드 오버라이드
# 디버깅을 위해 커맨드 오버라이드
containers:
- name: myapp
image: myapp:latest
command: ["sleep"]
args: ["infinity"]# Pod exec로 디버깅
$ kubectl exec -it myapp-7d4b8c9f5-abc12 -- /bin/bash
# 수동으로 앱 실행
$ kubectl exec -it myapp-7d4b8c9f5-abc12 -- python app.py방법 5: Init Container 사용
spec:
initContainers:
- name: wait-for-db
image: busybox
command: ['sh', '-c', 'until nc -z db-service 5432; do sleep 2; done']
containers:
- name: myapp
image: myapp:latest
dependsOn:
- wait-for-dbAdvanced: 디버깅 명령어 모음
# Pod 상태 확인
$ kubectl get pods -o wide
# 상세 이벤트 확인
$ kubectl describe pod
# 로그 확인
$ kubectl logs
$ kubectl logs --previous
$ kubectl logs -f # Follow logs
# Pod exec
$ kubectl exec -it -- /bin/bash
# 디버그 컨테이너로 Pod 진입
$ kubectl debug -it --image=busybox
# Pod 리소스 사용량 확인
$ kubectl top pod
# Pod YAML 확인
$ kubectl get pod -o yaml Lessons Learned
로그가 첫 번째 단계: CrashLoopBackOff 발생 시 먼저
kubectl logs로 에러 메시지를 확인하세요.Health Check 필수: Liveness/Readiness Probe를 설정하여 Pod 상태를 모니터링하세요.
Init Container 활용: 의존성이 있는 서비스가 준비될 때까지 기다리는 init container를 사용하세요.
리소스 제한: 메모리/CPU 제한을 설정하여 OOM Killed를 방지하세요.
디버깅 전략: 문제가 지속되면 커맨드 오버라이드로 Pod을 유지하고 수동 디버깅을 수행하세요.
This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.