搭建镜像仓库是容器云最核心的步骤之一。基本上最近几年大家都在自己的容器集群中搭建了镜像仓库。作为开源项目,Docker发布的Registry(V1版本)和最后发布了一份Distribution(V2版本)都在解决这个事情。但是不管是当初快速迭代的时候没有仔细考虑,还是迭代速度太快欠下来的技术债,反正是把我们这些实际应用者郁闷了良久。因为真正运营起一套容器云系统之后,会产生大量的镜像,这些镜像的管理就会摆上日程。一般用了没多久,就发现在单机上可以轻易删除镜像的操作在镜像仓库上尽然没有提供。当然在社区发现此问题后在第二个版本中,已经提供了相关的删除方案。当时因为其中细节有趣,我拿出来讲讲,让各位看官能顺着文字知道个前后因果。
在Distribution的代码库中查看ROADMAP.md中有明确的说明删除操作的利弊。首先,镜像内容是存储在一层虚拟文件系统(VFS)之上,由多个文件块(Blobs)、描述清单文件(Manifests)和 标签文件(tags)组成,因为镜像设计是多层的。所以这些文件会互相依赖,在没有确认文件块(Blob)是否被其他镜像使用的情况下,直接删除会让仓库不完整。所以一般的做法是只做删除标记,而不是真删除,通过垃圾回收机制来遍历当前仓库的有向关系图(DAG),然后在删除没有被引用的文件块。
目前Docker Distribution属于维护阶段,已经再把实现标准往OCI社区迁移。所以未来大家应该以OCI镜像作为基准。通过代码补丁(https://github.com/docker/distribution/pull/2076)来实现支持OCI版本的镜像仓库。
如何有效的删除镜像的方法也是有的,大致分为4种方法,请参考:
Reference Counting- 引用计数。
Lock the World GC- 全局垃圾回收。
Generational GC- 两代垃圾回收。
Centralized Oracle- 中央数据库。
每种方案都有利弊。所以在实现过程中一定要多考虑和实践。
领取专属 10元无门槛券
私享最新 技术干货