前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >清理镜像库空间的一个思路

清理镜像库空间的一个思路

作者头像
崔秀龙
发布2020-11-04 16:15:01
9690
发布2020-11-04 16:15:01
举报
文章被收录于专栏:伪架构师

最近遇到一个有趣的状况,某镜像仓库占用了大量的磁盘空间。通常要解决这种问题,给 Registry 发删除指令,并进行 GC 就可以了。然而很多时候,所有镜像都正常,在删除多个 Tag 甚至是 Repository 之后,问题仍然没能缓解,原理也很容易理解——删除的镜像虽然大,可能只是复用了一些比较大的层,删除镜像并不会真正的发出,所以还是需要对镜像库的存储进行更多的了解,进行进一步的统计,在层一级对镜像仓库进行分析,才能获取更有效的途径。

Docker Registry Exporter

首先发现了一个有意思的项目:DockerRegistryExporter,这个项目是一个 Python 编写的 Prometheus Exporter,其中包含四个 Gauge:

-repository_tags_total:按镜像计算的 Tag 数量。 -repository_revisions_total:按镜像计算的版本数量。 -repository_tag_layers_total:以镜像和 Tag 计算的 Layer 数量。 -repository_tag_size_bytes:以镜像和 Tag 计算的文件尺寸。

该镜像使用挂卷的方式,直接对镜像库文件系统进行扫描,例如:

代码语言:javascript
复制
containers:
- image: registry:2
  name: registry
  ports:
  - containerPort: 5000
    name: http
    protocol: TCP
  readinessProbe:
    httpGet:
      path: /
      port: 5000
    initialDelaySeconds: 1
    timeoutSeconds: 1
  livenessProbe:
    httpGet:
      path: /
      port: 5000
    initialDelaySeconds: 1
    timeoutSeconds: 1
  volumeMounts:
  - name: storage
    mountPath: /var/lib/registry

- image: skyuk/docker-registry-exporter:v1.0.0
  name: registry-exporter
  args:
    - /var/lib/registry/docker/registry/v2
  ports:
  - containerPort: 8080
    name: http
    protocol: TCP
  volumeMounts:
  - name: storage
    mountPath: /var/lib/registry

volumes:
- name: storage
  persistentVolumeClaim:
    claimName: registry

通过Sidecar的部署方式和Registry容器共享文件系统,可以定时输出监控指标,例如:

代码语言:javascript
复制
$ curl http://registry:8080
# HELP repository_tag_size_bytes Size of eachtag
# TYPE repository_tag_size_bytes gauge
repository_tag_size_bytes{repository="org/image1", tag="0.3.0"} 162749959.0
repository_tag_size_bytes{repository="org/image2", tag="1009140546"} 226608092.0
...

然而这并不能满足我的要求,关于引用的数据并没有体现,另外前面也提到,我们需要比较精确地获得镜像版本、Tag 和 Layer 之间的引用关系以及各自的尺寸,用 PromQL 有点别扭。

我做了个奇怪的事情

这并不是一个很常见的需求,只能是一个清理之前的准备动作,目前看来我需要找到的就是引用数量少、但是体量比较大的 Layer,但是谁知道以后会需要什么新的标准呢?干脆把这些东西写入到数据库里算了,把这些东西写入数据库之后,还掌握 SQL 这样传统才艺的程序员就可以随便搞一搞其它条件了。

关于镜像仓库的一点基础

镜像库根目录中有两个子目录:blobs 中保存了所有的 Layer,而 repositories 中则是以镜像为单位保存的元数据。

首先看看镜像的数据

代码语言:javascript
复制
$ tree/org/repo/gameserver
.
├── revisions
│   └── sha256
│       └── ecfb0206e8b...
│           └── link
└── tags
    └── latest
        ├── current
        │   └── link
        └── index
            └── sha256
                └── ecfb020...
                    └── link

每个镜像的 Manifests 有两个目录,分别承载的是版本和 Tag,正常来说 Tag 和版本是一致的,但实际上在一些特别情况下,这两个数量可能是不一致的,就会导致只用 Tag 已经无法拉取该镜像,属于一种半孤立状态,应该说是需要清除的。

两个目录中的link文件中包含的是一个哈希码,可以使用这个哈希码在_layers中查找到该镜像的版本/tag 对应的清单层,使用这个字符串可以在根_layer中查到对应的目录,目录下面的data文件中就是每个层的具体数据,对于清单层,其中会是一个json字符串:

代码语言:javascript
复制
{
    "schemaVersion": 2,
    "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
    "config": {
        "mediaType": "application/vnd.docker.container.image.v1+json",
        "size": 2694,
        "digest": "sha256:7929bcd70e47d3726d55a870b2ca11c25792758f3ba8b4ff136811f0809af636"
    },
    "layers": [
        {
            "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
            "size": 2546278,
            "digest": "sha256:3db1cceb1cccb362634e914bfe76d329c64d148262a9e139a046337d82e1aeec"
        },
        {
            "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
            "size": 32,
            "digest": "sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1"
        }
    ]}

这里看到清单中包含两个主节点,configlayer,至此,一个镜像是由三种不同的层构成的:清单、Config 和 Layer。我们关注的主要是 Layer,其中的 data 文件包含的就是各层的具体内容,清单和 Config 中都是文本,Layer 通常都是二进制的,也是我们要关注的主要内容。

接下来的问题就顺理成章了,把 Repository、Tag、Revision 以及 Layer 的关系建立起来,随便用个 SQL 语句,就能够按照具体需求对“引用少、尺寸大”的 Layer 进行过滤了。

相关链接

  • Docker Registry Exporterhttps://github.com/sky-uk/docker-registry-exporter
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-11-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 伪架构师 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Docker Registry Exporter
  • 我做了个奇怪的事情
    • 关于镜像仓库的一点基础
    • 相关链接
    相关产品与服务
    容器镜像服务
    容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档