page contents

Docker Registry的最强实践

一个registry是一个存储和内容交付系统,其中维护着若干命名的Docker镜像,这些镜像有不同的标记版本。(例如:有一个镜像名字叫 hello/world,它有两个tags分别是2.0和2.1) 用户通过使用 docker push 和 docker pull 命令与 registry 进行交互。(例如:docker pull registry-1.docker.io/hello/world:2.1)cc

attachments-2020-11-2LuK1gvl5fa60257f0425.png

1. 理解Registry

一个registry是一个存储和内容交付系统,其中维护着若干命名的Docker镜像,这些镜像有不同的标记版本。(例如:有一个镜像名字叫 hello/world,它有两个tags分别是2.0和2.1)

用户通过使用 docker push 和 docker pull 命令与 registry 进行交互。(例如:docker pull registry-1.docker.io/hello/world:2.1)

A registry is a storage and content delivery system, holding named Docker images, available in different tagged versions.
Users interact with a registry by using docker push and pull commands.

前面说了,registry是一个存储系统,它存储的是Docker镜像。那么,镜像到底存到哪里呢?存储本身委托给驱动程序。默认的存储驱动程序是本地posix文件系统,还支持其它基于云的存储驱动程序,例如 Aliyun OSS

由于保护对托管映像的访问至关重要,因此Registry本身支持TLS和基本身份验证。

1.1. 理解镜像命名

docker pull ubuntu 指示docker从官方Docker Hub中拉取一个名字叫ubuntu的镜像。这条命令其实是docker pull docker.io/library/ubuntu的简写

docker pull myregistrydomain:port/foo/bar 指示docker拉取位于myregistrydomain:port的镜像foo/bar

1.2. 用例

运行你自己的Registry是与CI/CD系统集成并对其进行补充的绝佳解决方案。在典型的工作流程中,对源版本控制系统的提交将触发在CI系统上的构建,如果构建成功,则将新镜像推送到你的Registry。然后,来自Registry的通知将触发在暂存环境上的部署,或者通知其它系统有一个新镜像可用。

如果要在大型计算机集群上快速部署新镜像,它也是必不可少的组件。

这也是在隔离的网络中分发镜像的最佳方法。


2. 部署一个registry server

# Run a local registry
docker run -d -p --restart=always --name registry registry:2

2.1. Copy an image from Docker Hub to your registry

你可以从Docker Hub上拉取一个镜像,并把它推送到你自己的Registry上。下面的例子中,从Docker Hub上拉取镜像ubuntu:16.04,并将其重新打标记为my-ubuntu,然后将其推送到本地registry,最后,再将ubuntu:16.04和my-ubuntu删除。

# 1. Pull the ubuntu:16.04 image from Docker Hub
docker pull ubuntu:16.04
# 2. Tag the image as localhost:5000/my-ubuntu
#   (注意,当tag的第一部分是主机名和端口时,push时Docker会将其解释为registry的位置)
docker tag ubuntu:16.04 localhost:5000/my-ubuntu
# 3. Push the image to the local registry running at localhost:5000
docker push localhost:5000/my-ubuntu
# 4. Remove the locally-cached ubuntu:16.04 and localhost:5000/my-ubuntu images, so that you can test pulling the image from your registry. This does not remove the localhost:5000/my-ubuntu image from your registry.
docker image remove ubuntu:16.04
docker image remove localhost:5000/my-ubuntu
# 5. Pull the localhost:5000/my-ubuntu image from your local registry
docker pull localhost:5000/my-ubuntu 

停止本地registry

# stop the registry
docker container stop registry
# remove the container
docker container stop registry && docker container rm -v registry


3. 基本配置

为了配置container,可以给docker run命令指定额外的选项参数

# 自动重启registry
# -p选项的值,第一个是主机端口,第二个是容器端口。在容器中,registry默认监听端口是5000
docker run -d -p 5000:5000 --restart=always --name registry registry:2
# 自定义存储位置
docker run -d -p 5000:5000 --restart=always --name registry -v /mnt/registry:/var/lib/registry registry:2

3.1. 运行一个外部可访问的registry

运行一个仅在本地主机上可访问的registry没有什么用处,为了使你的registry可供外部主机访问,必须首先使用TLS保护registry。

下面是一个将registry作为服务来运行的例子:

首先,获得一个证书

假设你的registry的URL是https://myregistry.domain.com/,同时假设的DNS,路由和防火墙设置允许通过端口443访问registry的主机,再假设你已经从CA那里获得一个证书。

那么,接下来

创建一个certs目录

从CA那里复制.crt和.key文件到certs目录,假设分别重命名为domain.crt和domain.key

重启registry,将其指向使用TLS证书

docker run -d 
 --restart=always 
 --name registry 
 -v "$(pwd)"/certs:/certs 
 -e REGISTRY_HTTP_ADDR=0.0.0.0:443 
 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt 
 -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key 
 -p 443:443 
 registry:2 

现在Docker客户端就可以通过registry的外网地址进行pull和push了

docker pull ubuntu:16.04
docker tag ubuntu:16.04 myregistry.domain.com/my-ubuntu
docker push myregistry.domain.com/my-ubuntu
docker pull myregistry.domain.com/my-ubuntu

将registry作为一个服务运行

与独立容器相比,swarm services具有多个优点。它们使用声明式模型,这意味着你定义了所需的状态,而Docker则将服务保持在该状态。服务提供了自动负载平衡扩展,并具有控制服务分配的能力以及其他优势。服务还允许你秘密存储敏感数据,例如TLS证书。

下面这个例子将registry作为单副本服务启动,可以在端口80上的任何群集节点上访问该registry,并假定使用的是与前面示例相同的TLS证书。

# 首先,保存TLS证书和key作为secret
docker secret create domain.crt certs/domain.crt
docker secret create domain.key certs/domain.key
# 接下来,将你想要在上面允许registry的node添加一个标签
docker node update --label-add registry=true node1
# 再接着,创建一个服务,并授权它可以访问两个secret,并将其限制为仅在标签为registry=true的节点上运行
docker service create 
 --name registry 
 --secret domain.crt 
 --secret domain.key 
 --constraint 'node.labels.registry==true' 
 --mount type=bind,src=/mnt/registry,dst=/var/lib/registry 
 -e REGISTRY_HTTP_ADDR=0.0.0.0:443 
 -e REGISTRY_HTTP_TLS_CERTIFICATE=/run/secrets/domain.crt 
 -e REGISTRY_HTTP_TLS_KEY=/run/secrets/domain.key 
 --publish published=443,target=443 
 --replicas 1 
 registry:2

现在你可以在任何swarm节点的443端口上访问服务。Docker会将请求发送到运行该服务的节点。


4. 文档

# 启动registry
docker run -d -p 5000:5000 --name registry registry:2
# 从Docker Hub上拉取镜像
docker pull ubuntu
# 给镜像打tag
docker image tag ubuntu localhost:5000/myfirstimage
# 推送至你自己的registry
docker push localhost:5000/myfirstimage
# 再次从你自己的registry拉取镜像
docker pull localhost:5000/myfirstimage
# 停止registry并删除所有数据
docker container stop registry && docker container rm -v registry

https://docs.docker.com/regis...

https://docs.docker.com/regis...

attachments-2020-11-mQHBxZtD5fa6026fcbae6.jpg来源:https://www.cnblogs.com/cjsblog/p/12246286.html

  • 发表于 2020-11-07 10:08
  • 阅读 ( 441 )
  • 分类:操作系统

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
Pack
Pack

1135 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1478 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章