Docker registryV2整体架构与启动过程是怎样的

66次阅读
没有评论

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

这篇文章主要介绍“Docker registryV2 整体架构与启动过程是怎样的”,在日常操作中,相信很多人在 Docker registryV2 整体架构与启动过程是怎样的问题上存在疑惑,丸趣 TV 小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Docker registryV2 整体架构与启动过程是怎样的”的疑惑有所帮助!接下来,请跟着丸趣 TV 小编一起来学习吧!

Docker registry 概述

用一句话解释 Docker registry 就是:存放 docker image 的远程仓库。在使用 docker 的过程中,我们一定会用到 docker Registry,当我们使用 docker 的 pull 命令(下载镜像),或者 run 一个本地没有的镜像时,docker engine 会从默认的仓库下载对应的镜像。

目前,docker pull 命令默认仓库是 docker 的官方仓库,这样就导致一个问题,下载镜像速度比较慢。所以在大型分布式 docker 集群中,通常都会配置一个私有的 docker registry,这样能提高镜像下载速度,从而提升应用的启动速度;也方便管理镜像。

docker registry 的安装方式也很简单,docker 公司已经把 registry 封装在一个 docker 容器中了,我们只需要下载这个容器,然后启动,就可以使用了,十分方便。但是,这样启动的方式,只能有一个 registry,在稍大一点的集群中,单点故障和性能瓶颈问题就比较突出了,扩展成高可用的分布式结构势在必行,所以很多公司在优化 registry 方面做了很多工作,目前开源的有 VMware 的 Habor[1] 和京东的 speedy[2]。

Docker Registry 发展历史

– 2013 年 3 月 13 日,docker 在 github 上有了第一个 release[3]
– 2013 年 7 月 3 日,docker 在 github 上发布了 docker registry v1[4]
– 2015 年 1 月 30 日,docker registry v2(项目名叫 docker distribution) 有了第一个 release,同时停止更新 docker registry v1[5]
 

在使用 docker registry v2 的时候需要注意,只有 docker1.6 以上版本才支持 registry v2,这并不意味着 1.6 以后只能用 v2 版本,我们从源代码里可以看出,docker Engine 在下载镜像的时候,会自动判断远端仓库是 v1 还是 v2 版,从而使用不同的下载策略,这个策略可太重要了。下面我们就讲一下 v1 和 v2 下载策略的区别。

 

图 1 v1 版串行下载 layer

我们知道,一个 docker image 是由很多的 layer 组成的,registry v1 的下载过程如图 1 所示,下载镜像时也是以 layer 为最小单元下载的,在 v1 的时代 docker image,镜像结构有一种链表一样的组织,当下载完一个 layer 时,才能得到 parent 信息,然后再去下载 parent layer,这样结构显然效率不高,所以在 v2 中,改变了这种结构,在 image 的 manifest 文件中存储了所有的 layer 信息,这样拿到所有的 layer 信息,就可以并行下载了,提高了下载效率,过程如图二所示。

 

图二 v2 版升级为并行下载 layer
 

还有就是使用的开发语言也有改变,从 python 变成 go。

Docker registryV2 整体架构图

 

图 3 docker registry 2.0 架构图 [6]
 

从架构图上我们发现,registry v2 的架构还是很简单的,它的核心是一个 web 服务器,从阅读源码也会发现,具体实现是用 go 语言的 net/http 包中的 http.Server,在 registry 初始化时绑定了 rest 接口。请求会触发相应的 handler,handler 会从后端存储中取出具体的数据并写入 response。这个过程也很容易理解。

Registry 启动源码分析

下面我们就讲一下 registry 的启动过程,我也是第一次细读开源项目的源码,也讲一下我作为一个新手是如何阅读源代码的。

既然 registry 是以一个 docker container 形式运行的,要看它是如何启动的,当然首先看它的 Dockerfile

 

图 4 Dockerfile
 

主要做了两件事:
1. 拷贝代码到容器中;
2. 编译成二进制可执行文件;
3. 指定程序入口;
 

当我们运行 docker run –p 5000:5000 registry:2 时,容器内部 registry 的启动命令其实是 registry serve /etc/docker/registry/config.yml,
进入到项目中找 main 函数,发现程序的入口文件是 /cmd/registry/main.go,main 函数也只有一句话:

 

其实在加载 RootCmd 时已经做了命令绑定,子命令 serve 对应的实现在 /registry/registry.go L 30,调用的内容主要有:
1. 读取配置文件;
2. 把配置参数传递给 NewRegistry() 函数,用来实例化一个 registry 对象(虽然对象这个词用在 go 语言里并不合适,单张这样类比更好理解);
3. registry 进入端口监听状态,启动完毕。
 

Registry 对象的结构定义在 /registry/registry.go L68,Registry 结构体声明了三个成员,如图 5 所示,有配置参数,app,还有一个 http Server,显而易见,最重要的就是 app 这个成员了。

 

图 5 Registry 结构体
 

App 结构体的定义在 /registry/handlers/app.go L54,成员长,主要有:
1. driver 指明了后端存储,可以通过 driver 进行读 / 写 / 查询等操作
2. router 包含了 http 路由规则,把不同的请求分发到不同的 handler 上
3. registry 主要的 app 后端
4. accessController 访问控制器
 

NewApp() 函数完成了 App 实例的初始化,实现在 /registry/handlers/app.go L91。该函数的大体流程如下:
1. 声明一个 app 实例
2. 给 app 实例绑定 web handler
3. 初始化 app 的后端存储驱动
4. 初始化 app 的密钥
5. 配置 app 的 redis 缓存
6. 初始化 app 的后端存储重定向功能
7. 根据参数初始化 app 的后端 registry
8. 返回 app 实例
 

至此,/registry/registry.go 的 NewRegistry() 也调用结束,返回了 registry 实例,调用 registry 的 ListenAndServe() 进入监听状态,直到 registry 结束。

到此,关于“Docker registryV2 整体架构与启动过程是怎样的”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注丸趣 TV 网站,丸趣 TV 小编会继续努力为大家带来更多实用的文章!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-16发表,共计2838字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)