在私有registry仓库的场景中,对于私有镜像的升级操作是一个比较常见的操作。然而在我们升级私有镜像、并push到私有仓库后,升级前的镜像也就失去了它存在的意义;而随着时间的积累,旧镜像将会越来越多,旧镜像的数据有可能会占用大量磁盘空间。为了解决此问题,我们需要对私有仓库中的旧镜像进行清理以释放空间。
1 获取到镜像的Digest
curl -I -H "Accept: application/vnd.docker.distribution.manifest.v2+json" localhost:5000/v2/$ImageName/manifests/$tag
2 通过DELETE API删除镜像manifest
curl -i -X DELETE localhost:5000/v2/$ImageName/manifests/$Digest
//or
curl -lv -X DELETE http://127.0.0.1:5000/v2/$ImageName/manifests/$Digest
3 垃圾回收并搜集需要回收的layers
docker exec -it registry registry garbage-collect /etc/docker/registry/config.yml | grep "blob eligible for deletion:"
其中registry容器的名字就是“registry”,也就是docker exec -it "$container"的参数"$container"。
上面一步做了两件事情:(1)垃圾回收;(2) 垃圾回收时会打印出需要清理的layers,过滤出这些layers并搜集起来
如果只是希望看到有哪些可回收垃圾,可以增加如下参数,这样做就不会真正执行清理动作:
docker exec -it registry registry garbage-collect --dry-run /etc/docker/registry/config.yml | grep "blob eligible for deletion:"
4 查找并删除第[3]步搜集的需要清理layers
在上面一步中已经搜集了需要清理的layers,这一步就要搜索所有的$repositories/*/_layers/sha256/目录,一旦有需要清理的目录,我们就将其删除掉。
在registry容器的配置文件/etc/docker/registry/config.yml中增加uploadpurging条目并使能delete选项,其作用是定时清理repositories/$container/_uploads/目录下的内容:
storage:
delete:
enabled: true
filesystem:
......
maintenance:
uploadpurging:
enabled: true
age: 24h
interval: 12h
dryrun: false
上面uploadpurging几个参数的说明:
age: 清理的对象是存在超过age时间的文件,这个时间可以自己配置(注意单位,h表示小时、m表示分钟)
interval:清理的频度,这个时间可以自己配置(注意单位,h表示小时、m表示分钟)
dryrun:如果配置为true则只是统计并不真正执行清理,所以我们这里配置为false
假设我们要删除docker-hub下载的golang:1.10-alpine镜像,可以参考如下示例步骤。
upload目录的清理工作在registry容器运行通过registry容器的配置文件来搞定,这里不多说,下面主要啰嗦一下手动清理的部分。
sh-4.3# curl -I -H "Accept: application/vnd.docker.distribution.manifest.v2+json" localhost:5000/v2/golang/manifests/1.10-alpine
HTTP/1.1 200 OK
Content-Length: 1364
Content-Type: application/vnd.docker.distribution.manifest.v2+json
Docker-Content-Digest: sha256:565ad18e011a417bb20dae206b9aff68d4c1daf84c58b84f30f512b74c57f0c7
Docker-Distribution-Api-Version: registry/2.0
Etag: "sha256:565ad18e011a417bb20dae206b9aff68d4c1daf84c58b84f30f512b74c57f0c7"
X-Content-Type-Options: nosniff
Date: Tue, 09 Jul 2019 07:16:20 GMT
通过上面的接口命令我们查询到golang:1.10-alpine镜像的Digest为:
Docker-Content-Digest: sha256:565ad18e011a417bb20dae206b9aff68d4c1daf84c58b84f30f512b74c57f0c7
curl -i -X DELETE localhost:5000/v2/golang/manifests/sha256:565ad18e011a417bb20dae206b9aff68d4c1daf84c58b84f30f512b74c57f0c7
上面的操作只是删除了repositories/golang/_manifests/目录下的相关内容,blob目录和repositories/golang/_layer/目录都未删除。
首先,进行垃圾回收、搜集需要清理的layers
docker exec -it registry registry garbage-collect /etc/docker/registry/config.yml | grep "blob eligible for deletion:" | awk -F ":" '{print $3}'
945d978b4f197a284150a58bc63f99c562080d67d3eb5ba8b97945b194d58235
e6618267e614431da67d69a1ee7f7c841a6140611b528592cf14af73e6c6c638
51d6d4c96fd308155315fc8f535227125342b8466a665fbf44eb87bd350de277
565ad18e011a417bb20dae206b9aff68d4c1daf84c58b84f30f512b74c57f0c7
6c40cc604d8e4c121adcb6b0bfe8bb038815c350980090e74aa5a6423f8f82c0
74ebde557090d8e97f2efab58320263740ce7a3b2e56db39ea491a5f011afb7c
7b53e4a31d219f1d5f1b3e42b8cafd1e8f63375399fac2f83fcd092be6a548c5
其次,查找所有的layers目录,依次删除上面获取的layers,参考代码如下所示:
for layer in $layers
do
dic=$(find $repositories/*/_layers/sha256 -name $layer)
rm $dic
done