如何部署一个 docker 私有registryregistry

温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
君子务本,本立而道成。
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
阅读(22894)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_',
blogTitle:'部署自己的私有 Docker Registry',
blogAbstract:'这篇博客讨论了如何部署一个带 SSL 加密、HTTP 验证并有防火墙防护的私有&
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}主题信息(必填)
主题描述(最多限制在50个字符)
申请人信息(必填)
申请信息已提交审核,请注意查收邮件,我们会尽快给您反馈。
如有疑问,请联系
傻丫头和高科技产物小心翼翼的初恋
如今的编程是一场程序员和上帝的竞赛,程序员要开发出更大更好、傻瓜都会用到软件。而上帝在努力创造出更大更傻的傻瓜。目前为止,上帝是赢的。个人网站:。个人QQ群:、
个人大数据技术博客:
人生得意须尽欢,莫使金樽空对月。
本文转自微信号EAWorld。扫描下方二维码,关注成功后,回复“普元方法+”,将会获得热门课堂免费学习机会!
一、Harbor的安全机制
二、Harbor的镜像同步
三、Harbor与K8s的集成实践
四、两个小贴士
Habor是由VMWare公司开源的容器镜像仓库。事实上,Habor是在Docker Registry上进行了相应的企业级扩展,从而获得了更加广泛的应用,这些新的企业级特性包括:管理用户界面,基于角色的访问控制 ,AD/LDAP集成以及审计日志等。
容器的核心在于镜象的概念,由于可以将应用打包成镜像,并快速的启动和停止,因此容器成为新的炙手可热的基础设施CAAS,并为敏捷和持续交付包括DevOps提供底层的支持。
而Habor和Docker Registry所提供的容器镜像仓库,就是容器镜像的存储和分发服务。之所以会有这样的服务存在,是由于以下三个原因:
1、提供分层传输机制,优化网络传输
Docker镜像是是分层的,而如果每次传输都使用全量文件(所以用FTP的方式并不适合),显然不经济。必须提供识别分层传输的机制,以层的UUID为标识,确定传输的对象。
2、提供WEB界面,优化用户体验
只用镜像的名字来进行上传下载显然很不方便,需要有一个用户界面可以支持登陆、搜索功能,包括区分公有、私有镜像。
3、支持水平扩展集群
当有用户对镜像的上传下载操作集中在某服务器,需要对相应的访问压力作分解。
上面这些就是Docker Registry所完成的主要工作,而Habor在此之上,又提供了用户、同步等诸多特性,这篇文章中我们就这几个方面作一些阐述,同时实例代码介绍Harbor与K8s的集成。一、Harbor的安全机制企业中的软件研发团队往往划分为诸多角色,如项目经理、产品经理、测试、运维等。在实际的软件开发和运维过程中,这些角色对于镜像的使用需求是不一样的。从安全的角度,也是需要通过某种机制来进行权限控制的。
举例来说,开发人员显然需要拥有对镜像的读写(PULL/PUSH)权限以更新和改正代码;测试人员中需要读取(PULL)权限;而项目经理需要对上述的角色进行管理。
Harbor为这种需求提供了用户和成员两种管理概念。
在Harbor中,用户主要分为两类。一类为管理员,另一类为普通用户。两类用户都可以成为项目的成员。而管理员可以对用户进行管理。
成员是对应于项目的概念,分为三类:管理员、开发者、访客。管理员可以对开发者和访客作权限的配置和管理。测试和运维人员可以访客身份读取项目镜像,或者公共镜像库中的文件。
从项目的角度出发,显然项目管理员拥有最大的项目权限,如果要对用户进行禁用或限权等,可以通过修改用户在项目中的成员角色来实现,甚至将用户移除出这个项目。
二、Harbor的镜像同步为什么需要镜像同步
由于对镜像的访问是一个核心的容器概念,在实际使用过程中,一个镜像库可能是不够用的,下例情况下,我们可能会需要部署多个镜像仓库:
国外的公有镜像下载过慢,需要一个中转仓库进行加速
容器规模较大,一个镜像仓库不堪重负
对系统稳定性要求高,需要多个仓库保证高可用性
镜像仓库有多级规划,下级仓库依赖上级仓库
更常用的场景是,在企业级软件环境中,会在软件开发的不同阶段存在不同的镜像仓库,
在开发环境库,开发人员频繁修改镜像,一旦代码完成,生成稳定的镜像即需要同步到测试环境。
在测试环境库,测试人员对镜像是只读操作,测试完成后,将镜像同步到预上线环境库。
在预上线环境库,运维人员对镜像也是只读操作,一旦运行正常,即将镜像同步到生产环境库。
在这个流程中,各环境的镜像库之间都需要镜像的同步和复制。
Harbor的镜像同步机制
有了多个镜像仓库,在多个仓库之间进行镜像同步马上就成为了一个普遍的需求。比较传统的镜像同步方式,有两种:第一种方案,使用Linux提供的RSYNC服务来定义两个仓库之间的镜像数据同步。
第二种方案,对于使用IaaS服务进行镜像存储的场景,利用IaaS的配置工具来对镜像的同步进行配置。
这两种方案都依赖于仓库所在的存储环境,而需要采用不同的工具策略。Harbor则提供了更加灵活的方案来处理镜像的同步,其核心是三个概念:
用Harbor自己的API来进行镜像下载和传输,作到与底层存储环境解耦。
利用任务调度和监控机制进行复制任务的管理,保障复制任务的健壮性。在同步过程中,如果源镜像已删除,Harbor会自动同步删除远端的镜像。在镜像同步复制的过程中,Harbor会监控整个复制过程,遇到网络等错误,会自动重试。
提供复制策略机制保证项目级的复制需求。在Harbor中,可以在项目中创建复制策略,来实现对镜像的同步。与Docker Registry的不同之处在于,Harbor的复制是推(PUSH)的策略,由源端发起,而Docker Registry的复制是拉(PULL)的策略,由目标端发起。
Harbor的多级部署
在实际的企业级生产运维场景,往往需要跨地域,跨层级进行镜像的同步复制,比如集团企业从总部到省公司,由省公司再市公司的场景。
这一部署场景可简化如下图:
更复杂的部署场景如下图:
三、Harbor与K8s的集成实践
Harbor提供了基于角色的访问控制机制,并通过项目来对镜像进行组织和访问权限的控制。kubernetes中通过namespace来对资源进行隔离,在企业级应用场景中,通过将两者进行结合可以有效将kubernetes使用的镜像资源进行管理和访问控制,增强镜像使用的安全性。尤其是在多租户场景下,可以通过租户、namespace和项目相结合的方式来实现对多租户镜像资源的管理和访问控制。
集成的核心概念和关键步骤
两者的集成,一个核心概念是k8s的secret。作为kubernetes中一个重要的资源secret,它的设计初衷是为了解决容器在访问外部网络或外部资源时验证的问题,例如访问一个Git仓库,连接一个数据库,设置一些密码配置等,需要额外验证的场景Secret存储了敏感数据,例如能允许容器接受请求的权限令牌。通过将Harbor的用户信息与K8s的Secret相关联,即达成了两者的集成。步骤如下:
在Harbor中创建创建用户,项目,将项目设置为私有。
将创建的用户加入到项目中,设置用户的角色为开发者或者为项目管理员。确保该账户具有拉取该仓库镜像的权限。
创建K8s下的Secret,其中secret中的用户名、密码和邮箱地址信息为在Harbor中创建的用户的信息。
在此过程中需要注意的是,第三步中创建的secret,对应的用户必须在Harbor的对应私库中有下载镜像的权限,否则应用部署时会报无法下载镜像。
在Harbor中创建了用户,如userD
在Harbor中创建一个私有项目,如projectA
在Harbor中使用Docker命令行登陆并上传镜像至步骤2中的私有库
在K8s中创建Namespace
在K8s的Namespace中创建SecretC,该Secret对应Harbor中的用户账号userD
使用Harbor私库中的镜像在K8s的Namespace中部署应用,指定镜像下载时使用上面创建的SecretC
如果只需要能够拉取Harbor的镜像在K8s中部署应用,Harbor中的userD需要在projectA中有最低权限的访客成员角色。
Harbor与K8s集成的代码实践
imagePullSecret在K8s中用来保存镜像仓库的认证信息,以方便Kubelet在启动Pod时,能够获得镜像仓库的认证信息,确保能Kubelet够有权限从镜像仓库中下载Pod所需的镜像。
首先我们来看一下k8s中的ImagePull类型的Secret如何来创建。官方文档为:
以下代码实践Harbor版本是0.3.5。
首先,我们需要在harbor中选择一个用户,使用它的用户名与密码生成一个字符串,用户名与密码中间用冒号相连,然后使用base64对它进行加密,如下所示:[root@k8s-01 ~]# echo “test:tT001”|base64
dGVzdDp0VDAwMQo=
然后,我们需要生成一个dockerconfig.json,需要使用上面生成的加密字符串,内容大致如下,假如对应的harbor库的地址为::
“auths”:{
“auth”: “dGVzdDp0VDAwMQo=”,
“email”: “”
我们需要把这整个json使用base64进行加密。生成的字符串可能比较长,需要加上 -w 0 参数,不让它换行。将上面的json保存成dockerconfig.json文件,然后执行命令:
[root@k8s-01 secret]# cat dockerconfig.json |base64 -w 0
ewogICJhdXRocyI6IHsKICAgICJodWIudGVzdGhhcmJvci5jb20iOiB7CiAgICAgICJhdXRoIjogImRHVnpkRHAwVkRBd01Rbz0iLAogICAgICAiZW1haWwiOiAiIgogICAgfQogIH0KfQo=
现在,我们可以来创建secret所需的yaml了。secret创建的时候,必须指定namespace。多个namespace中的secret可以同名。假如我们需要在名为hub中的namespace中创建名为testsecret的secret,对应的secret.yaml内容如下。需要使用上面生成的加密字符串。
此时在k8s中使用kubectl create 命令即可创建对应的secret:
kubectl create -f secret.yaml
最后,在部署应用的时候,我们需要为Pod指定下载镜像所需的secret名字,如下所示:
apiVersion: v1
name: httpdpod
namespace: hub
containers:
- name: httpdpod
image:/project1/httpd:2.2
imagePullSecrets:
- name:testsecret
注意,要想部署成功,test用户必须为harbor中的project1项目中的成员,它才能有下载这个httpd:2.2的权限。
容器云的用户与集成
作为容器云运行时,Harbor的用户与K8s的Secret可以有更集约的整合方式。在我们的项目实践中,一个容器云的用户与一个Harbor中同名Project一一对应,但此用户可以在k8s中可以创建多个namespace。为了简化管理过程,目前我们的做法是:
在容器云启动过程中,自动在Harbor中创建一个专用用户,专门用来在各私库中下载镜像
每个在Harbor中新建的私库,都会将这个专用用户添加为它的访客成员角色 ,使这个专用用户拥有下载此库中镜像的权限
在K8s中,每创建一个新的namespace的同时,在此namespace下,使用上面的专用用户的信息创建固定名称的secret(多namespace中可存在同名secret)
部署应用时,指定imagePullSecrets下面的名称为上面固定的secret名称。四、两个小贴士使用在线工具让Harbor的接口文档更易读
Harbor对外提了restful形式的接口供其它系统集成,它的接口描述以swagger格式的文档包含在源码中,文档地址为: 。
目前,越来越多的系统使用restful的接口对外暴露服务,而swagger已经成了事实上的restful接口的描述标准。直接使用文本编辑器去查看这种swagger文档,会有点晕,没法方便清晰地查看接口的整体结构。我们可以借助一些工具来看这些文档。在线的,比如官方提供的swagger在线编辑器,把文档内容复制至左边,右边即可显示html格式的文档,可以折叠等,让人对所有接口一目了然。离线的,则可以在一些编辑器安装插件,将它同样转化成html进行查看,比如vscode,安装 Swagger Viewer插件即可。关于Swagger的使用,也可以阅读我的同事李小飞的文章《微服务架构实战:Swagger规范RESTful API》。
两种格式的文档展示如下:
小贴士:Harbor的Java Client开源实现
对于熟悉Java编程的用户来说,Harbor官方没有提供java client,但是在github上也有人写了相关的项目,项目地址:
五、总结本文主要介绍了Harbor的用户机制、镜像同步和与K8s的集成实践。
Harbor的用户机制分为系统用户和项目成员两类。用户可以成为项目成员,而不同成员有不同的镜像读写权限。
Harbor的同步策略和任务调度机制,为镜像库间的镜像同步提供了灵活的机制。
利用K8s的Secret与Harbor用户的关联,可以在K8s中拉取Harbor私有库中的镜像来部署应用。我们也用代码进行了举例。最后,再分享几个在Harbor(0.3.5)的使用过程中碰到的小坑:
在Harbor中创建用户时,密码必须为复杂密码。但是修改时,没有了此限制
用户更新密码的时候,原密码不能与新密码一致,否则报500内部错误
在为harbor的project添加成员的时候,成员角色没有相关API,需要给的id值也没有常量定义,目前来看,1为admin, 2为devlop,3为guest。关于作者:秦双春现任普元云计算架构师。曾在PDM,云计算,数据备份,移动互联相关领域公司工作,10年IT工作经验。曾任上海科企软件桌面虚拟化产品的核心工程师,主导过爱数TxCloud云柜的设计与开发,主导过万达信息的食安管理与追溯平台的移动平台开发。国内云计算的早期实践者,开源技术爱好者,容器技术专家。
关于EAWorld
微服务,DevOps,元数据,企业架构原创技术分享,EAii(Enterprise Architecture Innovation Institute)企业架构创新研究院旗下官方微信公众号。扫描下方二维码,关注成功后,回复“普元方法+”,将会获得热门课堂免费学习机会!
微信号:EAWorld。
全新形态的PWorld2017盛大开启,首四场定于7月1日在北京、上海、广州、成都四城同步举行。CSDN专项报名通道可获得现场伴手礼个性T恤一件!7月1日北京站报名:7月1日上海站报名:7月1日广州站报名:7月1日成都站报名:IT-Docker(31)
安装部署一个私有的Docker Registry是引入、学习和使用
这门技术的必经之路之一。尤其是当Docker被所在组织接受,更多人、项目和产品开始接触和使用Docker时,存储和分发自制的Docker image便成了刚需。Docker Registry一如既往的继承了“Docker坑多”的特点,为此这里将自己搭建”各类”Registry过程中执行的步骤、遇到的问题记录下来,为己备忘,为他参考。
Docker在2015年推出了
项目,即Docker Registry 2。相比于
,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的配置。不过在本文中,我们只是利用Docker以及Registry的官方Image来部署Registry,这样更便于全面了解Registry的部署配置细节。
Registry2在镜像存储方面不仅支持本地盘,还支持诸多主流第三方存储方案。通过分布式存储系统你还可以实现一个分布式Docker Registry服务。这里仅以本地盘以及single node registry2为例。
这里还是复用以往文章中的Docker环境:
Docker Registry Server: 10.10.105.71 Ubuntu 14.04 3.16.0-57-generic;docker 1.9.1
其他两个工作Server:
10.10.105.72 Ubuntu 14.04 3.19.0-25- docker 1.9.1
10.10.126.101 Ubuntu 12.04 3.16.7-013607- docker 1.9.1
本次Registry使用当前最新stable版本:Registry 2.3.0。由于镜像采用本地磁盘存储,root分区较小,需要映射使用其他volume。
本以为Docker Registry的搭建是何其简单的,甚至简单到通过一行命令就可以完成的。比如我们在Registry Server上执行:
在~/dockerregistry下,执行:
$sudo docker run -d -p
-v `pwd`/data:/var/lib/registry --restart=always --name registry registry:2
Unable to find image 'registry:2' locally
2: Pulling from library/registry
fa: Pull complete
9ba: Pull complete
973de4038269: Pull complete
c1: Pull complete
8da16446f5ca: Pull complete
fd8c38b8b68d: Pull complete
f02: Pull complete
e039ba1c0008: Pull complete
c457c689c328: Pull complete
Digest: sha256:339d702cf9a4b0aa255ee7cebee9ad8a247afe8c49ef1
Status: Downloaded newer image for registry:2
ecbdefab36b0a44bd2a5a2b44
$ docker images
REPOSITORY
VIRTUAL SIZE
c457c689c328
9 days ago
$ docker ps
CONTAINER ID
registry:2
&/bin/registry /etc/d&
About a minute ago
Up About a minute
0.0.0.0:/tcp
Registry container已经跑起来了,其启动日志可以通过:docker logs registry查看。
我们在71本地给busybox:latest打一个tag,并尝试将新tag下的image push到Registry中去:
$ docker tag busybox:latest 10.10.105.71:5000/tonybai/busybox:latest
$ docker images
REPOSITORY
VIRTUAL SIZE
c457c689c328
9 days ago
9 days ago
10.10.105.71:5000/tonybai/busybox
9 days ago
push到Registry中:
$ docker push 10.10.105.71:5000/tonybai/busybox
The push refers to a repository [10.10.105.71:5000/tonybai/busybox] (len: 1)
unable to ping registry endpoint https://10.10.105.71:5000/v0/
v2 ping attempt failed with error: Get https://10.10.105.71:5000/v2/: Tunnel or SSL Forbidden
v1 ping attempt failed with error: Get https://10.10.105.71:5000/v1/_ping: Tunnel or SSL Forbidden
出错了!简单分析了一下,可能是71上docker daemon配置中加了http代理的缘故,导致无法ping通registry endpoint。于是在/etc/default/docker中注释掉export http_proxy=”xxx”的设置,并重启docker daemon。
再次尝试push:
$ docker push 10.10.105.71:5000/tonybai/busybox
The push refers to a repository [10.10.105.71:5000/tonybai/busybox] (len: 1)
unable to ping registry endpoint https://10.10.105.71:5000/v0/
v2 ping attempt failed with error: Get https://10.10.105.71:5000/v2/: tls: oversized record received with length 20527
v1 ping attempt failed with error: Get https://10.10.105.71:5000/v1/_ping: tls: oversized record received with length 20527
虽然还是失败,但错误信息已有所不同了。这次看来连接是可以建立的,但client端通过https访问server端,似乎想tls通信,但这一过程并未完成。
在其他机器上尝试push image到registry也遇到了同样的错误输出,如下:
10.10.105.72:
$ docker push 10.10.105.71:5000/tonybai/ubuntu
The push refers to a repository [10.10.105.71:5000/tonybai/ubuntu] (len: 1)
unable to ping registry endpoint https://10.10.105.71:5000/v0/
v2 ping attempt failed with error: Get https://10.10.105.71:5000/v2/: tls: oversized record received with length 20527
v1 ping attempt failed with error: Get https://10.10.105.71:5000/v1/_ping: tls: oversized record received with length 20527
从错误信息来看,client与Registry交互,默认将采用https访问,但我们在install Registry时并未配置指定任何tls相关的key和crt文件,https访问定然失败。要想弄清这个问题,只能查看
Registry的文档还是相对详尽的。在文档中,我们找到了
,即接收plain http访问的Registry的配置和使用方法,虽然这不是官方推荐的。
实际上对于我们内部网络而言,Insecure Registry基本能满足需求,部署过程也避免了secure registry的那些繁琐步骤,比如制作和部署证书等。
为了搭建一个Insecure Registry,我们需要先清理一下上面已经启动的Registry容器。
$ docker stop registry
$ docker rm registry
修改Registry server上的Docker daemon的配置,为DOCKER_OPTS增加–insecure-registry:
DOCKER_OPTS=&--insecure-registry 10.10.105.71:5000 ....
重启Docker Daemon,启动Registry容器:
$ sudo service docker restart
docker stop/waiting
docker start/running, process 6712
$ sudo docker run -d -p
-v `pwd`/data:/var/lib/registry --restart=always --name registry registry:2
5966e92fce9c68d2edeecf5cea019
尝试再次Push image:
$ docker push 10.10.105.71:5000/tonybai/busybox
The push refers to a repository [10.10.105.71:5000/tonybai/busybox] (len: 1)
65e: Pushed
5506dda26018: Pushed
latest: digest: sha256:800f2d4558acd67f52262fbe170c9fc2e67efaa6f230a74b41b555e6fcca2892 size: 2739
这回push ok!
我们将本地的tag做untag处理,再从Registry pull相关image:
$ docker images
REPOSITORY
VIRTUAL SIZE
c457c689c328
9 days ago
10.10.105.71:5000/tonybai/busybox
9 days ago
9 days ago
6cc0fc2a5ee3
5 weeks ago
$ docker rmi 10.10.105.71:5000/tonybai/busybox
Untagged: 10.10.105.71:5000/tonybai/busybox:latest
$ docker images
REPOSITORY
VIRTUAL SIZE
c457c689c328
9 days ago
9 days ago
6cc0fc2a5ee3
5 weeks ago
$ docker pull 10.10.105.71:5000/tonybai/busybox
Using default tag: latest
latest: Pulling from tonybai/busybox
Digest: sha256:800f2d4558acd67f52262fbe170c9fc2e67efaa6f230a74b41b555e6fcca2892
Status: Downloaded newer image for 10.10.105.71:5000/tonybai/busybox:latest
$ docker images
REPOSITORY
VIRTUAL SIZE
c457c689c328
9 days ago
10.10.105.71:5000/tonybai/busybox
9 days ago
9 days ago
6cc0fc2a5ee3
5 weeks ago
可以看到:Pull过程也很顺利。
在Private Registry2中查看或检索Repository或images,
$ docker search 10.10.105.71:5000/tonybai/busybox/
Error response from daemon: Unexpected status code 404
但通过v2版本的API,我们可以实现相同目的:
http://10.10.105.71:5000/v2/_catalog
{&repositories&:[&tonybai/busybox&]}
http://10.10.105.71:5000/v2/tonybai/busybox/tags/list
{&name&:&tonybai/busybox&,&tags&:[&latest&]}
在其他主机上,我们尝试pull busybox:
10.10.105.72:
$docker pull 10.10.105.71:5000/tonybai/busybox
Using default tag: latest
Error response from daemon: unable to ping registry endpoint https://10.10.105.71:5000/v0/
v2 ping attempt failed with error: Get https://10.10.105.71:5000/v2/: tls: oversized record received with length 20527
v1 ping attempt failed with error: Get https://10.10.105.71:5000/v1/_ping: tls: oversized record received with length 20527
我们发现依旧不能pull和push!在Registry手册中讲到,如果采用insecure registry的模式,那么所有与Registry交互的主机上的Docker Daemon都要配置:–insecure-registry选项。
我们按照上面的配置方法,修改105.72上的/etc/default/docker,重启Docker daemon,再执行pull/push就会得到正确的结果:
$ sudo vi /etc/default/docker
$ sudo service docker restart
docker stop/waiting
docker start/running, process 10614
$ docker pull 10.10.105.71:5000/tonybai/busybox
Using default tag: latest
latest: Pulling from tonybai/busybox
5506dda26018: Pull complete
65e: Pull complete
Digest: sha256:800f2d4558acd67f52262fbe170c9fc2e67efaa6f230a74b41b555e6fcca2892
Status: Downloaded newer image for 10.10.105.71:5000/tonybai/busybox:latest
$ docker images
REPOSITORY
VIRTUAL SIZE
8 days ago
10.10.105.71:5000/tonybai/ubuntu
8 days ago
10.10.105.71:5000/tonybai/busybox
9 days ago
$ docker push 10.10.105.71:5000/tonybai/ubuntu
The push refers to a repository [10.10.105.71:5000/tonybai/ubuntu] (len: 1)
3ac: Pushed
8ea: Pushed
2e: Pushed
e3c70beaa378: Pushed
14.04: digest: sha256:72e5438f0fd68fecf02ef592ce2ef7069bbf8c5cc size: 6781
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签署的证书,那么这步可直接忽略。
$ openssl req -newkey rsa:2048 -nodes -sha256 -keyout certs/domain.key -x509 -days 365 -out certs/domain.crt
Generating a 2048 bit RSA private key
..............+++
............................................+++
writing new private key to 'certs/domain.key'
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:Liaoning
Locality Name (eg, city) []:shenyang
Organization Name (eg, company) [Internet Widgits Pty Ltd]:foo
Organizational Unit Name (eg, section) []:bar
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:@
2、启动Secure Registry
启动带证书的Registry:
$ docker run -d -p
--restart=always --name registry \
-v `pwd`/data:/var/lib/registry \
-v `pwd`/certs:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
registry:2
35e8ce77dd455f2bdcd52be8a137f4aaead676c5ea5777
由于证书的CN是,我们需要修改一下/etc/hosts文件:
10.10.105.
重新为busybox制作一个tag:
$docker tag busybox::5000/tonybai/busybox:latest
Push到Registry:
$ docker :5000/tonybai/busybox
The push refers to a repository [:5000/tonybai/busybox] (len: 1)
unable to ping registry endpoint :5000/v0/
v2 ping attempt failed with error: Get :5000/v2/: x509: certificate signed by unknown authority
v1 ping attempt failed with error: Get :5000/v1/_ping: x509: certificate signed by unknown authority
push失败了!从错误日志来看,docker client认为server传输过来的证书的签署方是一个unknown authority(未知的CA),因此验证失败。我们需要让docker client安装我们的CA证书:
$ sudo mkdir -p /etc/docker/certs.:5000
$ sudo cp certs/domain.crt /etc/docker/certs.:5000/ca.crt
$ sudo service docker restart //安装证书后,重启Docker Daemon
再执行Push,我们看到了成功的输出日志。由于data目录下之前已经被push了tonybai/busybox repository,因此提示“已存在”:
$docker :5000/tonybai/busybox
The push refers to a repository [:5000/tonybai/busybox] (len: 1)
65e: Image already exists
5506dda26018: Image already exists
latest: digest: sha256:800f2d4558acd67f52262fbe170c9fc2e67efaa6f230a74b41b555e6fcca2892 size: 2739
3、外部访问Registry
我们换其他机器试试访问这个secure registry。根据之前的要求,我们照猫画虎的修改一下hosts文件,安装ca.cert,去除–insecure-registry选项,并重启Docker daemon。之后尝试从registry pull image:
$ docker :5000/tonybai/busybox
Using default tag: latest
latest: Pulling from tonybai/busybox
Digest: sha256:800f2d4558acd67f52262fbe170c9fc2e67efaa6f230a74b41b555e6fcca2892
Status: Downloaded newer image :5000/tonybai/busybox:latest
$ docker images
REPOSITORY
VIRTUAL SIZE
10.10.105.71:5000/tonybai/ubuntu
9 days ago
9 days ago
10.10.105.71:5000/tonybai/busybox
9 days ago
1.114 :5000/tonybai/busybox
9 days ago
这样来看,如果使用自签署的证书,那么所有要与Registry交互的Docker主机都需要安装的ca.crt(domain.crt)。但如果你使用知名CA,这一步也就可以忽略。
Registry提供了一种基础的鉴权方式。我们通过下面步骤即可为Registry加上基础鉴权:
在Register server上,为Registry增加foo用户,密码foo123:(之前需要停掉已有的Registry,并删除之)
//生成鉴权密码文件
$ mkdir auth
$ docker run --entrypoint htpasswd registry:2 -Bbn foo foo123
& auth/htpasswd
//启动带鉴权功能的Registry:
$ docker run -d -p
--restart=always --name registry \
-v `pwd`/auth:/auth \
-e &REGISTRY_AUTH=htpasswd& \
-e &REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm& \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
-v `pwd`/data:/var/lib/registry \
-v `pwd`/certs:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
registry:2
199ad0bb21b1c96fcd30df636c
在105.72上,我们尝试push image到Registry:
$ docker :5000/tonybai/busybox
The push refers to a repository [:5000/tonybai/busybox] (len: 1)
65e: Image push failed
Head :5000/v2/tonybai/busybox/blobs/sha256:a3ed95caeb02ffe68cdd9fdd633cba7c: no basic auth credentials
错误信息提示:鉴权失败。
在72上执行docker login:
$docker :5000
Username: foo
WARNING: login credentials saved in /home/baiming/.docker/config.json
Login Succeeded
login成功后,再行Push:
$ docker :5000/tonybai/busybox
The push refers to a repository [:5000/tonybai/busybox] (len: 1)
65e: Image already exists
5506dda26018: Image already exists
latest: digest: sha256:800f2d4558acd67f52262fbe170c9fc2e67efaa6f230a74b41b555e6fcca2892 size: 2739
前面提到过,通过V2版Rest API可以查询Repository和images:
$ curl --cacert domain.crt
--basic --user foo:foo123 :5000/v2/_catalog
{&repositories&:[&tonybai/busybox&,&tonybai/ubuntu&]}
但如果要删除Registry中的Repository或某个tag的Image,目前v2还不支持,原因见
不过如果你的Registry的存储引擎使用的是本地盘,倒是有一些第三方脚本可供使用,比如:
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:309934次
积分:3738
积分:3738
排名:第8588名
原创:22篇
转载:426篇
评论:30条
(6)(31)(27)(19)(39)(17)(29)(16)(12)(40)(16)(5)(23)(10)(4)(32)(8)(1)(7)(9)(24)(2)(13)(9)(13)(37)}

我要回帖

更多关于 docker registry web 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信