由于众所周知的原因,Docker Hub 已经无法访问和进行镜像拉取操作,本文作为备忘录,记录一个不使用外部镜像服务器解锁 Docker Hub 的镜像拉取功能的配置。
本文假设读者熟悉常见操作系统的软件安装方法(apt、yum、apk、brew 等)、Nginx 基本配置方法和基本的 Docker 命令
不使用镜像站点的原因很多,例如镜像站点可能记录你 pull 镜像的历史记录。
需要准备的东西#
- Nginx
- ndk_http_module
- ngx_http_lua_module
- https://www.nslookup.io/ (用于获取未被污染的 IP 地址)
Nginx 配置#
worker_processes auto;
load_module modules/ndk_http_module.so;
load_module modules/ngx_http_lua_module.so;
events {
worker_connections 1024;
}
http {
upstream production_servers {
server 104.16.99.215:443;
server 104.16.97.215:443;
server 104.16.100.215:443;
server 104.16.98.215:443;
server 104.16.101.215:443;
}
upstream registry_servers {
server 3.94.224.37:443;
server 44.208.254.194:443;
server 98.85.153.80:443;
}
server {
listen 127.0.0.1:9999;
listen [::1]:9999;
server_name localhost;
location / {
proxy_pass https://registry_servers;
proxy_set_header Host registry-1.docker.io;
proxy_buffering off;
proxy_set_header Authorization $http_authorization;
proxy_pass_header Authorization;
proxy_intercept_errors on;
recursive_error_pages on;
error_page 301 302 307 = @handle_redirect;
proxy_ssl_verify off;
header_filter_by_lua_block {
local auth = ngx.header["www-authenticate"]
if auth then
auth = string.gsub(auth,"https://auth.docker.io", "http://localhost:9999")
ngx.header["www-authenticate"] = auth
end
}
}
location /token {
proxy_pass https://registry_servers;
proxy_set_header Host auth.docker.io;
proxy_ssl_verify off;
}
location @handle_redirect {
set $saved_redirect_location '$upstream_http_location';
if ($saved_redirect_location ~ ^(?<protocol>\w+)://(?<domain>[^/]+)(?<path>(/[^?]*)?)(?:\?(?<params>.*))?$) {
proxy_pass $protocol://production_servers$path?$params;
}
proxy_set_header Host production.cloudflare.docker.com;
proxy_ssl_verify off;
}
}
}
原理#
- SNI 拔除
- Docker 内置的镜像服务器包含 localhost
使用示例#
注意 dockerhub 默认镜像组织名写为 library,其余的镜像只需在前面加上
localhost:9999/ 即可