Docker 配置镜像加速

170次阅读
没有评论

共计 7118 个字符,预计需要花费 18 分钟才能阅读完成。

背景

众所周知,从国内拉取 docker 镜像时常会遇到网络不畅无法拉取的问题。

Docker 配置镜像加速

下文会介绍几种镜像加速的方案。

实践

前提:需要有一台能够正常链接外网访问镜像仓库的服务器。

一、基于 Registry 部署加速服务

Docker Registry 是一个Dodcker 官方发行,用于存储和分发 Docker 镜像的服务。它直接提供了 镜像加速​ 的功能。

只需要启动一个简单的容器,配合 Nginx 即可实现镜像加速。本文仅以 docker.io 为例,若还需要代理其他仓库域名,流程完全一致。

PS. Docker 强制要求HTTPS

参考链接:

github.com/dqzboy/Docker-Proxy?tab=readme-ov-file

www.rclogs.com/2024/06/docker-registry-build#%E4%B8%89%E3%80%81%…

github.com/brighill/registry-mirror

Docker 配置镜像加速

部署 Registry

# 创建工作目录
mkdir /usr/local/registry && cd /usr/local/registry

# 创建配置文件
# vim docker-compose.yml
version: '3'
services:
  ## docker hub
  dockerhub:
    container_name: reg-docker-hub
    image: registry:latest
    restart: always
    environment:
       REGISTRY_PROXY_REMOTEURL: https://registry-1.docker.io
    volumes:
      - ./data:/var/lib/registry
    ports:
      - 50001:5000
    networks:
      - registry-net

networks:
  registry-net:

# 启动
docker-compose up -d

Nginx 反向代理

# 增加子配置文件
# vim /etc/nginx/conf/conf.d/***.opshub.cn.conf 
upstream reg-docker-hub {
  server 8.*.*.*:50001;
}

server {
  listen 80;
  server_name ***.opshub.cn;
  return 301 https://$server_name$request_uri;
}

server {
  listen 443 ssl http2;
  server_name ***.opshub.cn;

  ssl_certificate     /root/.acme.sh/*.opshub.cn_ecc/fullchain.cer;
  ssl_certificate_key /root/.acme.sh/*.opshub.cn_ecc/*.opshub.cn.key;
  ssl_session_timeout 5m;
  ssl_protocols TLSV1 TLSv1.1 TLSv1.2;
  ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
  ssl_prefer_server_ciphers on;

  # 为了防止被滥用,配置仅允许Get请求,即拉取镜像
  location / {
    limit_except GET {
      deny all;
    }

    proxy_set_header Host $http_host;
    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 https;
    proxy_redirect http:// https://;
    proxy_pass http://reg-docker-hub;
  }
}

# 重载nginx
ngint -t
nginx -s reload

客户端拉取镜像

先开启 Docker 的 debug模式:

# vim /etc/docker/daemon.json
{
  "debug": true
}

# systemctl restart docker

当客户端不配置代理时,表现如下:connect: connection timed out

Docker 配置镜像加速

查看日志可以看到详细输出:

# journalctl -u docker.service
Jan 14 17:27:20 kae-haiwaiyun-testnode dockerd[19181]: time="2025-01-14T17:27:20.513216547+08:00" level=debug msg="Calling HEAD /_ping"
Jan 14 17:27:20 kae-haiwaiyun-testnode dockerd[19181]: time="2025-01-14T17:27:20.513908792+08:00" level=debug msg="Calling POST /v1.44/images/create?fromImage=nginx&tag=latest"
Jan 14 17:27:20 kae-haiwaiyun-testnode dockerd[19181]: time="2025-01-14T17:27:20.524786710+08:00" level=debug msg="Trying to pull nginx from https://registry-1.docker.io"
Jan 14 17:27:20 kae-haiwaiyun-testnode dockerd[19181]: time="2025-01-14T17:27:20.524808476+08:00" level=debug msg="Trying to pull nginx from https://registry-1.docker.io"
Jan 14 17:27:23 kae-haiwaiyun-testnode dockerd[19181]: time="2025-01-14T17:27:23.584454048+08:00" level=warning msg="Error getting v2 registry: Get \"https://registry-1.docker.io/v2/\": dial tcp 208.43.170.231:
Jan 14 17:27:23 kae-haiwaiyun-testnode dockerd[19181]: time="2025-01-14T17:27:23.584490264+08:00" level=info msg="Attempting next endpoint for pull after error: Get \"https://registry-1.docker.io/v2/\": dial tc
Jan 14 17:27:23 kae-haiwaiyun-testnode dockerd[19181]: time="2025-01-14T17:27:23.586497175+08:00" level=error msg="Handler for POST /v1.44/images/create returned error: Get \"https://registry-1.docker.io/v2/\":
Jan 14 17:27:30 kae-haiwaiyun-testnode dockerd[19181]: time="2025-01-14T17:27:30.006232489+08:00" level=debug msg="Calling GET /v1.41/containers/json?limit=0"
Jan 14 17:28:00 kae-haiwaiyun-testnode dockerd[19181]: time="2025-01-14T17:28:00.005719245+08:00" level=debug msg="Calling GET /v1.41/containers/json?limit=0"

可以通过两种方式实现加速下载:

1、显式指定加速域名

下表是常用的镜像仓库域名

源站 替换为 平台
docker.io hub.your_domain_name docker hub
gcr.io gcr.your_domain_name Google Container Registry
ghcr.io ghcr.your_domain_name GitHub Container Registry
k8s.gcr.io k8s-gcr.your_domain_name Kubernetes Container Registry
registry.k8s.io k8s.your_domain_name Kubernetes’s container image registry
quay.io quay.your_domain_name Quay Container Registry
mcr.microsoft.com mcr.your_domain_name Microsoft Container Registry
docker.elastic.co elastic.your_domain_name Elastic Stack
nvcr.io nvcr.your_domain_name NVIDIA Container Registry
# docker pull ***.opshub.cn/library/nginx
Using default tag: latest
latest: Pulling from library/nginx
af302e5c37e9: Pull complete 
207b812743af: Pull complete 
841e383b441e: Pull complete 
0256c04a8d84: Pull complete 
38e992d287c5: Pull complete 
9e9aab598f58: Pull complete 
4de87b37f4ad: Pull complete 
Digest: sha256:0e65e7b19ac0abab5c911b175ca20040c98200337337cbb366af24ab597927ea
Status: Downloaded newer image for ***.opshub.cn/library/nginx:latest
***.opshub.cn/library/nginx:latest

执行 journalctl -u docker.service | grep pull​,可以看到此时直接由代理域名执行了镜像数据下载。

Docker 配置镜像加速

2、修改 docker 配置启用加速域名

daemon.json​ 支持配置仓库域名。域名可以使用列表方式写入多个,docker 会尝试由上至下遍历仓库,直到能够查询到镜像为止。

# 修改配置
# vim /etc/docker/daemon.json 
{
  "registry-mirrors": [
    "https://***.opshub.cn"
  ],
  "debug": true
}

# 重启 docker
systemctl restart docker

# 校验配置是否生效
# docker info|grep -A 1 Registry
 Registry Mirrors:
  https://***.opshub.cn/

当配置生效后,无需显式指定镜像域名,可以直接 pull 镜像。

# 先删除已经下载完毕的nginx镜像
docker rmi 9bea9f2796e2

# 下载镜像
# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
af302e5c37e9: Pull complete 
207b812743af: Pull complete 
841e383b441e: Pull complete 
0256c04a8d84: Pull complete 
38e992d287c5: Pull complete 
9e9aab598f58: Pull complete 
4de87b37f4ad: Pull complete 
Digest: sha256:0e65e7b19ac0abab5c911b175ca20040c98200337337cbb366af24ab597927ea
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest

从输出可以看到,以后一行中域名仍然是 docker.io,而不是代理域名。

执行 journalctl -u docker.service |grep "Fetching manifest from remote"​ 查看日志:可以看到从 docker.io 获取了清单

Docker 配置镜像加速

执行 journalctl -u docker.service | grep pull​查看日志:可以看到从 代理域名 下载了镜像

Docker 配置镜像加速

原因如下:

  1. 镜像源的作用
    registry-mirrors​ 配置的作用是加速docker.io​ 拉取镜像,而不是完全替换 docker.io​。因此:

    • Docker 仍然会与 docker.io​ 通信,获取镜像的元数据。
    • 实际的镜像层数据(blobs)会通过配置的镜像源(如 ***.opshub.cn​)下载。
  2. 日志中的关键信息
    • Trying to pull nginx from https://***.opshub.cn/`​:Docker 尝试通过***.opshub.cn`​ 拉取镜像。
    • Pulling ref from V2 registry: nginx:latest​:Docker 从 docker.io​ 获取镜像的元数据。
    • pulling blob "sha256:..."​:Docker 通过 ***.opshub.cn​ 下载实际的镜像层数据。
  3. 为什么仍然显示 docker.io
    即使配置了镜像源,Docker 仍然会显示从 docker.io​ 拉取镜像,因为:

    • 镜像的元数据(如 manifest 和 layer 信息)仍然从 docker.io​ 获取。
    • 镜像层数据(blobs)通过镜像源下载,但 Docker 的输出默认显示的是元数据的来源。

二、使用 socks & http 代理

可参考文章:使用 socks5 代理网络流量 进行代理配置。

在客户端中,修改 docker 配置文件:

# vim /etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=socks5://192.168.2.10:2080"
Environment="HTTPS_PROXY=socks5://192.168.2.10:2080"

# 重启服务
systemctl daemon-reload
systemctl restart docker

使用这种方式,会将 docker 所有流量均转发到代理服务器。影响面大。

如果 docker 是作为 kubernetes 的运行时,不建议这样做,会引发集群网络异常。

好处是客户端在pull镜像时,无需进行任何域名配置。

总结

文中的3种方式各有优劣,自行根据场景选择方案。

AI总结如下:

问题:
分析三种docker镜像代理方式的优劣:
1、通过部署 Registry 服务端,在客户端显式指定镜像加速域名
2、通过部署 Registry 服务端,在客户端的 /etc/docker/daemon.json 下配置代理域名
3、通过部署 socks代理,在客户端的 /etc/systemd/system/docker.service.d/http-proxy.conf 配置socks代理

回答:
我来详细分析这三种docker镜像代理方式的优缺点:

1. 通过显式指定镜像加速域名
优点:
- 配置简单,只需在pull/push时指定域名
- 灵活性高,可以针对不同镜像源使用不同的加速域名
- 不影响其他Docker操作
- 便于临时使用或测试

缺点:
- 需要每次手动指定域名,使用不便
- 容易遗漏,特别是在自动化脚本中
- 团队协作时需要所有人都记住并使用正确的域名

2. 通过daemon.json配置代理域名
优点:
- 配置一次即可全局生效
- 对用户透明,无需改变使用习惯
- 便于统一管理和维护
- 适合团队使用
- 自动化友好

缺点:
- 需要重启docker服务才能生效
- 配置相对复杂,需要注意json格式
- 可能影响所有的镜像拉取操作
- 故障排查相对困难

3. 通过socks代理配置
优点:
- 支持更广泛的网络代理场景
- 可以同时作用于其他网络服务
- 对网络层面有更细粒度的控制
- 可以处理更复杂的网络环境

缺点:
- 配置最为复杂
- 需要额外维护代理服务器
- 可能影响系统整体网络性能
- 安全风险较大,需要额外的安全措施
- 故障排查最困难

使用建议:

1. 对于个人开发环境:
- 建议使用方式1或2,简单直接

2. 对于企业生产环境:
- 如果主要解决镜像加速问题,推荐使用方式2
- 如果有复杂的网络需求,考虑使用方式3

3. 对于临时使用:
- 推荐使用方式1,无需修改系统配置

4. 对于大规模部署:
- 建议使用方式2,便于统一管理和自动化部署

最佳实践:
1. 优先考虑使用daemon.json配置(方式2),这是最标准的做法
2. 如果遇到特殊情况需要使用其他镜像源,可以临时使用方式1
3. 只有在确实需要处理复杂网络环境时,才考虑使用方式3

需要注意的是,无论选择哪种方式,都应该:
- 做好配置文档
- 进行充分测试
- 建立监控机制
- 准备回退方案
- 定期检查和更新配置

引用链接

正文完
 
pengyinwei
版权声明:本站原创文章,由 pengyinwei 2025-01-14发表,共计7118字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处:https://www.opshub.cn
评论(没有评论)