← 中文资源

简体中文版本

Docker Hub 拉取限流 — CI 与集群中的 toomanyrequests

通过 registry 令牌与 ratelimit 响应头确认 Docker Hub 配额,使用专用账号认证、镜像代理与本地缓存解决拉取限流。

阅读英文原文

现象

拉取镜像报 toomanyrequests: You have reached your pull rate limit;集群中多个节点同时出现 ImagePullBackOff;CI 任务失败但本机 docker pull 仍可成功;扩容或夜间重建后集中出现。

诊断

先复现并确认完整错误:

docker pull nginx:1.27
docker info | grep -iE 'username|registry|credential'

用户名为空表示匿名拉取;在共享 CI 中使用个人账号同样会消耗该账号配额。要直接测量配额,可向 registry 申请拉取令牌并读取响应头:

TOKEN=$(curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:library/nginx:pull" | jq -r .token)
curl -sI -H "Authorization: Bearer $TOKEN" \
  https://registry-1.docker.io/v2/library/nginx/manifests/1.27 | grep -i ratelimit

ratelimit-remaining: 0 即可确认配额耗尽,与本地 Docker 守护进程无关。集群侧用 kubectl describe pod 查看事件,若多个节点同时报 429,通常是共享 NAT 出口或缺少 imagePullSecret。

修复

使用只读权限的机器账号令牌,配置为 Kubernetes imagePullSecret 与 CI Secret;在内网部署 pull-through cache 或 registry mirror;生产清单按 digest 固定镜像并复用缓存层;删除无意义的定时重新拉取。不要在 CI 中明文保存个人密码:

docker login registry-1.docker.io -u ci-puller --password-stdin < token.txt
docker pull nginx@sha256:0f0f0f...

验证

从节点与 CI 各拉取一次确认不再出现 429,registry 响应头中剩余配额明显大于 0;滚动发布后新 Pod 均应进入 Running 而不是 ImagePullBackOff。若仅单个节点失败,需单独检查其出口 IP,因为匿名配额按 IP 计算,一个 NAT 网关就可能拖累整个节点组。