여기서는 멈추세요
- Secret 값이나 registry 토큰을 출력·복사해야만 다음 단계가 가능하다면 중단하고 Secret 관리자에게 안전한 교체 절차를 요청합니다.
- 사설 CA 검증을 끄거나 insecure registry를 추가하는 우회만 가능하다면 적용하지 않고 PKI·보안 담당자에게 전달합니다.
- 현재 이미지 digest와 정상 revision을 확인할 수 없거나 registry 장애가 광범위하면 개별 Pod를 반복 재생성하지 않습니다.
IMAGE PULL
SAFE OPERATING BOUNDARY
이미지·imagePullSecrets 변경 전 보관한 manifest와 정상 rollout revision을 기준으로 복원합니다. Secret 교체는 이전 자격증명의 폐기 여부와 만료 상태를 확인한 뒤 조직의 Secret 관리 도구에서 되돌리고, Pod를 재생성하기 전에 registry 접근권한과 image digest를 다시 검증합니다.
BEFORE YOU START
CHECK THE BRANCH
registry host, repository 경로, tag 철자와 multi-architecture manifest를 확인합니다. mutable tag를 다시 덮어쓰기보다 빌드가 배포한 검증된 digest를 사용합니다.
Secret이 Pod와 같은 namespace에 있는지, type이 kubernetes.io/dockerconfigjson인지, ServiceAccount 또는 Pod의 imagePullSecrets가 그 이름을 참조하는지 확인합니다. Secret 원문은 출력하지 않습니다.
Pod 네트워크가 아니라 이미지를 가져오는 Node와 container runtime의 DNS·프록시·CA 신뢰 문제일 가능성이 큽니다. TLS 검증을 끄거나 insecure registry로 우회하지 않습니다.
실패 Pod의 assigned Node와 정상 Node를 비교해 runtime 설정, CA bundle, egress, disk pressure와 architecture 차이를 확인합니다. 캐시된 이미지 때문에 정상처럼 보일 수도 있습니다.
FOLLOW THE FLOW
Pod가 시도한 이미지 문자열과 kubelet 이벤트의 원문 이유를 확인합니다. 메시지에 포함된 레지스트리 계정명은 공유 전에 마스킹합니다.
kubectl get pod -n <NAMESPACE> <POD> -o widekubectl 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}'kubectl events -n <NAMESPACE> --for pod/<POD> --types=Warning,Normalnot found·manifest unknown은 이름/태그, unauthorized·denied는 인증, x509·timeout은 Node 네트워크/신뢰 저장소 분기로 봅니다.
오류 문구를 그대로 기록하되 토큰·계정·내부 registry 경로는 필요한 범위만 공유합니다.
Pod 직접 수정이 아니라 상위 워크로드에서 image, imagePullPolicy와 revision을 확인합니다.
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}'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와 배포 소스의 기대값을 비교합니다.
인증 정보의 값은 출력하지 않고 Secret type, 존재 namespace, 참조 관계만 확인합니다.
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 값을 출력하지 않습니다.kubectl get serviceaccount -n <NAMESPACE> <SERVICE_ACCOUNT> -o jsonpath='{range .imagePullSecrets[*]}{.name}{"\n"}{end}'kubectl events -n <NAMESPACE> --for pod/<POD> --types=Warning이벤트 메시지의 내부 registry 주소·image 이름·Secret 이름은 외부 공유 전 마스킹합니다.Secret이 없거나 다른 namespace에 있으면 참조할 수 없습니다. type과 참조가 맞아도 만료·권한 범위 문제는 registry 측 감사 로그나 안전한 인증 테스트가 필요합니다.
비밀값을 CLI 인자나 manifest 평문에 넣지 말고 조직의 Secret 배포 절차로 갱신안을 준비합니다.
Node 운영 권한이 있을 때만 실패 Node에서 containerd와 kubelet 로그를 확인합니다. 진단 중 이미지를 강제 삭제하거나 insecure 설정을 추가하지 않습니다.
kubectl describe node <NODE>describe 출력에는 내부 주소·label·annotation·workload 이름이 포함될 수 있습니다. 제한된 터미널에서 확인하고 외부 공유 전 마스킹합니다.sudo journalctl -u containerd.service -u kubelet.service --since '-15 min' --no-pagergetent 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 신뢰/네트워크 중 하나로 좁히고 각각 별도 변경으로 진행합니다.
이 단계는 새 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에 넣지 않습니다.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와 로컬 매뉴얼을 함께 확인하세요.