수요일

Kubernetes ImagePullBackOff 에러 해결법

🔍 검색 키워드: k8s ImagePullBackOff, 쿠버네티스 이미지 풀 실패, Docker 레지스트리 인증, 이미지 태그 오류, Pod 시작 실패

Kubernetes ImagePullBackOff 에러 해결법

증상

Kubernetes Pod를 배포했을 때 다음과 같은 상태에서 멈춘다:

$ kubectl get pods -n production
  NAME                    READY   STATUS             RESTARTS   AGE
  app-deployment-abc123   0/1     ImagePullBackOff   2          5m

상세 확인 시:

$ kubectl describe pod app-deployment-abc123 -n production
  Events:
    Type     Reason                 Age   Message
      ----     ------                 ----  -------
        Normal   Scheduled              5m    Successfully assigned production/app-deployment-abc123 to worker-node-1
          Normal   BackOff                4m    Back-off pulling image "myrepo/app:v1.0"
            Warning  Failed                 4m    Failed to pull image "myrepo/app:v1.0": rpc error: code = Unknown desc = Error response from daemon: unauthorized
              Warning  Failed                 3m    Back-off pulling image

또는 다음과 같은 메시지:

image not found
  image pull rate limit exceeded
  no such image
  invalid reference format

원인

  1. 이미지명 오류: 잘못된 저장소명, 태그 또는 레지스트리 주소
  2. 인증 실패: Private Docker 레지스트리 접근 권한 없음
  3. 네트워크 단절: 워커 노드에서 레지스트리 접근 불가
  4. 레지스트리 다운: Docker Hub, ECR 등 서비스 장애
  5. 이미지 미존재: 푸시되지 않은 이미지 태그
  6. 레이트 제한: Docker Hub 무료 계정 풀 한도 초과
  7. CPU/메모리 부족: 노드 리소스 부족으로 스케줄링 실패

해결 방법

방법 1: 이미지명 및 태그 확인

# 현재 Pod의 이미지 정보 확인
  kubectl get pod app-deployment-abc123 -n production -o yaml | grep image
  
  # 정확한 이미지명 확인 (레지스트리 포함)
  # 형식: [registry]/[repository]/[image]:[tag]
  # 정상 예: docker.io/myrepo/app:v1.0
  # 정상 예: gcr.io/my-project/app:latest
  # 정상 예: ecr.amazonaws.com/123456789.dkr.ecr.us-east-1.amazonaws.com/app:v1.0

Deployment 수정:

apiVersion: apps/v1
  kind: Deployment
  metadata:
    name: app-deployment
      namespace: production
      spec:
        replicas: 3
          selector:
              matchLabels:
                    app: app
                      template:
                          metadata:
                                labels:
                                        app: app
                                            spec:
                                                  containers:
                                                        - name: app
                                                                image: docker.io/myrepo/app:v1.0  # 정확한 이미지명
                                                                        imagePullPolicy: IfNotPresent      # 또는 Always

방법 2: Private 레지스트리 인증 설정

# 1. Docker 자격증명으로 Secret 생성
  kubectl create secret docker-registry regcred \
    --docker-server=gcr.io \
      --docker-username=_json_key \
        --docker-password="$(cat ~/gcr-key.json)" \
          --docker-email=user@example.com \
            -n production
            
            # 2. 또는 기존 docker config 파일 사용
            kubectl create secret generic regcred \
              --from-file=.dockerconfigjson=$HOME/.docker/config.json \
                --type=kubernetes.io/dockercfg \
                  -n production

Deployment에서 사용:

apiVersion: apps/v1
  kind: Deployment
  metadata:
    name: app-deployment
    spec:
      template:
          spec:
                imagePullSecrets:
                      - name: regcred  # 위에서 생성한 Secret 이름
                            containers:
                                  - name: app
                                          image: gcr.io/my-project/app:v1.0

방법 3: 워커 노드 네트워크 확인

# 워커 노드에서 직접 레지스트리 연결 확인
  kubectl debug node/worker-node-1 -it --image=ubuntu
  # Pod 내에서:
  apt-get update && apt-get install -y curl
  curl -I https://gcr.io
  curl -I https://docker.io
  
  # 또는 임시 Pod에서 테스트
  kubectl run test-curl --image=curlimages/curl -it --rm -- \
    curl -v https://gcr.io

방법 4: 로컬에서 이미지 빌드 및 푸시 확인

# 1. 로컬에서 이미지 빌드
  docker build -t myrepo/app:v1.0 .
  
  # 2. 레지스트리에 푸시
  docker push myrepo/app:v1.0
  
  # 3. 푸시된 이미지 확인
  # Docker Hub: https://hub.docker.com/r/myrepo/app
  # GCR: gcloud container images list
  # ECR: aws ecr describe-images --repository-name app
  
  # 4. 로컬에서 이미지 실행 가능 확인
  docker run --rm myrepo/app:v1.0 --version

방법 5: imagePullPolicy 조정

apiVersion: apps/v1
  kind: Deployment
  metadata:
    name: app-deployment
    spec:
      template:
          spec:
                containers:
                      - name: app
                              image: myrepo/app:v1.0
                                      # imagePullPolicy 옵션:
                                              # Always: 매번 레지스트리에서 풀 (기본, 태그 latest 사용 시)
                                                      # IfNotPresent: 로컬에 없을 때만 풀
                                                              # Never: 로컬에서만 사용 (오프라인 환경)
                                                                      imagePullPolicy: Always

방법 6: 디버깅 및 재시도

# Pod 상세 로그 확인
  kubectl logs app-deployment-abc123 -n production --previous
  
  # 이벤트 확인 (시간 역순)
  kubectl get events -n production --sort-by='.lastTimestamp'
  
  # Pod 재생성 (자동 재시도)
  kubectl rollout restart deployment/app-deployment -n production
  
  # 캐시 클리어 후 재배포
  kubectl set image deployment/app-deployment \
    app=myrepo/app:v1.1 \
      -n production
      
      # 또는 현재 이미지로 강제 롤아웃
      kubectl rollout restart deployment/app-deployment -n production

정리표

원인 증상 해결법
이미지명 오류 image not found 정확한 이미지명 확인
인증 실패 unauthorized imagePullSecrets 설정
네트워크 단절 connection timeout 워커 노드 네트워크 확인
레지스트리 장애 service unavailable 레지스트리 상태 확인
태그 미존재 manifest not found docker push 재실행
레이트 제한 rate limit exceeded 인증된 계정으로 전환
노드 리소스 부족 OutOfmemory, OutOfDisk 노드 리소스 확인

: 배포 전에 로컬 환경에서 docker push까지 성공하는지 확인하고, 클러스터에는 imagePullPolicy: Always 설정으로 항상 최신 이미지를 가져오도록 설정하면 버전 관리가 쉬워집니다.

댓글 없음:

댓글 쓰기