Docker 镜像拉不动?自建 Docker Hub 加速站 解决镜像拉取失败

本文首发于只抄博客,欢迎点击原文链接了解更多内容。

前言

众所周知,6 月份的时候,Docker Hub 的镜像就已经无法正常拉取,那会随手用 Nginx 反代了一下 Docker Hub,建了个自用的镜像站,一直用到了 9 月份,发现自建的镜像站也无法正常的拉取镜像了,看 Nginx 的日志全是 401 错误。

而拉取时候的报错则是连接不到 auth.docker.io,没想到是认证的域名也访问不到了,所以自己反代的镜像站也就无法拉取了。

于是在这里总结一下国内可以正常拉取镜像的方法,一种方法行不通了可以其他方法接着用

  • 通过 Nginx 反代 Docker Hub,现在还需要同时反代 auth.docker.io
  • 通过 Cloudflare Workers 反代
  • Docker 配置 Proxy

Nginx 反代

使用 1Panel 的还需要将 Nginx 自带配置中的 proxy_set_header Host $host; 注释掉

将下方 add_header www-authenticate 中的域名修改为自己的域名

nginx 复制代码
location /v2/ {
  proxy_pass https://registry-1.docker.io; # Docker Hub 的官方镜像仓库
  proxy_set_header Host registry-1.docker.io;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;

  # 关闭缓存
  proxy_buffering off;

  # 转发认证相关的头部
  proxy_set_header Authorization $http_authorization;
  proxy_pass_header Authorization;

  # 重写 www-authenticate 头为你的反代地址
  proxy_hide_header www-authenticate;
  add_header www-authenticate 'Bearer realm="https://mirrors.domain.com/token",service="registry.docker.io"' always;
  # always 参数确保该头部在返回 401 错误时无论什么情况下都会被添加。

  # 对 upstream 状态码检查,实现 error_page 错误重定向
  proxy_intercept_errors on;
  # error_page 指令默认只检查了第一次后端返回的状态码,开启后可以跟随多次重定向。
  recursive_error_pages on;
  # 根据状态码执行对应操作,以下为301、302、307状态码都会触发
  error_page 301 302 307 = @handle_redirect;

}
# 处理 Docker OAuth2 Token 认证请求
location /token {
  resolver 1.1.1.1 valid=600s;
  proxy_pass https://auth.docker.io; # Docker 认证服务器

  # 设置请求头,确保转发正确
  proxy_set_header Host auth.docker.io;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;

  # 传递 Authorization 头信息,获取 Token
  proxy_set_header Authorization $http_authorization;
  proxy_pass_header Authorization;

  # 禁用缓存
  proxy_buffering off;
}
location @handle_redirect {
  resolver 1.1.1.1;
  set $saved_redirect_location '$upstream_http_location';
  proxy_pass $saved_redirect_location;
}

Workers 反代

如果你没有自己的 VPS,那么可以使用 Cloudflare 提供的 Workers 进行反代,但需要注意的,反代可能会违反 Cloudflare 的 ToS 导致账号违规

点击左侧的 Worker & Pages,然后点击 Create Worker 来新建一个 Worker

名字可以随意命名,可以直接点击右下角的 Deploy 进行部署

然后编辑代码,将自带的内容全部删除后,复制 Github 的 _worker.js 中的代码并将 workers_url 修改为自己的绑定的域名

由于自带的 workers.dev 域名无法正常访问,还需要在 Settings -> Domains & Routes 绑定自己的域名

使用方法

单次使用

直接在原拉取命令前添加镜像站地址

sh 复制代码
docker pull mirrors.domain.com/whyour/qinglong:latest

全局使用

通过在配置文件中填写 registry-mirrors 后,你可以直接使用原来的拉取命令来获取镜像

创建 /etc/docker/daemon.json 文件,填入以下内容

json 复制代码
{
  "registry-mirrors": ["https://mirrors.domain.com"]
}

保存后,重启 Docker

sh 复制代码
systemctl daemon-reload
systemctl restart docker

配置 Proxy

如果你没有镜像站,也可以直接配置 Proxy,让 Docker 拉取镜像时走 Proxy 也能够正常使用

创建 /etc/systemd/system/docker.service.d 目录,并在该目录下新建 http-proxy.conf 文件填入以下内容

ini 复制代码
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:7890"
Environment="HTTPS_PROXY=http://127.0.0.1:7890"

保存后,重启 Docker

sh 复制代码
systemctl daemon-reload
systemctl restart docker

注意事项

自建的镜像站不要公开使用,Docker Hub 对于拉取频率有限制,对于匿名用户,限制设置为每个 IP 地址每 6 小时 100 次拉取。

通过以下请求获取 Token

sh 复制代码
TOKEN=$(curl "https://auth.docker.io/token?service=registry.docker.io&scope=repository:ratelimitpreview/test:pull" | jq -r .token)

再通过以下请求查看返回的 ratelimit-remaining 值就代表还剩下几次可以拉取

sh 复制代码
curl --head -H "Authorization: Bearer $TOKEN" https://registry-1.docker.io/v2/ratelimitpreview/test/manifests/latest
相关推荐
wwc_boke1 小时前
Linux查看端口占用及Windows查看端口占用
linux·运维·windows
licy__2 小时前
Docker 基础命令简介
docker·云原生·eureka
dickredone2 小时前
使用CentOS宝塔面板docker搭建EasyTier内网穿透服务
linux·网络·docker·内网穿透·宝塔面板·组网·easytier
winds~2 小时前
ubuntu中安装matplotcpp绘图
linux·运维·ubuntu
黑音3 小时前
百度网盘 服务器开小差了
运维
黑色叉腰丶大魔王3 小时前
《运维网络安全》
运维·网络·网络安全
IT-民工211103 小时前
nginx监控指标有哪些
运维·nginx
代码熬夜敲Q3 小时前
Ubuntu 扩容磁盘
运维
小安运维日记4 小时前
Linux云计算 |【第五阶段】CLOUD-DAY8
linux·运维·docker·云计算·k8s·学习方法
chian-ocean4 小时前
【linux】的爱恨情仇
linux·运维·服务器