文章目录

  • Docker 仓库之单机 Docker Registry
  • 1. 下载 docker registry 镜像
  • 2. 搭建单机仓库
  • 2.1 创建一个授权使用目录
  • 2.2 创建一个用户并生成密码
  • 2.3 验证用户名密码
  • 2.4 启动docker registry
  • 2.5 验证端口和容器
  • 2.6 测试登录仓库
  • 2.7 拉取和上传镜像测试
  • 2.8 查看仓库里的所有镜像
  • 2.9 查看镜像的版本
  • 3.仓库中的镜像删除
  • 3.1 查询具体镜像的digest,用于后面的删除镜像清单
  • 3.2 根据具体镜像的digest删除清单
  • 3.3 垃圾回收


Docker 仓库之单机 Docker Registry

Docker Registry 作为 Docker 的核心组件之一负责镜像内容的存储与分发,客户端的 docker pull 以及 push 命令都将直接与 registry 进行交互,最初版本的 registry 由Python 实现,由于设计初期在安全性,性能以及API 的设计上有着诸多的缺陷, 该版本在 0.9 之后停止了开发,由新的项目 distribution(新的 docker register 被称为 Distribution)来重新设计并开发下一代 registry,新的项目由 go 语言开发, 所有的API,底层存储方式,系统架构都进行了全面的重新设计已解决上一代registry 中存在的问题,2016 年 4 月份 rgistry 2.0 正式发布,docker 1.6 版本开始支持 registry 2.0,而八月份随着 docker 1.8 发布,docker hub 正式启用 2.1 版本registry 全面替代之前版本 registry,新版 registry 对镜像存储格式进行了重新设计并和旧版不兼容,docker 1.5 和之前的版本无法读取 2.0 的镜像,另外,Registry2.4 版本之后支持了回收站机制,也就是可以删除镜像了,在 2.4 版本之前是无法支持删除镜像的,所以如果你要使用最好是大于 Registry 2.4 版本的。

下面将介绍通过官方提供的 docker registry 镜像来简单搭建一套本地私有仓库环境。

1. 下载 docker registry 镜像
root@z1:~# docker pull registry
2. 搭建单机仓库
2.1 创建一个授权使用目录
root@z1:~# mkdir /docker/auth  -p
2.2 创建一个用户并生成密码
root@z1:~# docker run --entrypoint htpasswd registry -Bbn zt 123456 > /docker/auth/htpasswd
2.3 验证用户名密码
root@z1:~# cat /docker/auth/htpasswd 
zt:$2y$05$j8zaYRADx7DJQl70w38RLeQ9oFo4.5q9pYfKDcQoCm8gi0fYHHNPq
2.4 启动docker registry
root@z1:~# docker run -d -p 5000:5000 --restart=always   --name registry1 -v /docker/auth:/auth -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd registry

c4dff6518c1b42dc5174a793d85736f30b5283fe40ee827cd9aa45e67caa437e


root@z1:~#
2.5 验证端口和容器
root@z1:~# ss -ntl
State          Recv-Q          Send-Q                    Local Address:Port                    Peer Address:Port         
LISTEN         0               128                                   *:5000                               *:*
2.6 测试登录仓库

若出错

root@z1:~# docker login 192.168.1.101:5000 
Username: zt
Password: 
Error response from daemon: Get https://192.168.1.101:5000/v2/: http: server gave HTTP response to HTTPS client

root@z1:~# vim /etc/docker/daemon.json 

{
  "registry-mirrors": ["https://n0kig7se.mirror.aliyuncs.com"],
  "insecure-registries":["192.168.1.101:5000"]
}
2.7 拉取和上传镜像测试
root@z1:~# docker images
REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE
linux37-centos7.8-tomcat   8.5.45              faead4af4765        29 hours ago        835MB
registry                   latest              708bc6af7e5e        4 months ago        25.8MB

root@z1:~# docker tag registry:latest  192.168.1.101:5000/zt/registry:latest

一台上传镜像

root@z1:~# docker push 192.168.1.101:5000/zt/registry  
The push refers to repository [192.168.1.101:5000/zt/registry]
a330d9dc14ce: Pushed 
588f0b714a86: Pushed 
c62467775792: Pushed 
9d08b7a37338: Pushed 
7444ea29e45e: Pushed 
latest: digest: sha256:3a8eef8d0a818b9bbb4bd17667253473e2d99935ccbbd37649af6bcaa064cf0d size: 1363

另一台下载

root@z2:~# docker pull 192.168.1.101:5000/zt/registry 
Using default tag: latest
latest: Pulling from zt/registry
486039affc0a: Pull complete 
ba51a3b098e6: Pull complete 
8bb4c43d6c8e: Pull complete 
6f5f453e5f2d: Pull complete 
42bc10b72f42: Pull complete 
Digest: sha256:3a8eef8d0a818b9bbb4bd17667253473e2d99935ccbbd37649af6bcaa064cf0d
Status: Downloaded newer image for 192.168.1.101:5000/zt/registry:latest
2.8 查看仓库里的所有镜像

国内docker 注册表 docker registery_docker

2.9 查看镜像的版本

国内docker 注册表 docker registery_Docker_02

root@z1:~#  curl -u zt  http://192.168.1.101:5000/v2/zt/registry/tags/list
Enter host password for user 'zt':
{"name":"zt/registry","tags":["latest"]}
3.仓库中的镜像删除

因为比较繁琐,所以专门 说一下

3.1 查询具体镜像的digest,用于后面的删除镜像清单
curl  -I -s -XGET --header "Accept: application/vnd.docker.distribution.manifest.v2+json" <protocol>://<私有仓库地址>/v2/<image_name>/manifests/<tag>

如:

root@z1:~# curl  -u zt  -I -s -XGET --header "Accept: application/vnd.docker.distribution.manifest.v2+json" http://192.168.1.101:5000/v2/zt/registry/manifests/latest  | awk '/Docker-Content-Digest/{print $NF}'
Enter host password for user 'zt':

sha256:3a8eef8d0a818b9bbb4bd17667253473e2d99935ccbbd37649af6bcaa064cf0d
3.2 根据具体镜像的digest删除清单
curl  -I -s -XDELETE --header "Accept: application/vnd.docker.distribution.manifest.v2+json" <protocol>://<私有仓库地址>/v2/<image_name>/manifests/<image_digest>

root@z1:~# curl  -u zt -v --silent -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -X DELETE http://192.168.1.101:5000/v2/zt/registry/manifests/sha256:3a8eef8d0a818b9bbb4bd17667253473e2d99935ccbbd37649af6bcaa064cf0d

结果报错,因为没有在创建容器时指定环境变量REGISTRY_STORAGE_DELETE_ENABLED=true

< HTTP/1.1 405 Method Not Allowed
< Content-Type: application/json; charset=utf-8
< Docker-Distribution-Api-Version: registry/2.0
< X-Content-Type-Options: nosniff
< Date: Sat, 23 May 2020 16:15:03 GMT
< Content-Length: 78


< HTTP/1.1 405 Method Not Allowed
< Content-Type: application/json; charset=utf-8
< Docker-Distribution-Api-Version: registry/2.0
< X-Content-Type-Options: nosniff
< Date: Sat, 23 May 2020 16:15:03 GMT
< Content-Length: 78
< 
{"errors":[{"code":"UNSUPPORTED","message":"The operation is unsupported."}]}
* Connection #0 to host 192.168.1.101 left intact

难受,

只好再创建一个容器

docker run -d -p 5001:5000 --restart=always   --name registry2 -v /docker/auth:/auth -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd -e REGISTRY_STORAGE_DELETE_ENABLED=true registry

上传镜像

root@z1:~# docker  tag registry  192.168.1.101:5001/zt/registry:v2
root@z1:~# docker push 192.168.1.101:5001/zt/registry:v2

root@z2:~# docker  push 192.168.1.101:5001/base/centos:7

再查digest

root@z2:~# curl  -u zt  -I -s -XGET --header "Accept: application/vnd.docker.distribution.manifest.v2+json" http://192.168.1.101:5001/v2/zt/registry/manifests/v2  | awk '/Docker-Content-Digest/{print $NF}'
Enter host password for user 'zt':
sha256:3a8eef8d0a818b9bbb4bd17667253473e2d99935ccbbd37649af6bcaa064cf0d

再删除清单

root@z2:~# curl  -u zt -v --silent -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -X DELETE http://192.168.1.101:5001/v2/zt/registry/manifests/sha256:3a8eef8d0a818b9bbb4bd17667253473e2d99935ccbbd37649af6bcaa064cf0d
Enter host password for user 'zt':
*   Trying 192.168.1.101...
* TCP_NODELAY set
* Connected to 192.168.1.101 (192.168.1.101) port 5001 (#0)
* Server auth using Basic with user 'zt'
> DELETE /v2/zt/registry/manifests/sha256:3a8eef8d0a818b9bbb4bd17667253473e2d99935ccbbd37649af6bcaa064cf0d HTTP/1.1
> Host: 192.168.1.101:5001
> Authorization: Basic enQ6MTIzNDU2
> User-Agent: curl/7.58.0
> Accept: application/vnd.docker.distribution.manifest.v2+json
> 
< HTTP/1.1 202 Accepted
< Docker-Distribution-Api-Version: registry/2.0
< X-Content-Type-Options: nosniff
< Date: Sat, 23 May 2020 16:49:47 GMT
< Content-Length: 0
< 
* Connection #0 to host 192.168.1.101 left intact

这里相当于删除镜像的索引,但是真正的空间并没有释放出来,需要整理。

3.3 垃圾回收

回收之前

root@z1:~# docker exec  -it  registry2 sh
/ # du -sh /var/lib/registry/
81.8M	/var/lib/registry/

回收

root@z1:~# docker container exec registry2  /bin/registry garbage-collect /etc/docker/registry/config.yml
base/centos

之后

/ # du -sh /var/lib/registry/
72.6M	/var/lib/registry/