镜像仓库代理-如何支持多`Namespace`

国内镜像拉取环境的恶劣程度的加剧,好不容易拉取下来的镜像,因为环境的重建等原因,又要重头拉取,非常耗费时间,而且还很不稳定。
如果有一套自己的镜像拉取代理,那么之前拉取的镜像都保存在代理中,后续重新拉取就简单多了,再也不用煎熬了。

一般搭建镜像代理可以使用 registry 搭建即可,不论是直接使用docker还是kubernetes都非常方便;但是最大的一个问题是,registry官方并不会支持多namespace
比如docker.io, registry.k8s.io两个不同的镜像仓库,需要部署2套不一样的registry-proxy服务;然后再借助nginx等服务进行反向代理,来映射到不同的registry-proxy服务; 非常不方便。

查找了一些资料, registry实际上对应的是开源项目 distribution/distribution 编译出的镜像; 在Issue中发现有一些前驱实际上已经发现这个问题,并且也在尝试进行一些修改,比如:

但是因为一些标准原因,导致这些PR迟迟无法合并;如果自己维护一个fork,后续官方的代码更新合并也是一个问题。

所以这里换了一个角度来解决这个问题,既然短时间无法让提交的PR合并,那么我们直接使用registry代码作为lib构建一个支持多namespace的镜像代理。

代码请跳转这里 registry-proxy

原理分析

通过对registry代码的分析,实际上registry-proxy会产生一个 registry.Registry 对象,那么:

  • 每个namespace创建一个registry.Registry
  • 每个监听在一个本地unix socket
  • 前置HTTP Server根据URL中的请求参数ns,分发到不同的unix socket

ARCH

安装

Docker 本地部署

  • 快速部署: 自动支持所有的namespace
1
2
3
docker run -d --restart always --name registry-proxy -p 5000:5000 \
  -v $PWD/var:/root/var \
  docker.io/aproton/registry-proxy:latest
  • 指定Namespace配置: 对每个namespace进行精细的配置
1
2
3
4
docker run -d --restart always --name registry-proxy -p 5000:5000 \
  -v $PWD/var:/root/var \
  -v $PWD/config:/root/config \
  docker.io/aproton/registry-proxy:latest

其中 $PWD/config 是一个配置文件目录,包含以下文件:

文件名 意义 格式
main.yaml 主配置文件
docker.io.yaml docker.io 的代理配置

代码介绍