折腾日记 | 国内可用镜像仓库代理

起因

今日购入一台阿里云 ECS,在折腾的时候发现部分国外的镜像拉取速度过慢,并且阿里云 ACR 镜像加速下载的镜像都不是最新的,寻找了些一些解决方案和国内可用的镜像代理服务,在这里做个记录。由于不可抗力,多数镜像代理服务平台已经下线代理,于 2024/10/12 对此文进行更新,下表为收集的加速器列表,不定时更新,有失效可能。目前可用的镜像站已知有企业维护的仅 DaoCloud 镜像站,由于我的机器是阿里云 ECS 因此我使用的阿里云提供的镜像仓库方案,你也可以尝试使用 Cloudflare Wokers 自建镜像加速器。

镜像加速器列表

供应商 加速器地址 备注
DaoCloud https://docker.m.daocloud.io 仅限境内机器使用,白名单模式,不在名单的镜像需要提交申请。
1plane https://docker.1panel.live
https://dockerproxy.1panel.live
https://proxy.1panel.live
仅限境内机器使用,可能会有流量限制。
💡
我搜索到是很多人在使用 Cloudflare Wokers 自建镜像代理,有兴趣的可以自行搜索相关教程。

目前提供镜像加速服务的供应商较少,由于我使用的是阿里云 ECS,因此为了方便,我通过 GitHub Action 定时同步镜像到阿里云 ACR 来使用 Docker,本文的目的就是想跟大家分享一下我在同步镜像的经验,希望可以给大家提供一个参考。

使用 GitHub Action 定时同步镜像到阿里云 ACR

本文主要有以下几个部分:

  • 如何在 ACR 中创建镜像仓库命名空间和仓库
  • 如何获取 ACR 的授权信息
  • 如何配置 GitHub Actions 同步镜像

事不宜迟,那让我们马上开始吧!

Step 1. 在 ACR 中创建镜像仓库命名空间和仓库

搭建第一步是在阿里云容器镜像服务(Aliyun Container Registry)中创建命名空间(namespace)和镜像仓库(repository)。在开始之前,我想先解释一下这个镜像服务地址、命名空间、以及仓库名字的含义。因为明白它们的含义有助于理解下文,理解现在做到哪一步。在下载 Docker image 的时候,一个仓库的全称可能长成下面这样:

registry.cn-shenzhen.aliyuncs.com/qinyangwang/nginx

也就是:

${REGISTRY}/${NAMESPACE}/${REPOSITORY}

具体来说,

REGISTRY 是阿里云容器镜像服务地址,其中的 cn-shenzhen 是区域的地址,你只需要替换到离你最近的区域即可,可用的区域列表请参考地域和可用区列表中的地域ID。

  • NAMESPACE 是镜像的命名空间,管理该命名空间下的仓库集合,包括仓库权限和仓库属性,这里你随意设置一个自己记得住的字符串即可。
  • REPOSITORY 是镜像仓库的名称,尽量输入易于辨别的字符串,比如我同步 vaultwarden/server 镜像到 ACR 就是 registry.cn-shenzhen.aliyuncs.com/qinyangwang/vaultwarden。

了解了镜像名称之后,我们开始创建镜像仓库实例:

1.登录容器镜像服务控制台

💡
若您是首次登录容器镜像服务控制台,您需要设置Registry登录密码,以便镜像的上传和下载。

2.在顶部菜单栏,选择所需地域。

3.在左侧导航栏,选择实例列表

4.在实例列表页面,单击个人版区域任意位置。

5.在提示对话框单击创建个人版

6.在个人版实例管理页面选择仓库管理 > 命名空间

7.在命名空间页面单击创建命名空间

8.在创建命名空间对话框中设置命名空间名称,单击确定

Step 2. 获取 ACR 的授权信息

获取镜像仓库的登录名

  • 如果您使用的是阿里云账号,阿里云账号就是您的镜像仓库登录名。
  • 如果您使用的是 RAM 用户,去掉 RAM 用户账号 aliyundoc.com 后的名称就是您的镜像仓库登录名。例如您的 RAM 用户为 28768383240243****@aliyundoc.com,则您的镜像仓库登录名为28768383240243****。

设置镜像仓库登录密码

1.登录容器镜像服务控制台

2.单击设置Registry登录密码

💡
如果您忘记设置的Registry登录密码,您可以在个人实例 > 仓库管理 > 访问凭证来重置密码。

3.在设置Registry登录密码对话框中输入密码和确认密码,单击确定。

Step 3. 配置 GitHub Actions 同步镜像

配置 GitHub Actions 可以参考我的 GitHub 仓库

1.准备 auth.yaml,images.yaml ,image-sync.yml 这 3 个文件,它们分别是镜像仓库认证信息,源和目标镜像映射关系,Action 工作流模板,按下面的路径存储:

.github/
    workflows/
        image-sync.yml  # Workflow templates
image-sync/
    auth.yaml           # Docker image repository verification information
    images.yaml         # Map of source and target images

2.除了 image-sync.yml 的路径是固定的,其他两个路径可以自定义,只需要在 image-sync.yml 修改参数即可:

jobs:
    sync-images:
        with:
            auth_file: ./image-sync/auth.yaml           # The auth information file of registries, optional.
            images_file: ./image-sync/images.yaml       # The images file descirbes which images need to sync, always needed.
            version: latest                             # The version of image-syncer, use the latest version if not specified.
            proc: 6                                     # The max number of goroutines to sync images, default value is 5.

3.需要在 auth.yaml 中输入目标 registry 的鉴权信息(如果源 registry 也需要鉴权,则源 registry 的鉴权信息也需要输入),最佳实践是将鉴权信息输入到 Secrets 中,然后在 image-sync.yml 中作为 env 使用,最后在 auth.yaml 中以 ${XXX} 的形式引用:

# auth.yaml
registry.cn-hangzhou.aliyuncs.com:
  username: ${ACR_USERNAME}
  password: ${ACR_PASSWORD}
# image-sync.yml
jobs:
    sync-images:
      env:
        ACR_USERNAME: ${{ secrets.ACR_USERNAME }}
        ACR_PASSWORD: ${{ secrets.ACR_PASSWORD }}

在 GitHub 仓库的 Settings 中点击 Secrets and variables > Actions,然后在 Repository secrets 点击 New repository secret 来添加鉴权信息:

4.镜像同步配置文件定义了所有的镜像同步规则。每条规则都是一个键值对,键表示“源镜像地址”,值表示“目标镜像地址”。源/目标镜像地址与我们在 docker pull/push 命令中使用的 url 基本相同,但在 “tags” 和 “digest” 部分还是有区别的:

  • 源镜像 url 和目标镜像 url 都不能为空。
  • 如果源镜像 url 不包含 tags 或 digest,则源仓库的所有 tags 都会被同步。
  • 源镜像 url 可以有多个 tags,tags 之间用逗号隔开,只有指定的 tags 才会被同步。
  • 源镜像 url 最多只能有一个 digest,目标镜像 url 只能没有 digest 或者同时有相同的 digest。
  • 源镜像 url 的“tags”部分可以是一个正则表达式,需要有一个额外的前缀和后缀字符串/。源仓库中所有符合正则表达式的标签都会被同步,不支持多个正则表达式。
  • 如果目标镜像 url 没有摘要或标签,则表示源镜像在同步后会保留相同的标签或摘要。
  • 目标镜像 url 可以有多个标签,标签数量必须与源镜像url中的标签数量相同,则所有源镜像的标签都会更改为新标签(从左到右对应)。
  • “目标镜像 url”也可以是一个数组,每个数组都遵循上述规则。
  • 我在 image-sync.yml 中配置了两个触发条件,你可以参考 GitHub 文档按需修改:
    • 每日0点(UTC时间)
    • main 分支有新的提交
on:
  workflow_dispatch:
  schedule:
    - cron: "0 0 * * *"
  push:
    branches:
      - main

6.配置完成之后,此 Action 会每日定时同步镜像到 ACR 中,我目前使用的镜像较少没有什么特殊的问题,如果你有什么使用问题请在 QinYangWang/actions 这个仓库下提交 issues,我会尽量解答或修复相关问题。