今天,一起吐槽容器镜像中那些让人一言难尽的事情
发布日期:2021-06-30 18:33:06 浏览次数:2 分类:技术文章

本文共 2054 字,大约阅读时间需要 6 分钟。

 

凌云时刻 · 技术

导读:虽然选择 layer 的设计是为了让不同的应用软件镜像能够共用同一部分基础系统,达到节省存储和节省传输的目的,但是在实践中用户们也逐渐发现了它带来的难以 workaround 的问题。

作者|Liu,Bo

来源|云巅论剑

前言

现如今容器生态大受欢迎有许多原因,其中一个就是应用部署上的优秀体验,容器镜像的出现是这种体验能够成为现实的一个基础。

简要回顾一下容器镜像,概括为几点:

1. 它提供了一个应用软件运行的完整操作系统包,是不可变基础设施的一部分,其格式(https://docs.docker.com/storage/storagedriver/)如下图所示。

2. 镜像中一个重要的概念是 layer,引用 docker documentation(https://docs.docker.com/storage/storagedriver/)中的介绍,"Each layer is only a set of differences from the layer before it. The layers are stacked on top of each other."

3. 一个容器镜像是由一个或多个 layer 组成的。

4. 容器镜像是存储在 registry 中的,诸如 Docker Hub(https://hub.docker.com/)

但今天我们要一起来吐槽一下容器镜像。

首次启动中大型镜像很慢

第一次运行时总是需要等上几分钟,这是因为在正式启动一个容器之前,还需要一些准备工作:

1. 从 registry 下载镜像,包含了镜像的所有 layers,比如上图的镜像"rust:latest"中包含 6 layers。

2. 把镜像 layers 一个接一个地解压到本地 filesystem 中。

3. 最后用 overlayfs 将这些 layer 组合为一个 mount point 作为容器的 rootfs。

4. 启动容器。

其中,当启动一个庞大的镜像时,最耗时的是第一步中的下载镜像,但因为单一 layer 是一个整体,对同一个 layer 无法并行下载,与此同时镜像 size 很大通常意味着包含的 layer size 也很大,所以大部分时间都花在了网络传输上。

去重低效

如果大家关注过镜像 base layer,比如上图中的 CentOS 和 Ubuntu,其中的目录结构是相同的标准操作系统根分区结构,内容也是类似的,那么我们很自然地可以想到,在 registry 中存储的时候会将他们去重(Deduplication)吗?

对于上图这种情况,registry 现在不会做去重,原因仍是“单一 layer 是一个整体”,registry 的去重是基于 layer 的 digest id 的,即如果两个不同镜像使用了同一个 layer,那么在 registry 上只存一个 layer。

对删除和链接的处理

先说删除,当对 lower layer 中的一个 file 做 unlink 时,会在 upper layer 发生什么?

现在的逻辑是在 upper layer 添加一个特殊的 white-out empty file 来表示被 unlink 的 file,以达到最终视图上的 unlink 效果。

“你说你一个没点,完事我们还得搭一个是不?”

想象一下,如果想删掉一个 password file,这个 white-out 做法会带来什么后果?

再说 hardlink,当对 lower layer 中的一个 file 做 hardlink 时,会在 upper layer 发生什么?当前采取了一种笨拙的做法,即把 lower layer file 拷贝一份到 upper layer,再添加对应的 hardlink。当这个 file size 很大时,那么浪费的存储空间就相当可观了。

安全审计不完整

再说一个安全审计上的问题,因为镜像每一个 layer 都有对应的 digest id,在镜像下载之后可以对 layer 进行校验,但当把镜像 layers 一个接一个地解压到本地 filesystem 中之后呢?我们没有办法再去校验了,因为本质上解压后的 filesystem 目录和镜像的 layers 是两种不同的形态了,所以运行时的安全审计是缺失的。

成也 layer,败也 layer

我们回过头来看,上面的问题除了最后的安全审计,其它的原因都可以归结为“以 layer 为基本单位的镜像格式”。所以,虽然选择 layer 的设计是为了让不同的应用软件镜像能够共用同一部分基础系统,达到节省存储和节省传输的目的,但是在实践中用户们也逐渐发现了它带来的难以 workaround 的问题。

欲知详情,且听下次分解。

END

往期精彩文章回顾

长按扫描二维码关注凌云时刻

每日收获前沿技术与科技洞见

转载地址:https://lingyun.blog.csdn.net/article/details/111465990 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:面向生态合作伙伴的实践分享回顾
下一篇:云原生网络性能优化:service mesh 篇

发表评论

最新留言

哈哈,博客排版真的漂亮呢~
[***.90.31.176]2024年04月26日 16时29分10秒