问题出现得很突然,日志倒是留得挺全。Kubernetes 1.28 加 containerd,Pod 一直是 ErrImagePull,事件里写 401 Unauthorized,节点上用 crictl 手动拉同一个镜像却能成功。
刚开始盯着「Secret 类型不是 docker-registry」,折腾了半个多小时,排掉了。
原因不止一个,得分开看。Pod 没有引用 imagePullSecrets。也可能是Secret 建在了别的 namespace。
不容易想到的是,ServiceAccount 没有绑定拉取密钥。
上来先看 Pod 的失败事件
kubectl describe pod api-0 | grep -A3 'Failed'
建一个正确类型的 Secret
kubectl create secret docker-registry regcred --docker-server=registry.example.com --docker-username=robot --docker-password=$TOKEN
绑到默认 ServiceAccount
kubectl patch serviceaccount default -p '{"imagePullSecrets":[{"name":"regcred"}]}'
末了重建 Pod 确认状态
kubectl get pod api-0 -o wide
排查用的命令都是临时敲的,没有写成脚本,事后才整理。
手上没有现成的复现脚本,就照着线上请求手工拼了一个。
报错是间歇性的,我蹲守了半小时才抓到一次完整现场。
白天有业务在跑,能验证的部分都压到了晚上做。
别只看报错消失,验证要多做一步。新 Pod 能拉到镜像并进入 Running,事件里不再出现 401。
节点能拉不代表集群能拉,kubelet 用的是 Pod 上声明的凭据,两条路径要分开验证。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。
