Haru Utils

IMAGE PULL

Kubernetes ImagePullBackOff·ErrImagePull 장애

이미지 이름·태그·digest, 레지스트리 DNS·TLS·인증, imagePullSecret의 namespace와 ServiceAccount 연결을 구분해 비밀값을 노출하지 않고 복구합니다.
ImagePullBackOffErrImagePullFailed to pull imageimagePullSecretsunauthorized registrymanifest unknown
환경Kubernetes v1.35·v1.36·v1.37 · CRI containerd · 공개·사설 OCI registry
분류컨테이너
검토일2026-09-02
진행5단계 · 조회 우선

SAFE OPERATING BOUNDARY

중단·복구 기준부터 확인하세요

STOP CONDITIONS

여기서는 멈추세요

  • Secret 값이나 registry 토큰을 출력·복사해야만 다음 단계가 가능하다면 중단하고 Secret 관리자에게 안전한 교체 절차를 요청합니다.
  • 사설 CA 검증을 끄거나 insecure registry를 추가하는 우회만 가능하다면 적용하지 않고 PKI·보안 담당자에게 전달합니다.
  • 현재 이미지 digest와 정상 revision을 확인할 수 없거나 registry 장애가 광범위하면 개별 Pod를 반복 재생성하지 않습니다.
ROLLBACK

복구 기준

이미지·imagePullSecrets 변경 전 보관한 manifest와 정상 rollout revision을 기준으로 복원합니다. Secret 교체는 이전 자격증명의 폐기 여부와 만료 상태를 확인한 뒤 조직의 Secret 관리 도구에서 되돌리고, Pod를 재생성하기 전에 registry 접근권한과 image digest를 다시 검증합니다.

ESCALATION PACK

담당자에게 전달할 자료

  • 민감정보를 제거한 Waiting.message와 Pod 이벤트, 실패 Pod의 Node 이름
  • 이미지 tag·digest·imagePullPolicy, Secret type·namespace·참조명만 포함한 메타데이터
  • Node별 DNS·TLS·containerd 오류 차이와 적용 전후 imageID·rollout 결과
2026년 9월 2일 기준 upstream 공식 문서와 현재 지원 버전을 대조했습니다. 먼저 읽기 전용 명령으로 사실을 확인하고, 변경 명령은 영향·백업·복구 경로를 확인한 뒤 승인된 대상에만 적용하세요. <...> 자리표시자는 승인된 리터럴 값으로 직접 치환하고 외부 입력으로 shell 명령을 조립하거나 eval하지 마세요.

BEFORE YOU START

이런 증상에서 시작합니다

  • Pod STATUS가 ImagePullBackOff 또는 ErrImagePull임
  • 이벤트에 unauthorized, denied, manifest unknown이 표시됨
  • x509: certificate signed by unknown authority 오류가 표시됨
  • 같은 이미지는 일부 Node에서만 당겨지고 다른 Node에서는 실패함

CHECK THE BRANCH

놓치기 쉬운 원인 분기

01

manifest unknown 또는 not found인 경우

registry host, repository 경로, tag 철자와 multi-architecture manifest를 확인합니다. mutable tag를 다시 덮어쓰기보다 빌드가 배포한 검증된 digest를 사용합니다.

02

unauthorized 또는 denied인 경우

Secret이 Pod와 같은 namespace에 있는지, type이 kubernetes.io/dockerconfigjson인지, ServiceAccount 또는 Pod의 imagePullSecrets가 그 이름을 참조하는지 확인합니다. Secret 원문은 출력하지 않습니다.

03

x509·timeout·DNS 오류인 경우

Pod 네트워크가 아니라 이미지를 가져오는 Node와 container runtime의 DNS·프록시·CA 신뢰 문제일 가능성이 큽니다. TLS 검증을 끄거나 insecure registry로 우회하지 않습니다.

04

특정 Node에서만 실패하는 경우

실패 Pod의 assigned Node와 정상 Node를 비교해 runtime 설정, CA bundle, egress, disk pressure와 architecture 차이를 확인합니다. 캐시된 이미지 때문에 정상처럼 보일 수도 있습니다.

FOLLOW THE FLOW

순서대로 확인하기

1
조회시스템을 변경하지 않는 확인 단계

1분 점검: 이벤트와 정확한 이미지 참조 확인

Pod가 시도한 이미지 문자열과 kubelet 이벤트의 원문 이유를 확인합니다. 메시지에 포함된 레지스트리 계정명은 공유 전에 마스킹합니다.

Pod·Node·상태
kubectl get pod -n <NAMESPACE> <POD> -o wide
컨테이너별 이미지와 대기 이유
kubectl get pod -n <NAMESPACE> <POD> -o jsonpath='{range .spec.containers[*]}{.name}{" image="}{.image}{"\n"}{end}{range .status.containerStatuses[*]}{.name}{" reason="}{.state.waiting.reason}{" message="}{.state.waiting.message}{"\n"}{end}'
이미지 pull 이벤트
kubectl events -n <NAMESPACE> --for pod/<POD> --types=Warning,Normal
결과 읽기

not found·manifest unknown은 이름/태그, unauthorized·denied는 인증, x509·timeout은 Node 네트워크/신뢰 저장소 분기로 봅니다.

다음 판단

오류 문구를 그대로 기록하되 토큰·계정·내부 registry 경로는 필요한 범위만 공유합니다.

2
조회시스템을 변경하지 않는 확인 단계

워크로드의 이미지·정책·소유자 확인

Pod 직접 수정이 아니라 상위 워크로드에서 image, imagePullPolicy와 revision을 확인합니다.

Pod 이미지 pull 설정
kubectl get pod -n <NAMESPACE> <POD> -o jsonpath='{.spec.serviceAccountName}{"\n"}{range .spec.imagePullSecrets[*]}{.name}{"\n"}{end}{range .spec.containers[*]}{.name}{" "}{.image}{" policy="}{.imagePullPolicy}{"\n"}{end}'
상위 Deployment 이미지
kubectl get deployment -n <NAMESPACE> <DEPLOYMENT> -o jsonpath='{range .spec.template.spec.containers[*]}{.name}{" "}{.image}{"\n"}{end}'
최근 배포 이력
kubectl rollout history deployment/<DEPLOYMENT> -n <NAMESPACE>
결과 읽기

Pod와 Deployment의 이미지 참조가 다르면 진행 중이거나 실패한 rollout일 수 있습니다. :latest의 로컬 캐시 여부만으로 성공을 판단하지 않습니다.

다음 판단

검증된 registry digest·tag와 배포 소스의 기대값을 비교합니다.

3
조회시스템을 변경하지 않는 확인 단계

Secret 메타데이터와 ServiceAccount 연결 확인

인증 정보의 값은 출력하지 않고 Secret type, 존재 namespace, 참조 관계만 확인합니다.

Secret type과 키 이름만 확인
kubectl get secret -n <NAMESPACE> <PULL_SECRET> -o jsonpath='{.type}{" keys="}{range $k,$v := .data}{$k}{" "}{end}{"\n"}'
-o yaml, -o json이나 base64 decode로 .dockerconfigjson 값을 출력하지 않습니다.
ServiceAccount pull secret 참조
kubectl get serviceaccount -n <NAMESPACE> <SERVICE_ACCOUNT> -o jsonpath='{range .imagePullSecrets[*]}{.name}{"\n"}{end}'
Pod 이벤트 중 Secret 오류
kubectl events -n <NAMESPACE> --for pod/<POD> --types=Warning
이벤트 메시지의 내부 registry 주소·image 이름·Secret 이름은 외부 공유 전 마스킹합니다.
결과 읽기

Secret이 없거나 다른 namespace에 있으면 참조할 수 없습니다. type과 참조가 맞아도 만료·권한 범위 문제는 registry 측 감사 로그나 안전한 인증 테스트가 필요합니다.

다음 판단

비밀값을 CLI 인자나 manifest 평문에 넣지 말고 조직의 Secret 배포 절차로 갱신안을 준비합니다.

4
주의서버 부하나 권한을 고려할 단계

실패 Node의 DNS·TLS·runtime 상태 확인

Node 운영 권한이 있을 때만 실패 Node에서 containerd와 kubelet 로그를 확인합니다. 진단 중 이미지를 강제 삭제하거나 insecure 설정을 추가하지 않습니다.

Node 조건
kubectl describe node <NODE>
describe 출력에는 내부 주소·label·annotation·workload 이름이 포함될 수 있습니다. 제한된 터미널에서 확인하고 외부 공유 전 마스킹합니다.
containerd·kubelet 최근 오류
sudo journalctl -u containerd.service -u kubelet.service --since '-15 min' --no-pager
registry 이름 해석과 TLS 인증서
getent ahosts <REGISTRY_HOST>
openssl s_client -connect <REGISTRY_HOST>:443 -servername <REGISTRY_HOST> -verify_return_error </dev/null
인증서 검증 실패를 무시하는 옵션을 추가하지 않습니다. 사설 CA는 승인된 배포 경로로 Node 신뢰 저장소에 설치합니다.
결과 읽기

모든 Node에서 같은 인증 오류면 Secret/registry, 한 Node만 x509·timeout이면 Node CA·프록시·egress·시간 차이를 우선 봅니다.

다음 판단

수정 범위를 이미지 참조, Secret 연결, Node 신뢰/네트워크 중 하나로 좁히고 각각 별도 변경으로 진행합니다.

5
변경데이터·서비스 상태가 달라질 수 있는 단계

검토된 이미지·Secret 참조 수정 후 검증

이 단계는 새 Pod 생성과 registry 접근을 유발합니다. 현재 manifest와 정상 revision을 보관하고 평문 자격증명이 없는 검토 파일만 적용합니다.

변경 단계입니다. 실행 전 대상 이름과 경로, 서비스 중단 영향, 복구 방법을 다시 확인하세요.
현재 워크로드 백업
install -d -m 0700 "<APPROVED_BACKUP_PATH>"
umask 077
kubectl get deployment -n <NAMESPACE> <DEPLOYMENT> -o yaml > "<APPROVED_BACKUP_PATH>/deployment.before-image-fix.yaml"
chmod 0600 "<APPROVED_BACKUP_PATH>/deployment.before-image-fix.yaml"
stat -Lc '%a %U:%G %n' "<APPROVED_BACKUP_PATH>/deployment.before-image-fix.yaml"
전체 YAML에는 literal env.value·annotation·내부 registry URL·식별자가 포함될 수 있습니다. 전용 0700 디렉터리와 0600 파일에서만 보관하고 원문을 외부에 공유하지 않습니다.
변경 미리보기
kubectl diff --server-side -f <REVIEWED_IMAGE_FIX.yaml>
승인된 변경 적용
kubectl apply --server-side -f <REVIEWED_IMAGE_FIX.yaml>
검증된 digest/tag 또는 조직의 Secret 관리 도구가 만든 참조만 포함합니다. dockerconfigjson 원문을 Git에 넣지 않습니다.
rollout·이벤트 검증
kubectl rollout status deployment/<DEPLOYMENT> -n <NAMESPACE> --timeout=5m
kubectl events -n <NAMESPACE> --for deployment/<DEPLOYMENT> --types=Warning,Normal
결과 읽기

새 Pod의 imageID가 기대 digest이고 Ready 상태이며 새 pull 경고가 없어야 합니다. 캐시에 있던 Pod 하나만 보고 복구로 판정하지 않습니다.

다음 판단

실패하면 백업 manifest·정상 revision과 Secret 배포 기록으로 되돌립니다. 재발 방지를 위해 immutable digest, 자격증명 만료 알림, 모든 Node의 registry egress·CA 검증을 배포 전 검사에 추가합니다.

PRIMARY REFERENCES

공식 문서

배포판과 버전에 따라 옵션·로그 위치가 다를 수 있습니다. 실행 전 서버의 --help와 로컬 매뉴얼을 함께 확인하세요.

도구 빠른 검색

최근 사용한 도구를 다시 열거나, 이름과 기능으로 검색하세요.

검색어와 도구의 입력·결과는 저장하지 않습니다.

↑↓ 이동 · Enter 열기 · Esc 닫기