Kubernetes ImagePullBackOff: 레지스트리가 아니라 IAM
I’m happy to translate the article for you, but I need the full text of the post (the content you’d like translated). Could you please paste the article’s body here? I’ll keep the source line, formatting, markdown, and any code blocks exactly as they are, and translate only the prose into Korean.
ImagePullBackOff – 왜 보통 레지스트리 문제가 아니라 인증 문제인가
2026년 현재, 파드가 ImagePullBackOff 상태가 되면 레지스트리는 보통 정상이다.
이미지 태그가 존재하고, 저장소가 가동 중이며, 그쪽에 문제는 없다.
실제 원인은 종종 Kubernetes 노드이다.
ImagePullBackOff가 실제 의미하는 바
“이미지를 가져오려고 했지만 실패했고, 이제 다시 시도하기 전에 더 오래 기다리겠다.”
Kubelet은 왜 가져오기가 실패했는지 알려주지 않는다.
가장 흔한 숨은 원인: 인증 토큰이 조용히 만료되었다.
전형적인 디버깅 흐름 (그리고 왜 실패하는가)
| 보이는 현상 | 생각하는 원인 |
|---|---|
ImagePullBackOff | “이미지 태그가 잘못되었을 수도 있습니다.” |
ImagePullBackOff | “레지스트리가 다운되었을 수도 있습니다.” |
ImagePullBackOff | “Docker Hub가 속도 제한을 걸었을 수도 있습니다.” |
레지스트리가 실제로 다운된 경우 연결 시간 초과가 발생합니다.
ImagePullBackOff는 보통 연결은 성공했지만 인증 핸드셰이크가 실패했음을 의미합니다.
Source: …
실제 문제는 Credential Provider에 있습니다
Kubernetes가 인‑트리 클라우드 제공자를 제거한 이후(“Great Decoupling”), kubelet은 클라우드 레지스트리(ECR, ACR 등)용 단기 인증 토큰을 얻기 위해 외부 Kubelet Credential Provider에 의존합니다.
Pull 흐름 개요
- 요청 – kubelet이
12345.dkr.ecr.us-east-1.amazonaws.com/app:v1와 같은 이미지를 발견합니다. - 교환 – kubelet이 Credential Provider 플러그인에 토큰을 요청합니다(AWS IAM, Azure Entra ID 등).
- 검증 – 클라우드가 노드의 IAM 역할이 허용되는지 확인합니다.
- Pull – 유효한 토큰을 사용해 kubelet이 레지스트리에 요청을 전달합니다.
3단계가 실패하면(토큰 만료, 시계 오차, IMDS 장애, IAM 정책 누락 등) 레지스트리는 401 Unauthorized를 반환하고, kubelet은 일반적인 ImagePullBackOff 오류를 보고합니다.
Fast‑Track to the Root Cause
1. Get the real error message
kubectl describe pod <pod-name>
Look for lines such as:
rpc error: code = Unknown desc = failed to authorize: failed to fetch anonymous token: unexpected status: 401 Unauthorized
or
no basic auth credentials
These indicate an authentication failure, not a network or registry outage.
2. Bypass Kubernetes and test the node directly
Most modern clusters run containerd (Docker shim is gone). Use
crictl, notdocker.
# SSH to the node
crictl pull <image>
| Result | Interpretation |
|---|---|
| Success | Node IAM is fine → problem is in ServiceAccount / imagePullSecrets. |
| Failure | Node itself is mis‑configured → IAM, network, or clock issue. |
If it fails, dig into the container runtime logs:
journalctl -u containerd --no-pager | grep -i "failed to pull"
일반적인 IAM 관련 원인 및 해결책
| 클라우드 | 증상 | 일반적인 원인 | 해결책 |
|---|---|---|---|
| AWS | 일부 노드에서 무작위 401 오류 발생 | 노드의 인스턴스 프로필에 AmazonEC2ContainerRegistryReadOnly(또는 ecr:GetAuthorizationToken / ecr:BatchGetImage) 정책이 없음 | 해당 정책을 노드 역할에 연결합니다. |
| Azure | 클러스터 생성 후 포드가 ImagePullBackOff 상태에 머무름 | AcrPull 역할이 아직 전파되지 않음(약 10 분 소요될 수 있음) | 기다리거나 다음 명령으로 확인: az aks show -n <cluster> -g <rg> --query "identityProfile.kubeletidentity.clientId" |
| GCP | 올바른 서비스 계정임에도 403 Forbidden 발생 | 노드가 기본 Storage Read‑Only 액세스 스코프로 생성되어 Artifact Registry API에 접근할 수 없음 | Workload Identity 사용하거나 cloud-platform 스코프로 노드 풀을 재생성합니다. |
토큰 만료 및 시계 오차
- AWS EKS 토큰은 12 시간마다 만료됩니다.
- GCP 메타데이터 토큰은 1 시간마다 만료됩니다.
노드의 시계가 오차가 발생(NTP 장애)하거나 Instance Metadata Service (IMDS) 가 제한되면 kubelet이 토큰을 갱신할 수 없어, 일정 기간 안정된 후 ImagePullBackOff 가 발생합니다.
감지: NTP/IMDS 알림을 위해 node-problem-detector 를 모니터링합니다.
네트워크‑관련 검사
아웃바운드 트래픽을 잠그면 (PrivateLink, Private Endpoints, VPC Endpoint 정책) 잘못 구성된 엔드포인트가 트래픽을 조용히 차단할 수 있습니다.
노드에서 테스트:
curl -v https://<registry-host>/v2/
| 응답 | 의미 |
|---|---|
| Timeout / Hang | 네트워킹 문제 (Security Group, PrivateLink, VPC Endpoint). |
| 401 Unauthorized | IAM 문제 (네트워크는 정상). |
| 200 OK | 레지스트리 접근 가능 → 이미지 태그에 오타가 있을 가능성이 높음. |
Recommended Hardening Checklist
- Workload Identity 사용 – 노드 전체 인스턴스 프로파일 대신 Kubernetes ServiceAccount에 IAM 역할을 바인딩합니다.
- VPC 엔드포인트 / 프라이빗 링크 활성화 – 레지스트리 트래픽을 퍼블릭 인터넷에서 차단합니다.
- IMDS 상태 모니터링 – 노드가 클라우드 메타데이터 서비스에 접근하지 못하면 알림을 보냅니다.
- 401 오류 알림 –
ImagePullBackOff또는 레지스트리 401 응답 시 Prometheus/Alertmanager가 경보를 발생하도록 설정합니다. - 노드 주간 교체 – 구성 드리프트와 좀비 프로세스를 방지합니다.
- containerd 선호 – Docker 대신
crictl로 풀 테스트를 수행합니다.
TL;DR
ImagePullBackOff는 드물게 Docker‑registry 문제이며,
거의 항상 IAM / 자격 증명(identity) 문제입니다.
Docker Hub UI를 계속 바라보지 말고 – 노드의 자격 증명 제공자, IAM 정책, 시계 동기화, 그리고 네트워크 경로에 집중하세요. 이들을 확인하면 파드가 이미지를 문제 없이 풀어냅니다.
## Destination
핸드쉐이크 감사를 시작합니다.
### Part 2: The Scheduler is Stuck
**Pending Pods 디버깅**
### It’s Not DNS (It’s MTU)
**Ingress 디버깅**
### Storage Has Gravity
**PVC 디버깅**