AI 摘要(由 ChatGPT 总结生成):
文章介绍了在国内提供镜像站和镜像加速服务被禁止的情况下,如何自建Docker镜像加速服务。全文详细描述了搭建流程,包括准备环境、安装Docker和Nginx、配置镜像仓库和Nginx反代等步骤。此外,还提供了如何通过修改Docker配置来使用新的Registry地址,并介绍了如何通过UI查看缓存的镜像。这为需要绕过官方限制的开发者提供了一种解决方案。

前言

因截止到 2024 年 06 月 07 日,国内已要求所有提供镜像站和镜像加速服务的机构停止其服务。这对国内一众开发者及安全从业者造成了相当的困扰,正好自己这几天晚上折腾了一下镜像站的部署,故简单水个文。

搭建流程

本文借鉴了另一位博主浅时光的教程,同时本文也同样适用内网自建,方便大家使用。

有的文章是使用 CloudFlare Works 搭建的,但 CloudFlare 在当下的国内环境下不知道啥时候会出幺蛾子,故本文不讨论使用 CloudFlare Works 方式部署。

操作流程

  • 拥有一台国外未被墙的主机。国内主机也可,但需会使用科学上网工具(此需自行解决,本文不提供相应教程)。
  • 一个域名,国外主机、内网自建不需备案,国内公网主机部署且对外提供则需备案。
  • 部署 Nginx,用于配置域名和 SSL 证书来反代 Registry 容器服务。
  • 部署 Docker 和 Docker Compose。

基础环境安装

  1. 添加 Docker YUM 源:
[root@localhost ~]# yum update
[root@localhost ~]# yum install -y yum-utils device-mapper-persistent-data lvm2
[root@localhost ~]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
  1. 安装 Docker :
#可以查看所有仓库中所有docker版本,并选择特定版本安装
[root@localhost ~]# yum list docker-ce --showduplicates | sort -r
[root@localhost ~]# yum install -y docker-ce
  1. 启动 Docker :
[root@localhost ~]# systemctl enable docker && systemctl start docker

部署镜像仓库代理

下文涉及浅时光博主的 GitHub 项目:Docker-Proxy

下述文件皆存放于 /var/registry-proxy 目录中,若需指定其它目录请自行创建并使用。

  1. 创建账号密码【可选】:
[root@localhost ~]# mkdir -p /var/registry-proxy &&  cd $_
[root@localhost registry-proxy]# mkdir auth && mkdir -p registry/data
[root@localhost registry-proxy]# docker run --entrypoint htpasswd httpd:2 -Bbn TEST TESTPASSWD > auth/htpasswd
  1. 添加 docker-compose.yml 文件:
  • 下述配置若需使用密码,则请将 volumes 处的 ./auth:/auth 注释取消。
  • 若内网、国内主机部署,请自行部署好科学上网代理,并将 environment 处的 HTTP_PROXYHTTPS_PROXYNO_PROXY 注释取消,并配置其正确的代理地址。
services:
  ## docker hub
  docker-hub:
    container_name: reg-docker-hub
    image: registry:latest
    restart: always
    #environment:
      #HTTP_PROXY: "http://172.17.0.1:7890"
      #HTTPS_PROXY: "http://172.17.0.1:7890"
      #NO_PROXY: "localhost,127.*,10.*,172.16.*,172.17.*,172.18.*,172.19.*,172.20.*,172.21.*,172.22.*,172.23.*,172.24.*,172.25.*,172.26.*,172.27.*,172.28.*,172.29.*,172.30.*,172.31.*,192.168.*"
    volumes:
      - ./registry/data:/var/lib/registry
      - ./docker-hub.yml:/etc/docker/registry/config.yml
      #- ./auth:/auth
    ports:
      - 51000:5000
    networks:
      - registry-net

  ## ghcr.io
  ghcr:
    container_name: reg-ghcr
    image: registry:latest
    restart: always
    environment:
      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Origin: '[http://localhost]'
      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Methods: '[HEAD,GET,OPTIONS,DELETE]'
      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Credentials: '[true]'
      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Headers: '[Authorization,Accept,Cache-Control]'
      REGISTRY_HTTP_HEADERS_Access-Control-Expose-Headers: '[Docker-Content-Digest]'
      REGISTRY_STORAGE_DELETE_ENABLED: 'true'
      #HTTP_PROXY: "http://172.17.0.1:7890"
      #HTTPS_PROXY: "http://172.17.0.1:7890"
      #NO_PROXY: "localhost,127.*,10.*,172.16.*,172.17.*,172.18.*,172.19.*,172.20.*,172.21.*,172.22.*,172.23.*,172.24.*,172.25.*,172.26.*,172.27.*,172.28.*,172.29.*,172.30.*,172.31.*,192.168.*"
    volumes:
      - ./registry/data:/var/lib/registry
      - ./ghcr.yml:/etc/docker/registry/config.yml
      #- ./auth:/auth
    ports:
      - 52000:5000
    networks:
      - registry-net

  ## gcr.io
  gcr:
    container_name: reg-gcr
    image: registry:latest
    restart: always
    environment:
      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Origin: '[http://localhost]'
      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Methods: '[HEAD,GET,OPTIONS,DELETE]'
      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Credentials: '[true]'
      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Headers: '[Authorization,Accept,Cache-Control]'
      REGISTRY_HTTP_HEADERS_Access-Control-Expose-Headers: '[Docker-Content-Digest]'
      REGISTRY_STORAGE_DELETE_ENABLED: 'true'
      #HTTP_PROXY: "http://172.17.0.1:7890"
      #HTTPS_PROXY: "http://172.17.0.1:7890"
      #NO_PROXY: "localhost,127.*,10.*,172.16.*,172.17.*,172.18.*,172.19.*,172.20.*,172.21.*,172.22.*,172.23.*,172.24.*,172.25.*,172.26.*,172.27.*,172.28.*,172.29.*,172.30.*,172.31.*,192.168.*"
    volumes:
      - ./registry/data:/var/lib/registry
      - ./gcr.yml:/etc/docker/registry/config.yml
      #- ./auth:/auth
    ports:
      - 53000:5000
    networks:
      - registry-net

  ## k8s.gcr.io
  k8s-gcr:
    container_name: reg-k8s-gcr
    image: registry:latest
    restart: always
    environment:
      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Origin: '[http://localhost]'
      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Methods: '[HEAD,GET,OPTIONS,DELETE]'
      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Credentials: '[true]'
      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Headers: '[Authorization,Accept,Cache-Control]'
      REGISTRY_HTTP_HEADERS_Access-Control-Expose-Headers: '[Docker-Content-Digest]'
      REGISTRY_STORAGE_DELETE_ENABLED: 'true'
      #HTTP_PROXY: "http://172.17.0.1:7890"
      #HTTPS_PROXY: "http://172.17.0.1:7890"
      #NO_PROXY: "localhost,127.*,10.*,172.16.*,172.17.*,172.18.*,172.19.*,172.20.*,172.21.*,172.22.*,172.23.*,172.24.*,172.25.*,172.26.*,172.27.*,172.28.*,172.29.*,172.30.*,172.31.*,192.168.*"
    volumes:
      - ./registry/data:/var/lib/registry
      - ./k8s-ghcr.yml:/etc/docker/registry/config.yml
      #- ./auth:/auth
    ports:
      - 54000:5000
    networks:
      - registry-net

  ## quay.io
  quay:
    container_name: reg-quay
    image: registry:latest
    restart: always
    environment:
      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Origin: '[http://localhost]'
      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Methods: '[HEAD,GET,OPTIONS,DELETE]'
      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Credentials: '[true]'
      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Headers: '[Authorization,Accept,Cache-Control]'
      REGISTRY_HTTP_HEADERS_Access-Control-Expose-Headers: '[Docker-Content-Digest]'
      REGISTRY_STORAGE_DELETE_ENABLED: 'true'
      #HTTP_PROXY: "http://172.17.0.1:7890"
      #HTTPS_PROXY: "http://172.17.0.1:7890"
      #NO_PROXY: "localhost,127.*,10.*,172.16.*,172.17.*,172.18.*,172.19.*,172.20.*,172.21.*,172.22.*,172.23.*,172.24.*,172.25.*,172.26.*,172.27.*,172.28.*,172.29.*,172.30.*,172.31.*,192.168.*"
    volumes:
      - ./registry/data:/var/lib/registry
      - ./quay.yml:/etc/docker/registry/config.yml
      #- ./auth:/auth
    ports:
      - 55000:5000
    networks:
      - registry-net
      
  ## UI
  registry-ui:
    container_name: registry-ui
    image: dqzboy/docker-registry-ui:latest
    restart: always
    ports:
      - 50000:8080
    environment:
      - DOCKER_REGISTRY_URL=http://reg-docker-hub:5000
      # [必须]使用 openssl rand -hex 16 生成唯一值
      - SECRET_KEY_BASE=4de431e51588e2050648ba63e3084fff
      # 启用Image TAG 的删除按钮
      - ENABLE_DELETE_IMAGES=true
      - NO_SSL_VERIFICATION=true
    networks:
      - registry-net

networks:
  registry-net:
  1. 添加 config.yml 文件:
注意:每个容器挂载对应的 config.yml ,这里名称与上面 docker-compose.yml 文件内定义的挂载名称保持一致;下面只是其中一个示例配置,其他的配置也一样,只需要更改 remoteurl 代理的地址即可。也可从 GitHub 项目内自行下载对应文件放入同目录下。
version: 0.1
log:
  fields:
    service: registry
storage:
  filesystem:
    rootdirectory: /var/lib/registry
  delete:
    enabled: true
  cache:
    blobdescriptor: inmemory   
    blobdescriptorsize: 10000
  maintenance:
    uploadpurging:
      enabled: true
      age: 168h
      interval: 24h
      dryrun: false
    readonly:
      enabled: false
http:
  addr: :5000
  headers:
    X-Content-Type-Options: [nosniff]
    Access-Control-Allow-Origin: ['*']
    Access-Control-Allow-Methods: ['HEAD', 'GET', 'OPTIONS', 'DELETE']
    Access-Control-Allow-Headers: ['Authorization', 'Accept', 'Cache-Control']
    Access-Control-Max-Age: [1728000]
    Access-Control-Allow-Credentials: [true]
    Access-Control-Expose-Headers: ['Docker-Content-Digest']
#auth:
#  htpasswd:
#    realm: basic-realm
#    path: /auth/htpasswd
health:
  storagedriver:
    enabled: true
    interval: 10s
    threshold: 3

proxy:
  remoteurl: https://registry-1.docker.io
  username: 
  password: 
  1. 启动容器服务:
[root@localhost registry-proxy]# ls
docker-compose.yaml  docker-hub.yml  gcr.yml  ghcr.yml  k8s-ghcr.yml  quay.yml  registry
[root@localhost registry-proxy]# docker compose up -d
[+] Running 7/7
 ✔ Network registry-docker_registry-net  Created                                                                                                                                   0.1s 
 ✔ Container reg-gcr                     Started                                                                                                                                   1.5s 
 ✔ Container reg-k8s-gcr                 Started                                                                                                                                   1.4s 
 ✔ Container reg-docker-hub              Started                                                                                                                                   1.4s 
 ✔ Container registry-ui                 Started                                                                                                                                   1.5s 
 ✔ Container reg-ghcr                    Started                                                                                                                                   1.5s 
 ✔ Container reg-quay                    Started                                                                                                                                   1.5s 
[root@localhost registry-proxy]#
# 检查启动容器状态
[root@localhost registry-proxy]# docker ps
  1. 配置 Nginx 反代:

此处需自备对应域名的 SSL 证书(最好申请一张通配符证书),并建议使用 acme.sh 等工具自动化管理申请部署证书。

实际配置时请将下述的 example.com 换成自己的域名,以及自行修改证书的路径和 WEB 存放日志的路径。

[root@localhost ~]# cd /etc/nginx/conf.d/
[root@localhost conf.d]# vim reverse_registry-proxy.conf
## Google Container Registry (gcr.io)
server {
        listen 80;
        listen [::]:80;
        listen 443 ssl;
        listen [::]:443 ssl;
        http2 on;
        ##  填写绑定证书的域名(下同)
        server_name gcr.example.com;

        # SSL配置,证书文件名称(填写你证书存放的路径和名称,下同)
        # RSA Cert
        ssl_certificate /xxx/fullchain.pem;
        ssl_certificate_key /xxx/privkey.pem;

        ssl_stapling on;
        ssl_stapling_verify on;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384::!MD5;
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 10m;
        ssl_session_tickets off;

        error_page 497  https://$host$request_uri;

        location / {
                proxy_pass http://localhost:53000;
                proxy_redirect off;

                proxy_ssl_server_name on;
                proxy_set_header        Host                    $http_host;
                proxy_set_header        X-Forwarded-Proto       $scheme;
                proxy_set_header        X-Real-IP               $remote_addr;
                proxy_set_header        X-Forwarded-For         $proxy_add_x_forwarded_for;

                send_timeout 600;
                proxy_connect_timeout 600;
                proxy_send_timeout 600;
                proxy_read_timeout 600;
        }

        # . files
        location ~ /\.(?!well-known) {
                deny all;
        }

        # robots.txt
        location = /robots.txt {
                default_type text/html;
                add_header Content-Type "text/plain; charset=UTF-8";
                return 200 "User-Agent: *\nDisallow: /";
        }

        access_log /xxx/gcr-access.log;
        error_log /xxx/gcr-error.log;
}

# hub mirror
server {
        listen 80;
        listen [::]:80;
        listen 443 ssl;
        listen [::]:443 ssl;
        http2 on;
        server_name hub.example.com;

        #SSL配置
        # RSA Cert
        ssl_certificate /xxx/fullchain.pem;
        ssl_certificate_key /xxx/privkey.pem;

        ssl_stapling on;
        ssl_stapling_verify on;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384::!MD5;
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 10m;
        ssl_session_tickets off;
        ssl_buffer_size 8k;

        error_page 497  https://$host$request_uri;

        location / {
                proxy_pass http://localhost:51000;
                proxy_redirect off;
                proxy_buffering off;

                proxy_ssl_server_name on;
                proxy_set_header        Host                    $http_host;
                proxy_set_header        X-Forwarded-Proto       $scheme;
                proxy_set_header        X-Real-IP               $remote_addr;
                proxy_set_header        X-Forwarded-For         $proxy_add_x_forwarded_for;
                proxy_set_header        X-Nginx-Proxy           true;

                send_timeout 600;
                proxy_connect_timeout 600;
                proxy_send_timeout 600;
                proxy_read_timeout 600;
        }

        # . files
        location ~ /\.(?!well-known) {
                deny all;
        }
        
        # robots.txt
        location = /robots.txt {
                default_type text/html;
                add_header Content-Type "text/plain; charset=UTF-8";
                return 200 "User-Agent: *\nDisallow: /";
        }

        access_log /xxx/hub-access.log;
        error_log /xxx/hub-error.log;
}

## GitHub Container Registry (ghcr.io)
server {
        listen 80;
        listen [::]:80;
        listen 443 ssl;
        listen [::]:443 ssl;
        http2 on;
        server_name ghcr.example.com;

        #SSL配置
        # RSA Cert
        ssl_certificate /xxx/fullchain.pem;
        ssl_certificate_key /xxx/privkey.pem;

        ssl_stapling on;
        ssl_stapling_verify on;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384::!MD5;
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 10m;
        ssl_session_tickets off;
        
        error_page 497  https://$host$request_uri;

        location / {
                proxy_pass http://localhost:52000;
                proxy_redirect off;
                proxy_buffering off;

                proxy_ssl_server_name on;
                proxy_set_header        Host                    $http_host;
                proxy_set_header        X-Forwarded-Proto       $scheme;
                proxy_set_header        X-Real-IP               $remote_addr;
                proxy_set_header        X-Forwarded-For         $proxy_add_x_forwarded_for;
                proxy_set_header        X-Nginx-Proxy           true;

                send_timeout 600;
                proxy_connect_timeout 600;
                proxy_send_timeout 600;
                proxy_read_timeout 600;
        }

        # . files
        location ~ /\.(?!well-known) {
                deny all;
        }

        # robots.txt
        location = /robots.txt {
                default_type text/html;
                add_header Content-Type "text/plain; charset=UTF-8";
                return 200 "User-Agent: *\nDisallow: /";
        }

        access_log /xxx/ghcr-access.log;
        error_log /xxx/ghcr-error.log;
}

## Kubernetes Container Registry (k8s.gcr.io)
server {
        listen 80;
        listen [::]:80;
        listen 443 ssl;
        listen [::]:443 ssl;
        http2 on;
        server_name k8s-gcr.example.com;

        #SSL配置
        # RSA Cert
        ssl_certificate /xxx/fullchain.pem;
        ssl_certificate_key /xxx/privkey.pem;

        ssl_stapling on;
        ssl_stapling_verify on;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384::!MD5;
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 10m;
        ssl_session_tickets off;

        error_page 497  https://$host$request_uri;

        location / {
                proxy_pass http://localhost:54000;
                proxy_redirect off;
                proxy_buffering off;

                proxy_ssl_server_name on;
                proxy_set_header        Host                    $http_host;
                proxy_set_header        X-Forwarded-Proto       $scheme;
                proxy_set_header        X-Real-IP               $remote_addr;
                proxy_set_header        X-Forwarded-For         $proxy_add_x_forwarded_for;
                proxy_set_header        X-Nginx-Proxy           true;

                send_timeout 600;
                proxy_connect_timeout 600;
                proxy_send_timeout 600;
                proxy_read_timeout 600;
        }

        # . files
        location ~ /\.(?!well-known) {
                deny all;
        }

        # robots.txt
        location = /robots.txt {
                default_type text/html;
                add_header Content-Type "text/plain; charset=UTF-8";
                return 200 "User-Agent: *\nDisallow: /";
        }

        access_log /xxx/k8s_gcr-access.log;
        error_log /xxx/k8s_gcr-error.log;
}

## Quay Container Registry (quay.io)
server {
        listen 80;
        listen [::]:80;
        listen 443 ssl;
        listen [::]:443 ssl;
        http2 on;
        server_name quay.example.com;

        #SSL配置
        # RSA Cert
        ssl_certificate /xxx/fullchain.pem;
        ssl_certificate_key /xxx/privkey.pem;

        ssl_stapling on;
        ssl_stapling_verify on;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384::!MD5;
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 10m;
        ssl_session_tickets off;

        error_page 497  https://$host$request_uri;

        location / {
                proxy_pass http://localhost:55000;
                proxy_redirect off;
                proxy_buffering off;

                proxy_ssl_server_name on;
                proxy_set_header        Host                    $http_host;
                proxy_set_header        X-Forwarded-Proto       $scheme;
                proxy_set_header        X-Real-IP               $remote_addr;
                proxy_set_header        X-Forwarded-For         $proxy_add_x_forwarded_for;
                proxy_set_header        X-Nginx-Proxy           true;

                send_timeout 600;
                proxy_connect_timeout 600;
                proxy_send_timeout 600;
                proxy_read_timeout 600;
        }

        # . files
        location ~ /\.(?!well-known) {
                deny all;
        }

        # robots.txt
        location = /robots.txt {
                default_type text/html;
                add_header Content-Type "text/plain; charset=UTF-8";
                return 200 "User-Agent: *\nDisallow: /";
        }

        access_log /xxx/quay-access.log;
        error_log /xxx/quay-error.log;
}

## Hub UI
server {
        listen 80;
        listen [::]:80;
        listen 443 ssl;
        listen [::]:443 ssl;
        http2 on;
        server_name ui.example.com;

        #SSL配置
        # RSA Cert
        ssl_certificate /xxx/fullchain.pem;
        ssl_certificate_key /xxx/privkey.pem;

        ssl_stapling on;
        ssl_stapling_verify on;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384::!MD5;
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 10m;
        ssl_session_tickets off;
        
        error_page 497  https://$host$request_uri;

        location / {
                proxy_pass http://localhost:50000;
                proxy_redirect off;
                proxy_buffering off;

                proxy_ssl_server_name on;
                proxy_set_header        Host                    $http_host;
                proxy_set_header        X-Forwarded-Proto       $scheme;
                proxy_set_header        X-Real-IP               $remote_addr;
                proxy_set_header        X-Forwarded-For         $proxy_add_x_forwarded_for;
                proxy_set_header        X-Nginx-Proxy           true;

                send_timeout 600;
                proxy_connect_timeout 600;
                proxy_send_timeout 600;
                proxy_read_timeout 600;
        }

        # . files
        location ~ /\.(?!well-known) {
                deny all;
        }

        # robots.txt
        location = /robots.txt {
                default_type text/html;
                add_header Content-Type "text/plain; charset=UTF-8";
                return 200 "User-Agent: *\nDisallow: /";
        }

        access_log /xxx/images-access.log;
        error_log /xxx/images-error.log;
}

# 重载Nginx配置
[root@localhost ~]#  nginx -t
[root@localhost ~]#  nginx -s reload
  1. 解析域名:
  • 将我们在 Nginx 配置的域名,在 DNS 服务商商进行解析,解析到部署镜像代理仓库的服务器上(若部署用于内网使用,则 DNS 服务商处可直接解析内网地址,也无需备案;也或内网的 DNS 服务器手动指定下地址的解析);
  • 通过访问 UI 地址可以查看镜像仓库缓存的镜像;
  • 通过使用对应的代理域名即可来下载之前无法下载的镜像。
  1. 上述流程完成后,即可使用自建的 Registry 地址替换官方的 Registry 地址拉取镜像,示例如下:
# docker hub Registry
## 源:nginx:latest
## 替换
docker pull hub.example.com/library/nginx:latest

# K8s Registry
## 源:gcr.io/google-containers/pause:3.1
## 替换:
docker pull gcr.example.com/google-containers/pause:3.1

镜像成功拉取后,访问 UI 页面就可以看到上面下载的镜像已经被缓存了:

image-20240612204206270.png

  1. 接下来修改 Docker 的 daemon.json 配置,配置自建的 Registry-proxy 地址,然后重启 Docker 即可,后续拉取镜像即可直接拉取:
[root@localhost registry-proxy]# vim /etc/docker/daemon.json 
{ 
  "registry-mirrors" : 
    [ 
      "https://hub.example.com"
    ] 
}
[root@localhost registry-proxy]# systemctl restart docker

镜像仓库映射

前缀替换的 Registry 参考:

源站替换为平台
docker.iohub.example.comDocker hub
gcr.iogcr.example.comGoogle Container Registry
ghcr.ioghcr.example.comGitHub Container Registry
k8s.gcr.iok8s-gcr.example.comKubernetes Container Registry
quay.ioquay.example.comQuay Container Registry

参考

自建Docker镜像加速服务:加速与优化镜像管理

Docker-Proxy

End

本文标题:自建Docker加速镜像服务

本文链接:https://www.isisy.com/1548.html

除非另有说明,本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

声明:转载请注明文章来源。

如果觉得我的文章对你有用,请随意赞赏