실패한 배포 디버깅: 일반적인 YAML 및 구성 오류 식별
이벤트, YAML 구조, 이미지 풀, 프로브, 리소스 및 스케줄링 규칙을 확인하여 실패한 Kubernetes 배포를 디버깅합니다.
실패한 배포 디버깅: 일반적인 YAML 및 구성 오류 식별
Kubernetes 배포 실패는 일반적으로 Pending, ImagePullBackOff, CrashLoopBackOff 상태의 파드 또는 사용 가능한 복제본이 0개인 형태로 나타납니다. 원인은 종종 이벤트에서 확인할 수 있지만, 올바른 순서로 Deployment, ReplicaSet 및 Pod를 검사해야 합니다.
이 가이드는 일반적으로 YAML 오류, 이미지 풀 문제, 잘못된 프로브, 리소스 제약 조건 및 배포가 정상 상태가 되는 것을 방해하는 스케줄링 규칙을 찾는 검사 과정을 안내합니다.
첫 번째 단계: 배포 상태 및 이벤트 확인
배포가 실패하면 첫 번째 진단 단계는 항상 기본 리소스 자체와 관리되는 ReplicaSet 및 Pod와 관련된 이벤트를 확인하는 것입니다. 이를 통해 Kubernetes가 무엇을 시도하고 있는지, 왜 실패하는지에 대한 최상위 수준의 개요를 얻을 수 있습니다.
1. 배포 상태 확인
kubectl get deployments를 사용하여 전체 상태를 확인합니다. 특히 READY, UP-TO-DATE 및 AVAILABLE 열을 살펴보세요. 여기서 불일치가 발견되면 기본 Pod에 문제가 있음을 나타냅니다.
kubectl get deployments <deployment-name>
배포 상태에 준비된 복제본이 거의 없거나 전혀 없으면 ReplicaSet을 확인하세요.
2. ReplicaSet 및 Pod 이벤트 검토
ReplicaSet은 원하는 수의 Pod를 관리합니다. 배포가 실패하면 일반적으로 ReplicaSet이 오류 연쇄의 원인입니다. 일반적으로 <deployment-name>-<hash> 형식으로 이름이 지정된 ReplicaSet에 describe 명령을 사용합니다:
kubectl describe rs <replicaset-name>
중요한 것은 출력 하단의 Events 섹션을 검토하는 것입니다. 이 섹션은 스케줄링 시도, 이미지 풀 실패, 볼륨 마운트 문제 등 최근 작업을 자세히 설명합니다. 이러한 이벤트는 종종 결정적인 증거입니다.
마지막으로 Pod 자체를 확인하여 즉각적인 실패를 보고합니다:
kubectl get pods -l app=<your-app-label>
kubectl describe pod <pod-name>
Pod 설명에서 State 및 Reason 필드를 찾으세요. 일반적인 이유로는 ImagePullBackOff, ErrImagePull, CrashLoopBackOff 및 Pending이 있습니다.
YAML 매니페스트의 일반적인 구성 오류
YAML 파일의 잘못된 구성은 배포 실패의 가장 빈번한 원인입니다. 이러한 오류는 단순한 들여쓰기 실수부터 복잡한 구조적 문제까지 다양할 수 있습니다.
1. YAML 구문 및 구조 오류
Kubernetes API는 올바른 YAML 구문(들여쓰기, 공백 및 데이터 유형)에 매우 민감합니다. YAML이 유효하지 않으면 kubectl apply는 종종 즉시 실패하며 파일을 구문 분석할 수 없다고 표시합니다.
모범 사례: 린터 사용
적용하기 전에 항상 YAML 구문의 유효성을 검사하세요. yamllint와 같은 도구나 통합 IDE 지원을 사용하면 기본 구문 오류를 즉시 잡을 수 있습니다.
일반적인 구조 오류의 예: 잘못된 매핑 또는 들여쓰기.
# 잘못됨: containers는 spec.template.spec 아래에 속하며, spec.template 바로 아래에 있지 않습니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
metadata:
labels:
app: my-app
containers:
- name: my-app
image: myregistry/myapp:v1
올바른 배치:
spec:
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: myregistry/myapp:v1
ports:
- containerPort: 8080
2. 이미지 참조 및 풀 오류
Pod가 ImagePullBackOff 또는 ErrImagePull 상태가 되면 컨테이너 이미지에 액세스하는 데 문제가 있는 것입니다.
- 이미지 이름/태그 오타: 이미지 저장소, 이름 및 태그의 철자를 다시 확인하세요.
- 프라이빗 레지스트리 인증: 프라이빗 레지스트리에서 가져오는 경우 이미지 풀 시크릿을 생성하고 Pod 사양에서
imagePullSecrets로 참조했는지 확인하세요.
# ImagePullSecret 사용을 보여주는 스니펫
spec:
imagePullSecrets:
- name: my-registry-secret
containers:
- name: my-app
image: private.example.com/my-app:v1
3. 리소스 요청 및 제한 위반
Pod가 Pending 상태로 유지되고 이벤트에 리소스 부족이 언급되면 클러스터 노드가 YAML에 정의된 CPU 또는 메모리 요구 사항을 충족할 수 없는 것입니다.
배포 매니페스트에 지정된 제한을 확인하세요:
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "1Gi"
cpu: "1"
문제 해결 단계:
kubectl describe nodes를 사용하여 사용 가능한 용량을 확인합니다.0/3 nodes are available: 3 Insufficient cpu와 같은 이벤트가 표시되면 YAML에서requests를 낮추거나 클러스터에 노드를 더 추가해야 합니다.
고급 구성 문제
기본 구문 및 이미지 풀 외에도 네트워킹, 스토리지 및 스케줄링과 관련된 복잡한 구성은 진단하기 어려운 실패로 이어질 수 있습니다.
1. 잘못 구성된 프로브(Liveness 및 Readiness)
Pod가 CrashLoopBackOff 상태로 전환되면 컨테이너가 시작되지만 즉시 검사에 실패하거나 시작되었지만 준비 상태 프로브(readiness probe)가 계속 실패하는 경우가 많습니다.
- Liveness 프로브: 이것이 반복적으로 실패하면 Kubernetes가 컨테이너를 다시 시작합니다.
kubectl describe pod <pod-name>에서 프로브 실패 이벤트를 확인하고 재시작 후kubectl logs <pod-name> --previous를 확인하세요. - Readiness 프로브: 이것이 실패하면 Pod는 계속 실행되지만 Service 엔드포인트에서 제외됩니다. 경로, 포트 및 예상 응답 코드가 애플리케이션이 실제로 제공하는 것과 일치하는지 확인하세요.
일반적인 Readiness 프로브 오류의 예: 잘못된 포트를 대상으로 하거나 앱이 TCP만 노출할 때 HTTP를 예상하는 경우.
2. 볼륨 및 PersistentVolumeClaim(PVC) 실패
볼륨 문제로 인해 Pod가 보류 중인 경우 PVC 상태를 확인하세요:
kubectl get pvc <pvc-name>
PVC 상태가 Pending이면 클러스터가 일치하는 StorageClass 또는 바인딩할 적절한 PersistentVolume을 찾을 수 없음을 의미합니다. 특정 바인딩 오류에 대한 PVC 이벤트를 확인하세요.
3. 어피니티 및 안티-어피니티 규칙
nodeAffinity 또는 podAntiAffinity와 같은 복잡한 스케줄링 규칙은 모든 기준을 충족하는 노드가 없으면 의도치 않게 Pod 스케줄링을 방해할 수 있습니다. Pod가 Pending 상태로 유지되고 이벤트에 스케줄링 제한이 언급되면 이러한 규칙을 검토하세요.
예를 들어, 특정 레이블(disktype: ssd)이 있는 노드에서 Pod를 실행해야 하는데 해당 레이블을 가진 노드가 없으면 Pod는 절대 스케줄링되지 않습니다.
# 예: 'disktype: ssd' 레이블이 있는 노드로 배포 제한
spec:
nodeSelector:
disktype: ssd
containers:
# ...
문제 해결 팁: 제한적인 nodeSelector 또는 affinity 규칙을 일시적으로 주석 처리하세요. Pod가 성공적으로 스케줄링되면 선택 기준에 문제가 있는 것입니다.
디버깅 워크플로우
실패한 배포에 직면했을 때 이 구조화된 경로를 따르세요:
- 배포 상태:
kubectl get deployments-> 복제본이 준비 상태를 보고합니까? - Pod 이벤트:
kubectl describe pod <failing-pod>-> Events 섹션에서 즉각적인 오류(ImagePull, OOMKilled, 볼륨 문제)를 확인합니다. - 컨테이너 로그:
kubectl logs <failing-pod>-> 컨테이너가 시작되지만 충돌하는 경우(CrashLoopBackOff), 애플리케이션 로직 또는 liveness 프로브가 의심됩니다. - 리소스 확인: Pod가
Pending상태이면 리소스 제약(Insufficient cpu/memory) 또는 실패한 볼륨 바인딩(PVC 상태)을 확인합니다. - 구성 검증: 들여쓰기, 올바른 필드 이름 및 유효한 리소스 값(requests/limits)에 대해 YAML을 검토합니다.
추측하는 대신 클러스터의 증거를 기반으로 작업하세요. 상태, 이벤트, 로그, 리소스 및 매니페스트 구조를 해당 순서로 확인한 다음, 발견한 오류와 일치하는 가장 작은 YAML 변경을 수행하세요.