Harbor镜像删除回收

Harbor镜像删除回收

问题原因

Harbor私有仓库运行一段时间后,仓库中存有大量镜像,会占用太多的存储空间。直接通过Harbor界面删除相关镜像,并不会自动删除存储中的文件和镜像。需要在UI上删除完毕之后,在执行垃圾回收命令,进行存储空间清理和回收。

Harbor镜像占用过多磁盘

docker镜像是分层的,registry在存储镜像的时候,将docker镜像分成了2部分:

  1. 镜像元数据(manifests),存储在docker/registry/v2/repositories目录中,在这里会看到registry上的项目、项目中的镜像、镜像到Layer的索引信息。

  2. blobs,存储在docker/registry/v2/blobs目录中,在这里按00-ff分目录存储了所有镜像的layer。

如果有2个镜像使用了同一个基础镜像,那么在registry上存储的时候,blobs只有一份数据,而镜像元数据中两个镜像各自的索引都有一部分layer指向相同的layer。

举个例子。

初始状态,A、B两个镜像,都是基于layer a所做的镜像;A引用a,b,B引用a,c。

A -----> a <----- B    \--> b     |         c <--/

之后删掉B镜像(通过Harbor的web,或者通过api)

A -----> a     B    \--> b         c

此时layer c实际已经没人用了,但是registry在删除B镜像时,只是会删除B的元数据,并不会主动删除layer c。

layer c就是无人照看的孤儿待回收的垃圾,需要GC。

果然 /data/registry/docker/registry这个目录占了600多GB,我们抓到了真凶。

GC过程

registry的GC使用“标记-清理”法。

  • 第一步,标记。registry扫描元数据,元数据能够索引到的blob标记为不能删除。

  • 第二步,清理。registry扫描所有blobs,如果改blob没有被标记,则删除它。

跟JVM老年代的GC是不是很像?

registry GC也是stop-the-world。将来registry会在起后台任务自动回收,不再需要手工去启动GC。

GC回收

使用API,删掉镜像,UI上确实看不见了,但是我们发现磁盘并未释放,还需要回收GC。

查看harbor相关的9个容器。

docker ps
图片

进入镜像存储位置,我们使用 docker exec -it 3501 /bin/bash,进到registry这个容器里

图片

df -h查看剩余空间

图片

先dry-run一下,看看待删除的报告,此步不会真正执行删除。

registry garbage-collect --dry-run  /etc/registry/config.yml

可以清理的blobs还是挺多的。去掉dry-run,实际跑一下

registry garbage-collect  /etc/registry/config.yml

GC效果还可以,清理出来500GB左右的空间。

这里如果执行删除时提示对/storage/docker/registry/v2/blobs/sha256/../data 没有权限,在容器外执行

chmod -R 777 /data/registry/docker/registry/v2

给整个目录授权即可

你可能感兴趣的:(Harbor镜像删除回收)