私有仓库的凭证是怎么交给运行时的?Secret 里到底存了什么?ServiceAccount 上配置 imagePullSecrets 有什么用?为什么 Pod 引用了 secret 还是拉取失败?这篇用一个会记录 Authorization 头的假仓库,把每一步看清楚。
type=kubernetes.io/dockerconfigjson;data 的键=['.dockerconfigjson']
解码后的 .dockerconfigjson:auths 的键=['localhost:5000'];里面 ['auth', 'email', 'password', 'username'];auth 字段 = base64("用户名:密码") = cHVsbGVyOnMzY3JldA== → puller:s3cretkubectl create secret docker-registry regcred --docker-server=localhost:5000 --docker-username=puller --docker-password=s3cret:type 是 kubernetes.io/dockerconfigjson,data 只有一个键 .dockerconfigjson;解码后是 {"auths": {"localhost:5000": {username, password, email, auth}}},auth 字段是 base64("用户名:密码") —— cHVsbGVyOnMzY3JldA==,解码得 puller:s3cret。这和 Secret 一样只是编码,不是加密(见 k58)。
仓库收到 5 个对 team/app 的请求:其中 3 个没有 Authorization 头(不带凭证的探测),2 个带 Authorization:['puller:s3cret']
nosecret Pod:ErrImagePull;pull access denied, repository does not exist or may require authorization: authorization failed: no basic auth credentials
withsecret Pod:ErrImagePull;localhost:5000/team/app:1.0: not found(认证通过了,失败原因变成“镜像不存在”)
Pod spec 里:withsecret.spec.imagePullSecrets=[{'name': 'regcred'}]假仓库要求 Basic 认证 puller:s3cret。两个 Pod 拉 localhost:5000/team/app:1.0:仓库收到 5 个请求,其中 3 个没有 Authorization 头(运行时先不带凭证探测,收到 401 + WWW-Authenticate 才带凭证重来),2 个带了,解码是 puller:s3cret。nosecret 失败原因是 pull access denied, repository does not exist or may require authorization: authorization failed: no basic auth credentials;withsecret(spec.imagePullSecrets=[regcred])失败原因变成 localhost:5000/team/app:1.0: not found——认证通过了,这个镜像本来就不存在。报错从 401 变成 not found,就是凭证被接受的证据。
给 default ServiceAccount 加上 imagePullSecrets: [regcred] 后,新建的 Pod viasa 没写 imagePullSecrets,spec.imagePullSecrets=[{'name': 'regcred'}](ServiceAccount 准入补进去的)
viasa:ErrImagePull;localhost:5000/team/app:2.0: not found给 default ServiceAccount 加上 imagePullSecrets: [regcred]:新建的 Pod viasa 没写 imagePullSecrets,但 spec.imagePullSecrets 已经是 [{name: regcred}]——ServiceAccount 准入把它补进来了,拉取 localhost:5000/team/app:2.0 同样认证通过。(只处理新建的 Pod,已有的不会被改。)
secret 的 auths 键是 registry.other.com,镜像在 localhost:5000:ErrImagePull;pull access denied, repository does not exist or may require authorization: authorization failed: no basic auth credentials(仓库地址不匹配,凭证不会发给它)
地址对但密码错:ErrImagePull;unexpected status from HEAD request to http://localhost:5000/v2/team/app/manifests/4.0: 401 Unauthorized
命名空间 k97b 里的 Pod 引用 k97 里的 secret regcred(imagePullSecrets 只能引用同命名空间的):创建是否成功:True;容器状态 ('waiting', 'ErrImagePull')
pull access denied, repository does not exist or may require authorization: authorization failed: no basic auth credentials
事件:['4s Normal Pulling pod/otherns Pulling image "localhost:5000/team/app:5.0"', '4s Warning Failed pod/otherns Failed to pull image "localhost:5000/team/app:5.0": failed to pull and unpack image "localhost:5000/team/app:5.0": faile', '4s Warning Failed pod/otherns Error: ErrImagePull']secret 的 auths 键写成 registry.other.com,镜像在 localhost:5000:仍是 no basic auth credentials,凭证不会发给地址不匹配的仓库;地址对但密码错:401 Unauthorized;命名空间 k97b 的 Pod 引用 k97 里的 regcred:Pod 照样创建成功,但拉取失败 no basic auth credentials——imagePullSecrets 只能引用同命名空间的 Secret,引用不到会被忽略,排查时要从拉取失败的原因倒推。