互联网技术 / 互联网资讯 · 2023年12月6日

解决镜像下载问题的终极方法

前言

在使用 Docker 和 Kubernetes 时,访问 gcR.io 和 quay.io 镜像仓库常常面临困难。由于众所周知的原因,这些仓库在中国无法直接访问。虽然 gcR.azk8s.cn 之前是 gcR.io 的代理站点,允许访问其镜像,但如今该服务已经仅限于 Azure 中国的 IP,无法对外提供服务。其他国内镜像加速方案大多采用定时同步的方式来缓存镜像,这种方法存在延迟,无法保证及时更新。我尝试过 UStc 和七牛云等镜像加速器,但效果不佳,很多镜像都无法找到。

为了能够顺利访问 gcR.io 等镜像仓库,我们需要在墙外搭建一个类似于 gcR.azk8s.cn 的镜像代理站点。利用 Docker 的开源项目 Registry,可以实现这个目标。Registry 不仅可以作为本地私有镜像仓库,还能作为上游镜像仓库的缓存,称为 pull through cache。

接下来,让我们先感受一下速度:

解决镜像下载问题的终极方法

解决镜像下载问题的终极方法

解决镜像下载问题的终极方法

1. 前提条件

需要一台能够访问 gcR.io 的服务器。

一个域名及相关的 SSL 证书(Docker 拉取镜像时需要验证域名证书),通常使用 Let’s Encrypt 就可以满足需求。

2. 核心思路

Registry 可以通过设置 Remote_URL 参数,将其配置为远程仓库的缓存。当你通过这个私有仓库地址拉取镜像时,Registry 会首先将镜像缓存到本地,然后再提供给客户端。我们只需部署一个私有 Registry,并将 Remote_URL 设置为需要加速的镜像仓库地址即可。

3. 定制 Registry

为了支持缓存 docker.io、gcR.io、k8s.gcR.io、quay.io 和 ghcR.io 等常见公共镜像仓库,我们需要定制 Registry 的配置文件,Dockerfile 如下:

FROM Registry:2.6 LABEL MAIntAIneR=”Registry-Proxy Docker MAIntAIneRs” ENV ProXY_Remote_URL DELETE_ENABLED COPY entrypoint.sh /entrypoint.sh

其中 entrypoint.sh 用于将环境变量传入配置文件:

entrypoint.sh

#!/BIn/sh set -e CONFIG_YML=/etc/docker/Registry/config.yml if [-n “$ProXY_Remote_URL” -a `gRep -c “$ProXY_Remote_URL” $CONFIG_YML` -eq 0 ]; then echo “Proxy:” >> $CONFIG_YML echo “& Remote_URL: $ProXY_Remote_URL” >> $CONFIG_YML echo “& Username: $ProXY_UserNAME” >> $CONFIG_YML echo “& Password: $ProXY_PASSWORD” >> $CONFIG_YML echo “—— Enabled Proxy to Remote: $ProXY_Remote_URL ——” elif [$DELETE_ENABLED = true -a `gRep -c “delete:” $CONFIG_YML` -eq 0 ]; then sed -i ””/RootDirectory/a delete:”” $CONFIG_YML sed -i ””/delete/a enabled: true”” $CONFIG_YML echo “—— Enabled local storage delete —–” fi case

4. 启动缓存服务

构建好 Docker 镜像后,可以直接启动服务。

解决镜像下载问题的终极方法

既然购买了两台服务器,自然要组建一个 k3s 集群。从主机名就可以看出我这台是用来干什么的。其中 2C 4G 作为 Master 节点,1C 2G 作为 Node 节点。

以 docker.io 为例,创建资源清单:

dockerhub.yml

apiVersion: apps/v1 kind: Deployment metadata: name: dockerhub labels: app: dockerhub spec: replicas: 1 selector: matchLabels: app: dockerhub template: metadata: labels: app: dockerhub spec: affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: – podAffinityTerm: labelSelector: matchExpressions: – key: app operator: In values: – dockerhub topologyKey: kubernetes.io/hostname weight: 1 dnsPolicy: None dnsConfig: nameservers: – 8.8.8.8 – 8.8.4.4 containers: – name: dockerhub image: yangchuansheng/Registry-Proxy:latest env: – name: ProXY_Remote_URL value: https://Registry-1.docker.io – name: ProXY_UserNAME value: yangchuansheng – name: ProXY_password value: ******** ports: – containerPort: 5000 protocol: TCP volumeMounts: – mountPath: /etc/localtime name: localtime – mountPath: /var/lib/Registry name: Registry — apiVersion: v1 kind: Service metadata: name: dockerhub labels: app: dockerhub spec: selector: app: dockerhub ports: – protocol: TCP name: http port: 5000 targetPort: 5000

使用资源清单创建相应的服务。