Docker Registry v2 API 无直接列出所有镜像端点,需用 /v2/_catalog 分页调用,配合 Basic Auth 认证、last 参数分页,并注意 Harbor 等私有仓库的路径与权限差异。

如何用 curl 直接调用 Docker Registry v2 API 获取镜像列表
Registry v2 API 不提供直接的“列出所有镜像”端点,/v2/_catalog 是唯一入口,但默认只返回最多 100 个仓库名,且必须手动处理分页和认证。
常见错误是直接 GET /v2/_catalog 却没带 Authorization 头,返回 401 Unauthorized;或忽略 last 参数,以为一次请求就能拉全量。
- 先用
docker login登录,再从~/.docker/config.json提取auth字段并 base64 解码,得到 username:password - 构造 Basic Auth:用
echo -n 'user:pass' | base64生成 token,放进Authorization: Basic <token> - 分页必须靠
last查询参数:GET /v2/_catalog?n=100&last=nginx,下次把上一页最后一个仓库名填进去 - 注意
Content-Type必须是application/json,否则某些私有 registry(如 Harbor)会静默返回空数组
Harbor 私有仓库调用 catalog 接口返回空或 403 的原因
Harbor 默认关闭匿名访问,即使你已登录 docker CLI,API 调用仍需显式传入有效 token,且权限粒度比 Docker Hub 更细——项目级权限不等于 registry 全局 catalog 权限。
典型现象:curl 返回 {"errors":[{"code":"FORBIDDEN","message":"forbidden"}]},或 {"repositories":[]} 但你知道库里有镜像。
- Harbor 的 catalog 接口路径是
/api/v2.0/projects/{project_name}/repositories(v2.0+),不是标准 registry 的/v2/_catalog - 必须用 Harbor 的用户 token,不能复用 docker login 生成的 basic auth;推荐走
/api/v1/users/current拿 session cookie,或调/service/token换 registry scope token - 确认当前用户在 Harbor UI 中对目标项目有
read权限,仅pull权限不够 - v1.10+ Harbor 默认禁用
_catalog,需在harbor.yml中显式开启registry:→compatibility:→schema1:false 不影响,但catalog需单独配
Python requests 调用 registry API 时 TLS 和重定向容易出错的地方
私有 registry 常用自签名证书或内网域名,requests 默认校验 HTTPS,而 redirect 行为又可能把原始 Authorization 头丢掉,导致跳转后 401。
错误示例:用 session.get(url, verify=False) 关闭证书校验,但没设 allow_redirects=True,结果卡在 302 不动;或者开了重定向却没传 auth 参数,跳过去就失效。
- 务必显式传
auth=requests.auth.HTTPBasicAuth(user, password),别只靠 headers 里塞 Authorization - 重定向必须保留认证头:requests 默认会丢,要加
auth参数而非 headers,它内部会自动透传 - 自签名证书不要简单设
verify=False,应指定verify='/path/to/ca.crt',否则中间人攻击风险真实存在 - registry 地址末尾不要加
/,比如https://reg.example.com可以,https://reg.example.com/可能在某些 nginx 反代配置下触发非预期重定向
用 skopeo 同步镜像时如何避免因 API 限流或 429 导致任务失败
skopeo copy 底层走的就是 registry API,但它不自动处理 429 Too Many Requests,一旦私有 registry(如 Nexus、Harbor)启用了速率限制,同步中途就会报错退出,且无重试机制。
现象是日志里突然出现 error copying image to the remote destination: Error writing blob: Error initiating layer upload to ...: received unexpected HTTP status: 429 Too Many Requests。
- 加
--retry-times 3和--retry-delay 2s参数,skopeo 1.10+ 支持,但仅对 pull/push 阶段生效,blob 上传失败仍可能不重试 - 更稳的做法是前置检查 registry 的
RateLimit-Limit和RateLimit-Remaining响应头,用 curl 先探活再触发 skopeo - 避免并发跑多个 skopeo copy 到同一 registry,它们共享同一个 IP 的限流桶;可加
sleep $((RANDOM % 5))错峰 - 某些 registry(如 ECR)的 429 不带
Retry-After头,此时硬 sleep 1s 往往不够,建议至少 3s 起步










