Please enable Javascript to view the contents

如何绕过 DockerHub 拉取镜像限制

 ·  ☕ 3 分钟

1. DockerHub 限制

终究还是绕不过下面这个报错:

1
Error response from daemon: toomanyrequests: You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limit

DockerHub 从 2020 年 11 月 2 日,正式开始限制非付费用户的拉取频率:

  • 匿名用户,每 6 小时只允许 pull 100 次

  • 已登录用户,每 6 小时只允许 pull 200 次

好吧,正常情况下,到这里就友尽了,不让用就不用。但是再看看这张图:

对于有些团队来说,DockerHub 的功能不仅仅是存储镜像,更重要的是作为分发中心。每次构建完镜像,直接被推送到 DockerHub,然后其他地方再同步镜像。

如此,DockerHub 拉取镜像的限制就不得不解决了。

2. 如何测试

2.1 镜像是如何拉取的

在测试之前,我们先来了解一下镜像是如何拉取的。下图是一个镜像的结构,一个镜像对应着一个 Manifest,也就是这里的 JSON 结构。

为了更具体一点,我们开启 Docker 的实验特征,查看一下 nginx 镜像的 manifest。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
export DOCKER_CLI_EXPERIMENTAL=enabled
docker manifest inspect --verbose nginx

```json
[
	{
		"Ref": "docker.io/library/nginx:latest@sha256:99d0a53e3718cef59443558607d1e100b325d6a2b678cd2a48b05e5e22ffeb49",
		"SchemaV2Manifest": {
			"schemaVersion": 2,
			"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
			"config": {
				"mediaType": "application/vnd.docker.container.image.v1+json",
				"size": 7480,
				"digest": "sha256:bc9a0695f5712dcaaa09a5adc415a3936ccba13fc2587dfd76b1b8aeea3f221c"
			},
			"layers": [
				{
					"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
					"size": 27105484,
					"digest": "sha256:852e50cd189dfeb54d97680d9fa6bed21a6d7d18cfb56d6abfe2de9d7f173795"
				},
...
]

可以看到在 Manifest 中,记录着很多 Layer 的指纹数据,而 Layer 层才是镜像层数据,Manifest 记录的只是元数据。拉取镜像的过程,分为两步:

  1. 拉取 Manifest
  2. 根据 Manifest 中的描述,拉取 Layer 层数据。如果本地有缓存,则不用请求。

2.2 测试脚本

  1. 查看当前 Dockerhub 的拉取余额

如果是登录用户,可以在 curl 后面添加 --user 'username:password' 参数。

1
2
3
4
5
6
TOKEN=$(curl "https://auth.docker.io/token?service=registry.docker.io&scope=repository:shaowenchen/dockerhub-ratelimit:pull" | jq -r .token)
curl --head -H "Authorization: Bearer $TOKEN" https://registry-1.docker.io/v2/shaowenchen/dockerhub-ratelimit/manifests/1

ratelimit-limit: 100;w=21600
ratelimit-remaining: 99;w=21600
docker-ratelimit-source: 1.2.3.4

docker-ratelimit-source,表示受限的 IP
ratelimit-remaining,表示的是 21600 秒,6 小时内,剩下的拉取次数余额。

拉取镜像层数据才会消耗余额,因此拉取已经拉取的镜像不会消耗余额。

  1. 使用脚本耗尽配额
1
2
3
4
5
number=1 ; \
while [[ $number -le 200 ]] ; do \
    docker pull shaowenchen/dockerhub-ratelimit:$number ; \
    ((number = number + 1)) ; \
done
1
2
3
4
5
number=1 ; \
while [[ $number -le 200 ]] ; do \
    docker rmi shaowenchen/dockerhub-ratelimit:$number ; \
    ((number = number + 1)) ; \
done
  1. 配置后,继续拉取镜像

这里主要分为三类镜像:

  • 第一类是本地存在的镜像
1
docker pull shaowenchen/docker-robotframework
  • 第二类是公共镜像(本地不存在)
1
docker pull python
  • 第三类是自己编译的镜像(本地不存在)
1
docker pull shaowenchen/s2ipy

3. 配置镜像源解除拉取限制

3.1 可选镜像源及测试结果

镜像源是否有效速度地址备注
网易***https://hub-mirror.c.163.com
腾讯**https://mirror.ccs.tencentyun.com速度还行
中科大**https://ustc-edu-cn.mirror.aliyuncs.com相当于 Aliyun 的公共镜像源
阿里云**https://<your_code>.mirror.aliyuncs.com需要登录,每人一个地址
百度-https://mirror.baidubce.com不能使用
Azure-https://dockerhub.azk8s.cn仅允许 Azure 主机使用
网易-https://hub-mirror.c.163.com
Daocloud-https://f1361db2.m.daocloud.io已经缓存的本地镜像也无法拉取
七牛-https://reg-mirror.qiniu.com

总体来看,使用网易或者腾讯的镜像源是个不错的选择。

3.2 配置方法

  • 编辑 Docker 的 Daemon 文件
1
vim /etc/docker/daemon.json 
  • 添加网易的镜像源
1
2
3
4
5
6
{
  "registry-mirrors": [
    "https://hub-mirror.c.163.com"
  ],
  "live-restore": true
}
  • 重启 Docker 服务
1
systemctl daemon-reload && systemctl restart docker

微信公众号
作者
微信公众号