部署私有Docker Registry

  • A+
所属分类:Linux

安装部署一个私有的Docker Registry是引入、学习和使用Docker这门技术的必经之路之一。尤其是当Docker被所在组织接受,更多人、项目和产品开始接触和使用Docker时,存储和分发自制的Docker image便成了刚需。Docker Registry一如既往的继承了“Docker坑多”的特点,为此这里将自己搭建”各类”Registry过程中执行的步骤、遇到的问题记录下来,为己备忘,为他参考。

Docker在2015年推出了distribution项目,即Docker Registry 2。相比于old registry,Registry 2使用Go实现,在安全性、性能方面均有大幅改进。Registry设计了全新的Rest API,并且在image存储格式等方面不再兼容于old Registry。去年8月份,docker官方hub使用Registriy 2.1替代了原先的old Registry。如果你要与Registry2交互,你的Docker版本至少要是Docker 1.6。

Docker的开发者也一直在致力于改善Registry安装和使用的体验,通过提供官方Registry Image以及Docker Compose工具等来简化Registry的配置。不过在本文中,我们只是利用Docker以及Registry的官方Image来部署Registry,这样更便于全面了解Registry的部署配置细节。

Registry2在镜像存储方面不仅支持本地盘,还支持诸多主流第三方存储方案。通过分布式存储系统你还可以实现一个分布式Docker Registry服务。这里仅以本地盘以及single node registry2为例。

一、环境

这里还是复用以往文章中的Docker环境:

本次Registry使用当前最新stable版本:Registry 2.3.0。由于镜像采用本地磁盘存储,root分区较小,需要映射使用其他volume。

二、初次搭建

本以为Docker Registry的搭建是何其简单的,甚至简单到通过一行命令就可以完成的。比如我们在Registry Server上执行:

Registry container已经跑起来了,其启动日志可以通过:docker logs registry查看。

我们在71本地给busybox:latest打一个tag,并尝试将新tag下的image push到Registry中去:

push到Registry中:

出错了!简单分析了一下,可能是71上docker daemon配置中加了http代理的缘故,导致无法ping通registry endpoint。于是在/etc/default/docker中注释掉export http_proxy=”xxx”的设置,并重启docker daemon。

再次尝试push:

虽然还是失败,但错误信息已有所不同了。这次看来连接是可以建立的,但client端通过https访问server端,似乎想tls通信,但这一过程并未完成。

在其他机器上尝试push image到registry也遇到了同样的错误输出,如下:

从错误信息来看,client与Registry交互,默认将采用https访问,但我们在install Registry时并未配置指定任何tls相关的key和crt文件,https访问定然失败。要想弄清这个问题,只能查看Registry Manual

三、Insecure Registry

Registry的文档还是相对详尽的。在文档中,我们找到了Insecure Registry,即接收plain http访问的Registry的配置和使用方法,虽然这不是官方推荐的。

实际上对于我们内部网络而言,Insecure Registry基本能满足需求,部署过程也避免了secure registry的那些繁琐步骤,比如制作和部署证书等。

为了搭建一个Insecure Registry,我们需要先清理一下上面已经启动的Registry容器。

修改Registry server上的Docker daemon的配置,为DOCKER_OPTS增加–insecure-registry:

重启Docker Daemon,启动Registry容器:

尝试再次Push image:

这回push ok!

我们将本地的tag做untag处理,再从Registry pull相关image:

可以看到:Pull过程也很顺利。

在Private Registry2中查看或检索Repository或images,将不能用docker search

但通过v2版本的API,我们可以实现相同目的:

在其他主机上,我们尝试pull busybox:

我们发现依旧不能pull和push!在Registry手册中讲到,如果采用insecure registry的模式,那么所有与Registry交互的主机上的Docker Daemon都要配置:–insecure-registry选项。

我们按照上面的配置方法,修改105.72上的/etc/default/docker,重启Docker daemon,再执行pull/push就会得到正确的结果:

四、Secure Registry

Docker官方是推荐你采用Secure Registry的工作模式的,即transport采用tls。这样我们就需要为Registry配置tls所需的key和crt文件了。

我们首先清理一下环境,将上面的Insecure Registry停掉并rm掉;将各台主机上Docker Daemon的DOCKER_OPTS配置中的–insecure-registry去掉,并重启Docker Daemon。

如果你拥有一个域名,域名下主机提供Registry服务,并且你拥有某知名CA签署的证书文件,那么你可以建立起一个Secure Registry。不过我这里没有现成的证书,只能使用自签署的证书。严格来讲,使用自签署的证书在Docker官方眼中依旧属于Insecure,不过这里只是借助自签署的证书来说明一下Secure Registry的部署步骤罢了。

1、制作自签署证书

如果你有知名CA签署的证书,那么这步可直接忽略。

2、启动Secure Registry

启动带证书的Registry:

由于证书的CN是mydockerhub.com,我们需要修改一下/etc/hosts文件:

重新为busybox制作一个tag:

Push到Registry:

push失败了!从错误日志来看,docker client认为server传输过来的证书的签署方是一个unknown authority(未知的CA),因此验证失败。我们需要让docker client安装我们的CA证书:

再执行Push,我们看到了成功的输出日志。由于data目录下之前已经被push了tonybai/busybox repository,因此提示“已存在”:

3、外部访问Registry

我们换其他机器试试访问这个secure registry。根据之前的要求,我们照猫画虎的修改一下hosts文件,安装ca.cert,去除–insecure-registry选项,并重启Docker daemon。之后尝试从registry pull image:

这样来看,如果使用自签署的证书,那么所有要与Registry交互的Docker主机都需要安装mydockerhub.com的ca.crt(domain.crt)。但如果你使用知名CA,这一步也就可以忽略。

五、Registry的鉴权管理

Registry提供了一种基础的鉴权方式。我们通过下面步骤即可为Registry加上基础鉴权:

在Register server上,为Registry增加foo用户,密码foo123:(之前需要停掉已有的Registry,并删除之)

在105.72上,我们尝试push image到Registry:

错误信息提示:鉴权失败。

在72上执行docker login:

login成功后,再行Push:

Push ok!

六、Registry中images的管理

前面提到过,通过V2版Rest API可以查询Repository和images:

但如果要删除Registry中的Repository或某个tag的Image,目前v2还不支持,原因见Registry的roadmap中的说明

不过如果你的Registry的存储引擎使用的是本地盘,倒是有一些第三方脚本可供使用,比如:delete-docker-registry-image

七、小结

Registry2发布不到1年,目前还有许多问题待解决,就比如delete image的问题,相信在2.4以及后续版本这些问题会被逐个解决掉或能找到一个相对理想的方案。

weinxin
微信公众号
扫一扫关注运维生存时间公众号,获取最新技术文章~
默北

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: