私有镜像仓库拉取失败?可能是缺少pull secret
在公司搭建CI/CD流水线时,经常会遇到Pod启动失败,状态卡在ImagePullBackOff。查了一圈才发现,是因为使用的镜像是放在私有Harbor或私有Registry里的,而Kubernetes默认没有权限拉取。
这时候就需要用到pull secret了。它就像是一把通行证,让Pod能顺利从需要认证的镜像仓库下载镜像。
什么是pull secret
pull secret本质上是一个包含Docker registry认证信息的Secret资源,类型为kubernetes.io/dockerconfigjson。它保存的是.docker/config.json里的auth字段内容,也就是用户名、密码和服务器地址的Base64编码。
创建pull secret的步骤
假设你的私有仓库地址是registry.example.com,账号devuser,密码secretpass。先在命令行执行:
kubectl create secret docker-registry my-registry-secret \
--docker-server=registry.example.com \
--docker-username=devuser \
--docker-password=secretpass \
--docker-email=devuser@example.com这条命令会在当前命名空间生成一个叫my-registry-secret的Secret。如果要跨命名空间使用,记得在每个需要的命名空间里都创建一份,或者通过脚本批量同步。
绑定到ServiceAccount更省事
每次部署都要在Pod模板里写imagePullSecrets太麻烦。更常见的做法是把它绑定到default ServiceAccount上。
比如:
kubectl patch serviceaccount default \
-p '{"imagePullSecrets":[{"name":"my-registry-secret"}]}'这样一来,该命名空间下所有未显式指定imagePullSecrets的Pod,都会自动带上这个secret,部署YAML也干净多了。
实际部署中的配置示例
如果你还是想在Pod里手动指定,可以这样写:
<apiVersion> v1</apiVersion>
<kind> Pod</kind>
<metadata>
<name> myapp</name>
</metadata>
<spec>
<containers>
- <name> app</name>
<image> registry.example.com/myteam/app:v1</image>
</containers>
<imagePullSecrets>
- <name> my-registry-secret</name>
</imagePullSecrets>
</spec>注意imagePullSecrets是在spec层级下的,不是容器里的配置。
排查常见问题
如果配置完还是拉不到镜像,可以用kubectl describe pod看事件记录,通常会提示“Failed to pull image”和具体的认证错误。
检查点有几个:Secret名字拼错没?是不是在正确的命名空间?密码有没有过期?registry地址带不带https前缀?这些细节一旦出错,就会导致拉取失败。
有时候团队换了镜像仓库域名,但旧的pull secret没更新,也会出现类似问题。建议把Secret的创建过程写进自动化脚本,避免人为疏漏。