Deploy a registry server
Use volumes
Use bind mounts
Garbage collection
HTTP API V2
Definition of: repository
导言
本文介绍如何在本地部署docker私有仓库,涉及到registry镜像(registry:2)、volume与bind(bind mount)、仓库的http api、仓库的垃圾回收等知识点。
1 | Server: Docker Engine - Community |
一. 创建一个volume
1 | #创建一个名为registry-vol的卷 |
与bind直接使用宿主的文件系统不同,volume由docker直接生成与管理,它跨系统、跨平台、易于备份与迁移。
二. 创建私有仓库
1 | #从docker hub拉取私有仓库的镜像 |
这里额外提供一个案例:
1 | #创建容器 |
需要注意的是:
- 第一个案例中的
-e REGISTRY_STORAGE_DELETE_ENABLED=true
,在第二个案例中可以通过在配置文件中添加registry:storage:delete:enabled:true
来替代。 - 虽然-v的功能和–mount相似,但推荐使用较为冗长的–mount,因为它简单易懂。
至此,私有仓库已经创建成功,我们可以通过docker提供的api确认一下:
1 | #访问私有仓库的接口 |
三. 推送镜像到私有仓库
1 | #将本地镜像hello:latest(该镜像来自上个笔记)添加一个标签,其中localhost:5000对应私有仓库地址 |
repository指的是一组Docker镜像。 repository可以通过推送到仓库服务来分享。同一个repository中的不同镜像可以通过标签来归类。
hello镜像推送成功后,私有仓库会生成一个名为hello的repository。这个repository会存储各个tag的hello镜像,例如:hello:v1、hello:v2。
四. 搭建私有仓库的管理后台
对于私有仓库,docker只提供了http api的接口文档,它并未提供官方的管理后台。为了方便学习,采用第三方提供的Joxit/docker-registry-ui。
1 | #拉取镜像 |
这里的REGISTRY_UR并不是 http://localhost:5000 ,因为容器和本机的localhost并不等价。通过以下方式取得在对应的docker网络中本机的局域网地址:
1 | #后台容器采用默认的bridge网络, 查询该网络的详细属性 |
通过浏览器访问 http://localhost:5050 ,可以通过管理后台对私有仓库进行管理了。
五. 删除私有仓库中的hello
通过后台页面,找到删除功能并不复杂。但是即使删除成功,后台的repository列表中依然存在hello(虽然再也无法拉取镜像)。这并不是管理后台的问题,下面通过接口确认:
1 | #通过docker的http api查看存储的repository列表 |
查阅资料,发现官方指出:
- 目前的api只能删除repository中的镜像,而不能删除repository本身。
- 私有仓库提供的api只能删除manifests(清单)和layers(层)。所以repository一旦被创建,将无法通过api将其彻底删除。
- api中的删除操作会移除对目标的引用,使得其可以被垃圾回收。同时让它无法被api访问。
- 垃圾回收会清理不被任何manifests(清单)引用的数据块,数据块包含layers(层)或manifests(清单)。当manifests(清单)被删除时,它指向的layers(层)中没被其他清单引用的也会被删除。
也就是说之前通过api删除的,只是repository下的hello:latest镜像,而repository本身依然存在。
想要删除repository,需要通过一种stop-the-world(清理期间上传中的镜像可能会被误删)的方式:
1 | #查找私有仓库的容器ID |