1. 从一次 Pod 拉取镜像失败说起Kubernetes 部署应用时从 Harbor 拉取镜像失败报repository does not exist or may require docker login这个报错在 K8s 集群里出现的频率相当高。它字面意思是「仓库不存在或者需要登录」但真正的原因往往不是镜像没了而是节点上的认证配置没到位。你如果只盯着 Harbor 界面看镜像在不在很容易绕远路。这个报错能帮我们做什么它其实是 kubelet 在拉取镜像时把底层容器运行时返回的鉴权失败信息原样抛了出来。适合谁看正在用 Kubernetes 部署业务、私有 Harbor 做镜像仓库、Pod 卡在ImagePullBackOff或ErrImagePull的同学。我试过在几个不同规模的集群里复现这个问题结论很一致九成以上是 imagePullSecret 缺失、Secret 内容格式不对或者节点级config.json没同步。下面按「先定位、再补认证、最后验证」的顺序走一遍每一步都给可复制的命令和配置骨架。目标是一次性把认证配置补齐而不是反复重启 Pod 碰运气。2. 先确认镜像与节点权限再谈 K8s 配置排查要分两层Harbor 侧镜像是否存在节点侧是否有拉取权限。很多人一上来就改 Deployment其实应该先在节点上手动拉一次。登录到 Pod 所在节点用kubectl get pod -o wide看 NODE 列执行docker pull harbor.example.com/oneapi-2/authtenantserver:15如果返回denied: requested access to the resource is denied说明节点没有 Harbor 的登录凭证。这时候执行一次登录docker login harbor.example.com -u your-user -p your-pass登录成功后Docker 会把凭证写到/root/.docker/config.json。再次docker pull应该就能拉到本地。这一步很关键它证明「镜像存在 账号有权限」问题被缩小到「Kubernetes 没拿到这份凭证」。注意docker login生成的凭证默认只对当前用户和当前节点有效kubelet 拉镜像时用的是自己的配置路径两者不共享。3. 创建 imagePullSecret 并挂到 DeploymentKubernetes 拉取私有仓库镜像标准做法是创建一个kubernetes.io/dockerconfigjson类型的 Secret然后在 Pod 模板里引用。创建命令有两种推荐用命令行直接生成避免手写 base64 出错。kubectl create secret docker-registry harbor-secret \ --docker-serverharbor.example.com \ --docker-usernameyour-user \ --docker-passwordyour-pass \ --docker-emailyour-mailexample.com \ -n your-namespace如果你已经有一份config.json也可以直接用它生成kubectl create secret generic harbor-secret \ --from-file.dockerconfigjson/root/.docker/config.json \ --typekubernetes.io/dockerconfigjson \ -n your-namespace创建完成后Secret 里的.dockerconfigjson骨架长这样你可以用kubectl get secret harbor-secret -o jsonpath{.data.\.dockerconfigjson} | base64 -d查看{ auths: { harbor.example.com: { username: your-user, password: your-pass, auth: base64(user:pass) } } }然后在 Deployment 里引用它。注意imagePullSecrets要写在spec.template.spec下和containers同级apiVersion: apps/v1 kind: Deployment metadata: name: authtenantserver namespace: your-namespace spec: replicas: 1 selector: matchLabels: app: authtenantserver template: metadata: labels: app: authtenantserver spec: imagePullSecrets: - name: harbor-secret containers: - name: app image: harbor.example.com/oneapi-2/authtenantserver:15 ports: - containerPort: 8080应用后重新部署kubectl apply -f deployment.yaml kubectl rollout restart deployment/authtenantserver -n your-namespace4. 用 kubectl describe pod 验证拉取事件配置改完不代表就通了必须看事件确认。执行kubectl describe pod pod-name -n your-namespace重点看Events区域。成功时你会看到类似Normal Pulling pulling image harbor.example.com/oneapi-2/authtenantserver:15 Normal Pulled Successfully pulled image Normal Created Created container app Normal Started Started container app如果还是失败事件里会继续出现Failed to pull image ... repository does not exist or may require docker login。这时候要检查三件事Secret 是否在同一个 namespace、imagePullSecrets名字是否拼对、Secret 里的 server 地址是否和镜像地址完全一致包括端口。一个常见坑是镜像地址写成harbor.example.com:443/...而 Secret 里 server 写的是harbor.example.com两者不匹配就会鉴权失败。地址必须逐字符对齐。5. 本篇常见错误排查清单下面这些是我在集群里踩过的坑按出现频率排序你可以对照检查。现象可能原因处理方式报 repository does not exist镜像 tag 写错或仓库路径不对在 Harbor 界面核对完整路径与 tag报 may require docker loginimagePullSecret 未引用或名字错检查spec.template.spec.imagePullSecretsSecret 创建了仍失败Secret 与 Pod 不在同一 namespace用-n指定相同命名空间部分节点成功部分失败节点级/var/lib/kubelet/config.json缺失同步该文件到所有节点改了配置仍拉旧凭证kubelet 缓存了旧 Secret删除 Pod 让其重建或重启 kubelet关于节点级config.json有些老集群或特定运行时下kubelet 会读取/var/lib/kubelet/config.json。如果 imagePullSecret 方式不生效可以把登录后的/root/.docker/config.json复制过去cp /root/.docker/config.json /var/lib/kubelet/config.json systemctl restart kubelet注意这个操作要在集群所有可能调度到该应用的节点上执行否则 Pod 漂移到没配置的节点会再次失败。另外重新部署时尽量让 Pod 落在原来的节点上验证确认单节点修复有效后再批量同步到其他节点。如果只有个别节点报错优先怀疑节点级配置差异而不是 Deployment 本身。6. 认证配好之后把模型接入也顺手理一遍镜像能拉起来说明集群和 Harbor 的认证链路已经通了。接下来如果你要在这些 Pod 里跑大模型调用或编码 Agent凭证管理是同一套思路集中配置、按命名空间隔离、避免硬编码。TaoToken 这边提供了兼容常见接口规范的接入方式API 地址是https://taotoken.net/api你可以把它当成一个统一的模型入口来用。具体操作上先到 API Keys 生成密钥再对照 接入文档 把 base_url 和 key 填进你的应用配置。想先验证模型通不通可以直接用 模型对话 发一条测试请求。如果你在集群里长期跑编码类 AgentCoding Plan 更适合按周期管理调用量。密钥同样建议用 Secret 注入环境变量别写进镜像里和刚才处理 Harbor 凭证是一个道理。