总结目前国内加速拉取 docker 镜像的几种方法 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
bobstgrason
V2EX    Docker

总结目前国内加速拉取 docker 镜像的几种方法

  •  2
     
  •   bobstgrason 2024-06-14 00:19:21 +08:00 3782 次点击
    这是一个创建于 483 天前的主题,其中的信息可能已经有所发展或是发生改变。

    更好的阅读体验:总结目前国内加速拉取 docker 镜像的几种方法 - Sun Blog

    目前仍可用的镜像(随时可能失效)

    sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": [ "https://docker.m.daocloud.io", "https://huecker.io", "https://dockerhub.timeweb.cloud", "https://noohub.ru" ] } EOF sudo systemctl daemon-reload sudo systemctl restart docker 

    使用 Nginx

    需要有一台国外服务器, 按下面添加 Nginx 配置即可:

    server { listen 443 ssl; server_name 域名; ssl_certificate 证书地址; ssl_certificate_key 密钥地址; proxy_ssl_server_name on; # 启用 SNI ssl_session_timeout 24h; ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256'; ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; location / { 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; # 对 upstream 状态码检查,实现 error_page 错误重定向 proxy_intercept_errors on; # error_page 指令默认只检查了第一次后端返回的状态码,开启后可以跟随多次重定向。 recursive_error_pages on; # 根据状态码执行对应操作,以下为 301 、302 、307 状态码都会触发 #error_page 301 302 307 = @handle_redirect; error_page 429 = @handle_too_many_requests; } #处理重定向 location @handle_redirect { resolver 1.1.1.1; set $saved_redirect_location '$upstream_http_location'; proxy_pass $saved_redirect_location; } # 处理 429 错误 location @handle_too_many_requests { proxy_set_header Host 替换为在 CloudFlare Worker 设置的域名; # 替换为另一个服务器的地址 proxy_pass http://替换为在 CloudFlare Worker 设置的域名; proxy_set_header Host $http_host; } } 

    使用代理

    主要是设置让服务器的 docker 走代理

    首先新建目录和文件

    mkdir -p /etc/systemd/system/docker.service.d vim /etc/systemd/system/docker.service.d/http-proxy.conf 

    然后在文件中粘贴以下内容, 注意代理地址需要换成你自己服务器的内网 ip 和代理端口

    [Service] EnvirOnment="HTTP_PROXY=http://192.168.8.125:10819" EnvirOnment="HTTPS_PROXY=http://192.168.8.125:10819" EnvirOnment="NO_PROXY=your-registry.com,10.10.10.10,*.example.com" 

    重启 docker

    systemctl daemon-reload systemctl restart docker 

    检查环境变量是否生效

    systemctl show --property=Environment docker 

    使用 Cloudflare 反向代理

    登录到Cloudflare控制台, 新建 worker, 在 worker.js 文件中输入以下代码, 注意需要自行修改代码中的域名

    'use strict' const hub_host = 'registry-1.docker.io' const auth_url = 'https://auth.docker.io' const workers_url = 'https://你的域名' const workers_host = '你的域名' const home_page_url = 'https://qninq.cn/file/html/dockerproxy.html' /** @type {RequestInit} */ const PREFLIGHT_INIT = { status: 204, headers: new Headers({ 'access-control-allow-origin': '*', 'access-control-allow-methods': 'GET,POST,PUT,PATCH,TRACE,DELETE,HEAD,OPTIONS', 'access-control-max-age': '1728000', }), } /** * @param {any} body * @param {number} status * @param {Object<string, string>} headers */ function makeRes(body, status = 200, headers = {}) { headers['access-control-allow-origin'] = '*' return new Response(body, {status, headers}) } /** * @param {string} urlStr */ function newUrl(urlStr) { try { return new URL(urlStr) } catch (err) { return null } } addEventListener('fetch', e => { const ret = fetchHandler(e) .catch(err => makeRes('cfworker error:\n' + err.stack, 502)) e.respondWith(ret) }) /** * @param {FetchEvent} e */ async function fetchHandler(e) { const getReqHeader = (key) => e.request.headers.get(key); let url = new URL(e.request.url); if (url.pathname === '/') { // Fetch and return the home page HTML content with replacement let respOnse= await fetch(home_page_url); let text = await response.text(); text = text.replace(/{workers_host}/g, workers_host); return new Response(text, { status: response.status, headers: response.headers }); } if (url.pathname === '/token') { let token_parameter = { headers: { 'Host': 'auth.docker.io', 'User-Agent': getReqHeader("User-Agent"), 'Accept': getReqHeader("Accept"), 'Accept-Language': getReqHeader("Accept-Language"), 'Accept-Encoding': getReqHeader("Accept-Encoding"), 'Connection': 'keep-alive', 'Cache-Control': 'max-age=0' } }; let token_url = auth_url + url.pathname + url.search return fetch(new Request(token_url, e.request), token_parameter) } url.hostname = hub_host; let parameter = { headers: { 'Host': hub_host, 'User-Agent': getReqHeader("User-Agent"), 'Accept': getReqHeader("Accept"), 'Accept-Language': getReqHeader("Accept-Language"), 'Accept-Encoding': getReqHeader("Accept-Encoding"), 'Connection': 'keep-alive', 'Cache-Control': 'max-age=0' }, cacheTtl: 3600 }; if (e.request.headers.has("Authorization")) { parameter.headers.Authorization = getReqHeader("Authorization"); } let original_respOnse= await fetch(new Request(url, e.request), parameter) let original_response_clOne= original_response.clone(); let original_text = original_response_clone.body; let response_headers = original_response.headers; let new_response_headers = new Headers(response_headers); let status = original_response.status; if (new_response_headers.get("Www-Authenticate")) { let auth = new_response_headers.get("Www-Authenticate"); let re = new RegExp(auth_url, 'g'); new_response_headers.set("Www-Authenticate", response_headers.get("Www-Authenticate").replace(re, workers_url)); } if (new_response_headers.get("Location")) { return httpHandler(e.request, new_response_headers.get("Location")) } let respOnse= new Response(original_text, { status, headers: new_response_headers }) return response; } /** * @param {Request} req * @param {string} pathname */ function httpHandler(req, pathname) { const reqHdrRaw = req.headers // preflight if (req.method === 'OPTIONS' && reqHdrRaw.has('access-control-request-haders') ) { return new Response(null, PREFLIGHT_INIT) } let rawLen = '' const reqHdrNew = new Headers(reqHdrRaw) const refer = reqHdrNew.get('referer') let urlStr = pathname const urlObj = newUrl(urlStr) /** @type {RequestInit} */ const reqInit = { method: req.method, headers: reqHdrNew, redirect: 'follow', body: req.body } return proxy(urlObj, reqInit, rawLen, 0) } /** * * @param {URL} urlObj * @param {RequestInit} reqInit */ async function proxy(urlObj, reqInit, rawLen) { const res = await fetch(urlObj.href, reqInit) const resHdrOld = res.headers const resHdrNew = new Headers(resHdrOld) // verify if (rawLen) { const newLen = resHdrOld.get('content-length') || '' const badLen = (rawLen !== newLen) if (badLen) { return makeRes(res.body, 400, { '--error': `bad len: ${newLen}, except: ${rawLen}`, 'access-control-expose-headers': '--error', }) } } const status = res.status resHdrNew.set('access-control-expose-headers', '*') resHdrNew.set('access-control-allow-origin', '*') resHdrNew.set('Cache-Control', 'max-age=1500') resHdrNew.delete('content-security-policy') resHdrNew.delete('content-security-policy-report-only') resHdrNew.delete('clear-site-data') return new Response(res.body, { status, headers: resHdrNew }) } 

    部署完成后,点击设置->触发器->添加自定义域,绑定自己的域名即可

    undefined

    使用 Github Action + 阿里云私有仓库

    使用 Github Action 将国外的 Docker 镜像转存到阿里云私有仓库,供国内服务器使用

    项目地址:tech-shrimp/docker_image_pusher: 使用 Github Action 将国外的 Docker 镜像转存到阿里云私有仓库,供国内服务器使用,免费易用

    项目的文档写的很详细,不再赘述

    参考

    自建 Docker Hub 加速镜像 (lty520.faith)

    tech-shrimp/docker_image_pusher: 使用 Github Action 将国外的 Docker 镜像转存到阿里云私有仓库,供国内服务器使用,免费易用

    都在蹭 CF 搭建 dockerhub 镜像代理,基于论坛看到的一个代码糊了个前端 - 软件分享 - LINUX DO

    5 条回复    2024-09-24 17:14:04 +08:00
    BrookO
        1
    BrookO  
       2024-06-14 09:54:31 +08:00
    使用 Nginx 这种方式会不会导致 ip 和域名被封
    kero991
        2
    kero991  
       2024-06-14 16:19:04 +08:00
    https://do.nark.eu.org
    在另一个贴看到的
    brucewsl
        3
    brucewsl  
       2024-06-14 16:26:46 +08:00
    Ethan9527
        4
    Ethan9527  
       2024-06-14 17:50:51 +08:00
    sn0wdr1am
        5
    sn0wdr1am  
       2024-09-24 17:14:04 +08:00
    比较全,还可以
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2363 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 23ms UTC 15:47 PVG 23:47 LAX 08:47 JFK 11:47
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86