前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >手把手教你搭建Docker Registry私服

手把手教你搭建Docker Registry私服

作者头像
猿哥
发布2019-07-25 21:36:05
1.7K0
发布2019-07-25 21:36:05
举报
文章被收录于专栏:Web技术布道师Web技术布道师

关于Docker更多的概念将不在本文赘述了,作为虚拟化市场的一颗冉冉升起的新星,Docker得到了越来越多企业的青睐,越来越多的开发者决定拥入Docker的怀抱。

“集装箱”是Docker设计哲学之所在,它让一台物理机(或者虚拟机)同时运行多个彼此隔离的应用变得更为轻松简单,当然这一切还是多亏Linux的相关底层技术,当然,也包括OS X,Windows这两个操作系统。

Docker的相关教程已经够多了,但是由于Docker近年来发展迅猛,版本迭代速度较快,多个版本之间还存在不兼容的情况,如果在网上找博客文章,未必能解决自己遇到的问题。

当然,对于Docker的环境安装,基础命令之类的内容,是完全没有问题的,通读官网文档内容基本都能顺利掌握。然而,当笔者尝试着搭建一套基于SSL的Docker Registry(官网推荐的做法)却遇到了不少的麻烦,对于这部分内容,大多数博客文档内容都是直接跳过了SSL的环节,采用了HTTP的访问形式。

特此分享,通读完了此篇文章后,对于搭建Docker Registry就不再是问题了。

代码语言:javascript
复制
> docker --versionDocker version 18.03.1-ce, build 9ee9f40

以上是我的Docker环境,建议安装Docker1.6+以上版本。

除此之外,读者还需要:

1、一台安装了CentOS_7_64bit操作系统的主机(或者虚拟机);

2、申请一个域名。不然,可以改HOST文件,但不保证能成功。笔者在阿里云申请了一个个人域名,包了5年,价值¥105;

3、如果申请了域名,顺便拿一个免费的CA证书,因为需要实现HTTPS访问,SSL证书是必须的,同样,阿里云上有免费证书申请。不然,可以使用OpenSSL自己生成,这也是很多博文所提到的做法,不保证成功;

4、再装上一个nginx做代理,可选。

5、熟悉Docker的基本概念和常用命令,但不必了解Dockerfile,Compose,Swarm,Kubernetes等高阶知识。

一、从Docker镜像说起

抽象的概念阐述不多说了,笔者举两个例子,让大家感受一下:

1、我们从系统之家下载来的ISO文件,除了基础的操作系统,还可能内置了多个预装软件;

2、在使用maven管理jar包依赖的时候,为了避免每次都从中央仓库拉取依赖包,使用了nexus做了代理仓库。

可以认为,Docker镜像就是一系列软件(文件)的组合,只要将它们放在合适的宿主上,即可做到开箱即用。

关于本文需要的Docker镜像操作,有五个常用的命令:

a、拉取镜像,后跟镜像仓库名称,如果要指定某个版本,可以带上tag。

代码语言:javascript
复制
> docker pull <repo>[:tag]

b、列出所有镜像,能得到镜像的相关基本信息。

代码语言:javascript
复制
> docker images
REPOSITORY                   TAG             IMAGE ID          CREATED        SIZE
redis                       latest          bfcb1f6df2db      3 weeks ago     107MB
registry                      2             d1fd7d86a825      4 months ago    33.3MB
hyper/docker-registry-web   latest          0db5683824d8      19 months ago   599MB

c、删除镜像。可以根据镜像ID,或者镜像仓库名称进行删除。

代码语言:javascript
复制
> docker rmi <IMAGE ID>/<repo>

d、镜像打标。可以将此操作与Git打标进行类比,相当于是release一个可用的镜像版本。

代码语言:javascript
复制
> docker tag <repo> <new_repo>[:tag]

e、镜像推送。同样是可以借鉴Git领域的push操作,将打包好的镜像推送给远程仓库(即为Docker Registry)。

代码语言:javascript
复制
> docker push <new_repo>[:tag]

以上五个命令只做简单介绍,不是本文的重点。更多镜像操作命令,可以自行查阅之。

进行接下来的操作之前,请读者先将registry镜像pull下来。

代码语言:javascript
复制
> docker pull registry:2
2: Pulling from library/registry
81033e7c1d6a: Pull complete
b235084c2315: Pull complete
c692f3a6894b: Pull complete
ba2177f3a70e: Pull complete
a8d793620947: Pull complete
Digest: sha256:672d519d7fd7bbc7a448d17956ebeefe225d5eb27509d8dc5ce67ecb4a0bce54
Status: Downloaded newer image for registry:2

此过程会持续几分钟,视网络状况而定,请读者耐心等候。

注意:笔者在pull的时候,指定了TAG,即为使用v2版本的registry,对于v1版本的registry,读者大可不必在意了,基本上是淘汰了。

二、先睹为快

对于急切想看一下Docker Registry运行效果的读者,可以先阅读本节内容。

运行如下命令即可:

代码语言:javascript
复制
> docker run -d \
-p 5000:5000 \
-v /usr/local/registry:/var/lib/registry \
--restart=always \
--name registry \
registry:2

这是一条典型的run命令,不出意外的话,Registry就在5000端口启动了。

为了验证,读者可以拉取一个busybox镜像(因为体积小),进行实验。

代码语言:javascript
复制
> docker pull busybox

拉取最新的busybox镜像后,再给其打标,准备发布到Registry中。

代码语言:javascript
复制
> docker tag busybox localhost:5000/bosybox:v1.0

最后再推送给Registry。

代码语言:javascript
复制
> docker push localhost:5000/bosybox:v1.0

此时,Registry就有了busybox:v1.0镜像了,这时可以不用再去Docker Hub上面拉取了,通过自建的Registry即可。

代码语言:javascript
复制
> docker pull localhost:5000/bosybox:v1.0

如果想查看远程仓库有哪些镜像,可以运行如下命令:

代码语言:javascript
复制
> curl http://localhost:5000/v2/_catalog

窥一斑而见全豹,通过以上命令,我们能得出一个重要的结论:

对Registry的访问都是通过一系列REST API完成的。

到此为止,我们已经搭建了一个Docker Registry的“半成品”,说是“半成品”是因为这个Registry只能在本机正常工作,如果在其他主机上试图推送镜像上来,结果是失败的。

如果要做到externally-accessible,就必须使用CA安全证书。

三、基于SSL证书改造Registry

在进行本节的操作前,请读者确认是否满足了文章开头所列的条件。

笔者申请了一个域名:iwendao.vip,并映射出来了一个二级域名:registry.iwendao.vip,专门用来作为Docker Registry的访问,然后基于此二级域名申请CA证书。

不出意外的话,从阿里云申请的免费证书都是由Symantec颁发的,将证书下载下来后,压缩包内有两份文件:xxxxxx.pem、xxxxxx.key。

将其更名为server.key,server.pem,通过ftp工具上传至主机,假设存放的目录是:/usr/local/certs。

代码语言:javascript
复制
> ll /usr/local/certs
- rw-r--r-- 1 root root 1678 May 28 13:42 server.key
- rw-r--r-- 1 root root 3662 May 28 13:42 server.pem

因为颁发的是intermediate certificate,会发现没有crt文件,可以使用如下命令得到:

代码语言:javascript
复制
> cat server.pem > server.crt

直接将pem文件内作为crt文件的内容输入,生成了server.crt文件。

至此,域名及其证书已准备就绪。

如果想使用nginx做代理,需要更改一下nginx.conf文件,以下是笔者的配置内容:

代码语言:javascript
复制
user  root root;worker_processes  1;events {
worker_connections  1024;}http {
include       mime.types;
default_type  application/octet-stream;
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log  logs/access.log  main;
sendfile        on;
keepalive_timeout 60;
gzip  on;
server {
listen 443;
server_name i-wendao;
ssl on;
root html;
index index.html index.htm;
ssl_certificate   /usr/local/certs/server.pem;
ssl_certificate_key  /usr/local/certs/server.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location ~  {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_pass https://registry;
}
}
upstream registry {
server 127.0.0.1:5000;
}}

在nginx.conf配置文件中,需要注意两个地方:

1、开启nginx的ssl,只需要配置之前下载好的pem和key文件,这是阿里云官方给出的示例,亲测有效;

2、因为对Registry的访问都是通过REST API完成的,而且是HTTPS的访问协议,所以location节点的配置中,proxy_pass配置的是https://registry,如果配置成http://registry,一旦Docker Registry启用了SSL后,是访问不通的。

宿主机的配置已经完成了,接下来对Docker容器进行配置。

对于Docker Registry Server的部署,官方给了两个途径:

其一,针对参数不多的情况,可以直接在docker run命令指定;

另一个是通过yaml配置文件,可以一次性配置多个参数。

在本节,笔者将使用第一种方式部署,第二种方式的部署可以参见文末的附文。

代码语言:javascript
复制
> docker run -d \
 -p 5000:5000 \
 -v /usr/local/registry:/var/lib/registry \
 -v /usr/local/certs:/certs \
 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/server.crt \
 -e REGISTRY_HTTP_TLS_KEY=/certs/server.key \
 --restart=always \
 --name registry \
 registry:2

如果没有安装nginx的读者,可运行这条命令:

代码语言:javascript
复制
> docker run -d \
 -p 443:443 \
 -v /usr/local/registry:/var/lib/registry \
 -v /usr/local/certs:/certs \
 -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/server.crt \
 -e REGISTRY_HTTP_TLS_KEY=/certs/server.key \
 --restart=always \
 --name registry \
 registry:2

可以看到,Docker Registry Server启用SSL的时候,用到的是crt、key两个证书文件。

接下来,我们实验一下。

代码语言:javascript
复制
> docker tag busybox registry.iwendao.vip/bosybox:v1.0

最后再推送给Registry。

代码语言:javascript
复制
> docker push registry.iwendao.vip/bosybox:v1.0

查看远程仓库有哪些镜像。

代码语言:javascript
复制
> curl https://registry.iwendao.vip/v2/_catalog

在另外一台主机,重复上述步骤,依然可以成功,说明已经搭建成功了。

四、Authentication的加持

通过对Registry Server的搭建,我们能明显感觉得到,Docker对于安全控制有足够的重视,这在全网HTTPS化的背景下是恰合时宜的做法。

这节是进阶知识,目的是将Docker的安全机制做得更彻底——加上登录校验机制。

很明显,既然是私服,就意味着不是每个人都能提交镜像的,只有凭借登录用户和密码才行。

当然,登录校验机制的前提是有HTTPS协议,否则,用户名和密码都将会明文传输。

Docker的认证机制也有很多实现,可以直接用代理(比如nginx)在Registry之前进行拦截验证,高端的一些的是有Token服务端,引导用户授权登录,实现难度较大。

本文以最简单的htpasswd在实现登录校验机制。关于htpasswd的更多介绍不在本文的范畴,请读者自行查阅之。

如果主机上没有安装此命令工具,可以运行如下命令:

代码语言:javascript
复制
> yum install httpd-tools

因为htpasswd是Apache2的附属工具命令,如果安装了Apache2,此命令理应是可以用的。

如果读者不想安装了,可以直接使用registry镜像,其内置了httpd。

假设密码文件存放在/usr/local/auth目录下面,运行如下命令

代码语言:javascript
复制
> htpasswd -Bbn admin 123456 > /usr/local/auth/passwd

使用registry镜像内置的httpd,如下:

代码语言:javascript
复制
> docker run --entrypoint htpasswd registry:2 -Bbn admin 123456 > /usr/local/auth/passwd

两种方式都能达到同样的目的:在/usr/local/auth/passwd文件中生成用户名和密码。

命令中的admin是用户名,123456即为密码。

查看passwd文件内容:

代码语言:javascript
复制
> cat /usr/local/auth/passwd
admin:$2y$05$/2H8DTcY.1JROHm0MnnK8.UulmbSclib63qTe8FGyWnnE9XWBz3cy

虽然是同样的命令,但在不同的主机,生成的结果并不相同。因此,在主机A上生成的密码文件不能用作主机B上进行认证。

接下来要启动registry容器了:

代码语言:javascript
复制
> docker run -d \
 -p 5000:5000 \
 --restart=always \
 --name registry \
 -v /usr/local/auth:/auth \
 -e REGISTRY_AUTH=htpasswd \
 -e REGISTRY_AUTH_HTPASSWD_REALM=Registry_Realm \
 -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/passwd \
 -v /usr/local/certs:/certs \
 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/server.crt \
 -e REGISTRY_HTTP_TLS_KEY=/certs/server.key \
 registry:2

启动成功后,如果试图直接查看远程仓库有哪些镜像,会提示未认证,如下:

代码语言:javascript
复制
> curl https://registry.iwendao.vip/v2/_catalog{
"errors": [{
"code": "UNAUTHORIZED",
"message": "authentication required",
"detail": [{
"Type": "registry",
"Class": "",
"Name": "catalog",
"Action": "*"
}]
}]}

包括pull,push操作也都受限了。因此,在做操作之前,需要进行登录。

代码语言:javascript
复制
> docker login https://registry.iwendao.vip

既然有登录,当然就有登出了。

代码语言:javascript
复制
> docker logout https://registry.iwendao.vip

五、WEB UI for Registry

当我们把Registry Server搭建好了之后,就意味着要开始管理我们的镜像了。这个时候会发现,并没有一个可视化的工具帮助用户进行镜像管理。

目前已经有很多开源的WEB UI管理工具:

1、docker-registry-frontend。截止到目前(2018年5月),其功能主要是镜像列表查看,标签查看,还未开放镜像删除功能,在GitHub上开源,stars 1k+。

2、docker-registry-web。相比docker-registry-frontend项目,此项目提供了镜像删除功能,还接入了角色系统,功能有了进一步完善,在GitHub上开源,stars 300+。

3、Rancher。这个平台的定位类似Kubernetes,不仅仅是镜像管理这么简单了,对于整个Docker容器管理都是能胜任的。

4、shipyard。很可惜,作者已经没有经历维护了,从GitHub上的stars,不难看出其昔日的辉煌。

关于WEB UI的安装部署就不再赘述了,都有其对应的文档。如果对于镜像管理没有什么特别要求,可以不用WEB UI,或者使用前两个之一。

六、总结

本文详述了Docker Registry私服搭建的过程,总结了来自各类博客,官网的学习资料,帮助读者顺利搭建Docker Registry私服。

附:

1、使用yaml文件启动registry server

假设配置文件的存放路径是:/usr/local/registry/config.yml

编辑其内容,如下:

代码语言:javascript
复制
version: 0.1log:
 fields:
   service: registrystorage:
 cache:
   blobdescriptor: inmemory
 filesystem:
   rootdirectory: /var/lib/registry
   maxthreads: 100
 delete:
   enabled: truehttp:
 addr: 0.0.0.0:5000
 host: https://registry.iwendao.vip
 secret: yoogurt-taxi-123!@#
 headers:
   X-Content-Type-Options: [nosniff]
 tls:
   certificate: /certs/214709594090104.crt
   key: /certs/214709594090104.keyhealth:
 storagedriver:
   enabled: true
   interval: 10s
   threshold: 3

更多配置项,可以访问Configuring a registry

配置文件中的配置项是可以对应到前文中-e参数的环境变量,其规则就是:

1、变量名由大写字母组成;

2、前缀固定加上REGISTRY;

3、将YAML中的配置项的冒号(:)变成了下划线(_)。

比如:

REGISTRY_HTTP_TLS_CERTIFICATE,对应的是http: tls: certificate配置项;

REGISTRY_AUTH_HTPASSWD_PATH,对应的是auth: htpasswd: path配置项。

值得注意的是,配置文件中所涉及的路径都是针对容器内的,这就意味着,在启动registry镜像的时候,需要通过-v参数指定挂载目录。

保存配置文件后,即可启动容器:

代码语言:javascript
复制
> docker run -d -p 5000:5000 --restart=always --name registry \
            -v /usr/local/certs:/certs
            -v /usr/local/registry/config.yml:/etc/docker/registry/config.yml \
            registry:2

2、介绍关于Docker的书籍

  • 《第一本Docker书(修订版)》,当之无愧的Docker启蒙书。零基础入门者可以着重看前五章基础部分,掌握Docker的相关原理及其使用,可用作工具书。读此书,建议跟着内容同步进行实践,入门以后,能够建立起对Docker的兴趣,以便持续学习下去。
  • 《Docker 容器与容器云(第2版)》,知识内容有所进阶。第一部分内容为基础知识,可以快速过一遍。本书对于容器云的概念做了各方面反复的解释,非常精彩,可以吸收之。接下来就是容器编排、部署的内容了,可以加之实践,培养感觉。
  • 《Kubernetes权威指南(第2版)》,当之无愧的Kubernetes入门书籍。读完了《Docker 容器与容器云(第2版)》的Kubernetes部分,再来读此书,会轻松一些。
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-05-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 PHP技术大全 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、从Docker镜像说起
  • 二、先睹为快
  • 三、基于SSL证书改造Registry
  • 四、Authentication的加持
  • 五、WEB UI for Registry
  • 六、总结
  • 附:
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档