bigywater.tech
Kubernetes · 103

imagePullSecrets:私有仓库认证怎么传给运行时

私有仓库的凭证是怎么交给运行时的?Secret 里到底存了什么?ServiceAccount 上配置 imagePullSecrets 有什么用?为什么 Pod 引用了 secret 还是拉取失败?这篇用一个会记录 Authorization 头的假仓库,把每一步看清楚。

401 → not found
带上正确的 imagePullSecrets 后,拉取失败的原因从认证失败变成“镜像不存在”,说明凭证被仓库接受
3 + 2
一次拉取里仓库收到的请求:3 个不带 Authorization 的探测,2 个带凭证
同命名空间
imagePullSecrets 只能引用与 Pod 同命名空间的 Secret;引用不到会被静默忽略

Secret 的内容

实测 · 本机执行输出
  type=kubernetes.io/dockerconfigjson;data 的键=['.dockerconfigjson']
  解码后的 .dockerconfigjson:auths 的键=['localhost:5000'];里面 ['auth', 'email', 'password', 'username'];auth 字段 = base64("用户名:密码") = cHVsbGVyOnMzY3JldA== → puller:s3cret

kubectl 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,就是凭证被接受的证据。

用 ServiceAccount 统一配置

实测 · 本机执行输出
  给 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,引用不到会被忽略,排查时要从拉取失败的原因倒推。

分步演示

imagePullSecrets
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / kind(Docker 里的单节点或多节点真实集群,节点是 Docker Desktop 虚拟机里的容器)/ kubectl;用空的 kubeconfig 之外的独立 kubeconfig,不碰用户自己的集群;计时用 date +%s%N / kubectl 事件时间戳,数字每次运行会有小幅抖动。三节点 kind 集群 kx-main(Kubernetes v1.37.0,containerd v2.3.4);假仓库是 worker 上的 hostNetwork Pod(python http.server),要求 Basic 认证,containerd 通过 /etc/containerd/certs.d/localhost:5000/hosts.toml 用 HTTP 访问它;认证通过后对不存在的镜像返回 404;请求头由假仓库逐条打印;每种情形各一次
    • 没有验证:Bearer token 认证的完整流程(401 + realm 获取令牌);kubelet 凭证提供者插件(credential provider,云上 ECR/GCR 用);节点本地 config.json 里的凭证;同一个仓库配置多个 secret 时的选择顺序;镜像真正拉取成功的情形(假仓库不提供镜像);imagePullSecrets 对 initContainers 的适用
    京ICP备2026067502号-1京公网安备11010502063487号