赞
踩
更多奇技淫巧欢迎订阅博客:https://fuckcloudnative.io
前言
很早很早以前,我们都使用裸机部署应用,部署应用无非以下几步:
安装操作系统
安装运行环境(PHP,NodeJS,Ruby, etc)
安装/复制程序
尝试运行程序
报错,修环境问题
继续报错,修开发人员
开发人员提交一个很脏的 Hack,应用终于跑起来了
直到容器化的出现,开发和运维开发将整个程序和运行环境放在一个个 Docker Image 和 docker-compose.yml
中,启动一个程序已经慢慢缩减成了一行 docker run
或者 docker-compose up -d
,绿色无害,迁移方便,使用起来让人上瘾,想不断地使用 Docker,并不断将 Docker 融入自己的 Workflow 中,然而,Docker 用的多了,就会看到以下情况:
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
打开这个页面,你就会知道,从 2020-11-02 开始,官方的 Docker Hub 开始对 pull 请求加上了限制,限制为匿名用户(未登录),每分钟只能拉 100 次 image,登录的免费用户每分钟拉 200 次 镜像:
The rate limits of 100 container image requests per six hours for anonymous usage, and 200 container image requests per six hours for free Docker accounts are now in effect.
对于登录而言,限制的是用户,对于未登录的用户而言,限制的是 IP。
Docker 要怡烂钱我可以理解, 但是 docker hub 上面 ubuntu:latest 这样的基础镜像都给我整一个 rate-limit 我是真的没想到。不知道今天起有多少人的 CI/CD 会因为这个挂掉。
——https://twitter.com/IceCode8964XI/status/1328395263606628352
这怎么行?
由于限制的是 pull 请求,为了摆脱这种限制,我们首先得了解 docker pull
背后到底做了啥,然后推测限制的位置并绕过。
我们虽然日常访问的是 https://hub.docker.com
,但是我们在 https://github.com/docker/distribution/blob/master/reference/normalize.go#L13 中可以看到实际 docker
使用的地址是一个硬编码的 docker.io
- var (
- legacyDefaultDomain = "index.docker.io"
- defaultDomain = "docker.io"
- officialRepoName = "library"
- defaultTag = "latest"
- )
在 Docker 的 API 文档:https://docs.docker.com/registry/spec/api/#pulling-an-image 中,我们知道:
An “image” is a combination of a JSON manifest and individual layer files. The process of pulling an image centers around retrieving these two components.
一个 docker pull
指令会从拉两部分,一部分是 manifest,一部分是 layer,前者指定了一个 image 相关的信息和 layer 的信息(一个 JSON 文件),后者就是一些大文件(layer),从我们内部统计的情况来看,后者普遍使用的是 https://production.cloudflare.docker.com/
,这部分应该是不会受到限制的,所以猜测限制的地方是前者 manifest 的部分的请求,从文档 https://docs.docker.com/docker-hub/download-rate-limit/ 中我们也可以知道:
A pull request is defined as up to two GET requests on registry manifest URLs (/v2//manifests/).
故而证实了我们猜测,Docker Hub 是在拉 manifest 的过程中进行限制的。
那么 manifest 是从哪儿拉的?
由于没有地方记录了 docker pull
的时候到底是从哪儿拉的地址,需要 MITM 一下:
- Flows
- GET https://registry-1.docker.io/v2/
- ← 401 application/json 87b 213ms
- GET https://auth.docker.io/token?account=youraccount&scope=repository%3Alibrary%2Fal
- pine%3Apull&service=registry.docker.io
- ← 200 application/json 4.18k 245ms
- >> GET https://registry-1.docker.io/v2/library/alpine/manifests/latest
- ← 200 application/vnd.docker.distribution.manifest.list.v2+json 1.6k 294ms
- GET https://registry-1.docker.io/v2/library/alpine/manifests/sha256:57334c50959f26ce
- 1ee025d08f136c2292c128f84e7b229d1b0da5dac89e9866
- ← 200 application/vnd.docker.distribution.manifest.v2+json 528b 326ms
- GET https://registry-1.docker.io/v2/library/alpine/blobs/sha256:b7b28af77ffec6054d13
- 378df4fdf02725830086c7444d9c278af25312aa39b9
- ← 307 text/html 242b 288ms
- GET https://registry-1.docker.io/v2/library/alpine/blobs/sha256:0503825856099e6adb39
- c8297af09547f69684b7016b7f3680ed801aa310baaa
- ← 307 text/html 242b 322ms
- GET https://production.cloudflare.docker.com/registry-v2/docker/registry/v2/blobs/sh
- a256/b7/b7b28af77ffec6054d13378df4fdf02725830086c7444d9c278af25312aa39b9/data?…
- ← 200 application/octet-stream 1.48k 191ms
- GET https://production.cloudflare.docker.com/registry-v2/docker/registry/v2/blobs/sh
- a256/05/0503825856099e6adb39c8297af09547f69684b7016b7f3680ed801aa310baaa/data?…
- ← 200 application/octet-stream 2.66m 207ms
- ⇩ [27/32] [*:8080]
我们会发现 https://registry-1.docker.io/v2/
这个地址,通过手动改 Host + 调路由的方式并重新 pull 发现可以成功之后得到了验证。
接下来就是给这个地址设置用不同的 IP 来请求这个地址即可绕开限制,比如..用 Tor。
刷 Docker Hub 流量固然很快乐,但是我们的主要目的还是保护内部 CI 不挂,且提升 pull 的速度,所以这个时候配置一个 pull-through cache[1] 才是一个比较合理的解决方式,嗷对了,如果你和我一样使用了自己的 cache 的话,记得改外部 DNS 设置,而不是容器内的 /etc/hosts
,不然容器内的程序还是会通过 Host 的 DNS 去查询 registry-1.docker.io
的 IP 并直连,让你继续看到 toomanyrequests。
[1]
配置一个 pull-through cache: https://github.com/n0vad3v/dockerfiles/tree/master/registry-pull-through-cache
原文链接:https://nova.moe/bypass-docker-hub-429/
你可能还喜欢
点击下方图片即可阅读
云原生是一种信仰 ????
扫码关注公众号
后台回复◉k8s◉获取史上最方便快捷的 Kubernetes 高可用部署工具,只需一条命令,连 ssh 都不需要!
点击 "阅读原文" 获取更好的阅读体验!
❤️给个「在看」,是对我最大的支持❤️
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。