作者介绍
李昂,腾讯高级开发工程师,次要关注容器存储和镜像存储相干畛域,目前次要负责腾讯容器镜像服务和镜像存储减速零碎的研发和设计工作。
李志宇,腾讯云后盾开发工程师。负责腾讯云 TKE 集群节点和运行时相干的工作,包含 containerd、docker 等容器运行时组件的定制开发和问题排查。
洪志国,腾讯云架构师,负责 TKE 产品容器运行时,K8s,容器网络,mesh 数据面等根底组件研发。
背景
在业务广泛曾经实现容器化的大环境下,不同的业务场景对于容器启动需要也是不同的,在离线计算和一些须要疾速减少计算资源(伸缩组)的在线服务场景下,往往对于容器的启动速度有较高的要求。
在容器启动的整个周期中镜像拉取的工夫往往占据 70% 甚至更多。据统计,某离线计算业务因容器镜像较大,每次扩容上千 Pod 耗时高达 40 分钟。镜像散发成为容器疾速弹性伸缩的次要阻碍。
ImageApparate(幻影)
为了解决这个问题,腾讯云容器服务 TKE 团队开发了下一代镜像散发计划ImageApparate(幻影), 将大规模大镜像散发的速度晋升 5-10倍。
应答既有 Docker 下载镜像模式带来的问题,社区新计划的探讨次要在镜像数据的提早加载(Lazy-Pull)和新镜像格局的设计不再以层为最小单位,而是 chuck 或者镜像内文件自身。
不过,目前看OCI V2
离咱们仍然还很远,以后咱们通过何种形式来应答这类场景呢?
回到问题自身,以后OCI V1
和容器运行时交互逻辑须要先下载残缺镜像能力运行容器,然而容器启动和运行时到底会应用镜像内的多少内容,这篇论文FAST '16[1]统计了 DockerHub 中一些常见的官网镜像在其应用启动后须要读取的数据量,得出的论断是仅有均匀 6.4% 的内容须要读取。也就是说镜像中的大部分内容可能在容器的整个生命周期内基本不须要,那么如果咱们只加载 6% 的数据就能够大幅缩小镜像拉取工夫,从而减速容器启动速度,这也就为后续的优化提供了实践前提。
因而缩小容器启动工夫的重点就在容器的 rootfs 即容器镜像的获取上。
基于此前提,在兼容OCI V1
的框架下,TCR 推出了 ImageApparate(幻影) 容器镜像减速服务。首先间接放论断,在 200 节点且镜像内容占镜像总大小的 5% 到 10%。如上所述,相比于传统的下载全副镜像的形式,ImageApparate 在容器全副启动工夫上都有 5-10倍 的晋升。而且本测试次要并不只是关注容器创立工夫,而是持续测试了从容器启动到业务过程能够提供服务后的总体工夫:
程序读取 500MB 大文件
测试了包含从容器启动后到程序读取 500MB 文件实现后的工夫随机读取 1000 小文件
测试了包含从容器启动后到随即读取 1000个 4k-16k 实现后的工夫执行 python 程序
测试了包含从容器启动后加载 Python 解释器执行一段简略的 python 代码实现后的工夫执行 gcc 编译
测试了包含从容器启动后执行 gcc 编译一段简略 C 代码并运行实现后的工夫
ImageApparate 方案设计
传统模式的问题
自 Docker 公布以来云计算畛域产生了微小的改革,传统虚拟机逐渐被容器代替。Docker 秉持 Build, Ship And Run 的理念杰出的实现了容器运行时和容器镜像的设计,引领整个容器行业。然而随着工夫的推移容器的 Ship And Run 在面对宽泛的用户需要场景中也逐步暴露出一些问题。
传统容器启动和镜像下载方式为:
- 拜访镜像仓库服务获取权限认证以及获取镜像存储地址
- 通过网络拜访镜像存储地址下载全副镜像层并解压
- 依据镜像的层信息应用联结文件系统挂载全副层作为
rootfs
,在此文件系统上创立并启动容器
容器镜像的设计从 Docker 公布至今始终沿用下来,并曾经成为事实标准也就是咱们当初应用的OCI V1
,应用分层的设计大大减少空间占用,利用各类联结文件系统(Aufs、Overlayfs)将每层联结挂载起来造成一个残缺的RootFS
只读根文件系统,容器运行时的写入操作会在联结文件系统的最上层的读写层,十分精美的设计。
然而,开发者和用户对于速度谋求是永无止境的,随着业务上云的宽泛遍及,为了充分发挥云上资源的弹性能力,用户往往须要新扩进去的计算节点能够用最快的速度应用容器化的计算能力(容器启动服务能够承受流量),而此时这个全新节点就须要下载容器镜像全副的层,大大拖慢容器启动速度,在这个场景下容器镜像的分层设计没有失去充沛的利用,齐全生效了。
针对OCI V1
容器镜像格局的一些问题社区也开始有集中的探讨,以后tar
包作为OCI V1
的镜像层散发格局次要有以下问题:
- 不同层之间的内容冗余
- 没有基于文件的寻址拜访能力,须要全副解包后能力拜访
- 没有并发解包能力
- 应用 whiteout 解决文件删除在不同存储类型中转换导致解压效率低下
TCR-Apparate OCI 制品
咱们设计的指标是面向生产级别,在节点上同时反对镜像减速模式和一般模式,为了和失常OCI V1
镜像存储解耦,咱们开发了镜像附加存储IAS
(ImageAttachStorage)联合镜像Manifest
中的内部层类型(Foreign Layer),能够在符合OCI V1
语义下实现减速镜像的制作、上传和下载,继承原有镜像权限的同时,减速后的镜像Manifest
索引以 OCI 制品模式存储在镜像仓库自身的存储中。
在镜像格局方面为了反对按需加载和克服tar
格局之前的一些毛病,ImageApparate 应用了只读文件系统代替了 tar 格局。只读文件系统解决了镜像层内文件寻址能力同时又具备成为Rootfs
牢靠的性能。ImageApparate 依然应用分层的设计在Manifest
内部层中间接指定附件存储地址,附加存储层IAS
在下载镜像时就能够按需挂载。
用户开启镜像减速性能并设置相干规定后,push 镜像后 ImageApparate 会在后盾运行如下流程:
- 用户以任意合乎
OCI V1
接口标准的客户端(包含 Docker)Push 镜像到 TCR 仓库 - TCR 的镜像服务会将用户数据写入到镜像仓库自身的后端存储中,个别为 COS 对象存储。
- TCR 的镜像服务会查看镜像减速规定,如果合乎规定会给 Apparate-client 组件收回 Webhook 告诉,申请转换镜像格局。
- Apparate-client 组件收到告诉后会把 COS 数据写入到
IAS
中,应用特定算法把此镜像的每个 Layer 一一转换为反对 ImageApparate 挂载的 Layer 格局。
因而,对于 TCR 用户来说只须要定义规定标记哪些镜像须要减速,而 CI/CD 的应用形式上没有任何变动,原来的开发模式牵强附会地继承下来。
镜像附加存储 IAS(ImageAttachStorage)
顾名思义,广义的镜像附加存储IAS
是除了自身的镜像后端存储之外的数据存储地址,IAS
既能够和镜像仓库的应用雷同的对象存储,也能够应用 NFS 或者 Lustre。Apparate 中的镜像附加存储除了存储地址外,还蕴含一套插件化的接口(兼容Posix)和镜像层IAS
中的布局(Layout)。IAS
中每个目录代表一个 Layer,这里仍然会应用基于内容寻址(Content Addressable)复用内容雷同层, 只读文件系统文件蕴含了这个原始层中的全部内容,随时能够通过加载元数据索引获取整个目录树。目前 Apparate 应用了腾讯云CFS[2]高性能版作为IAS
的一种实现,高吞吐低提早 CFS 目前和镜像下载场景十分符合。
镜像本地缓存由不同的IAS
附加存储插件本身实现,目前 CFS 实现应用了 FScache 框架作为本地缓存能够主动按页缓存拜访过的在远端存储上的局部数据,依据以后磁盘通过本地缓存能力,无效晋升镜像数据反复拜访的性能和稳定性。
运行时实现
以后 ImageApparate 在节点上应用的IAS
附加存储插件被称之为 Apparate-snapshotter,是通过 containerd 的 proxy-snapshotter 能力实现的。
Apparate-snapshotter 次要负责解析记录在镜像层中的IAS
信息,从而拿到另外数据存储地址,接下来 Apparate-snapshotter 会去数据存储服务中加载近程数据,并在本地提供拜访的 Posix 入口。
比方在 CFS 场景下,会把远端数据 mount 到本地,并把挂载点作为接下来本地拜访的入口。当须要应用远端数据时便由 snapshotter 或内核来提供按需加载的能力。
只读镜像格局
对于反对 Lazy-Pull 的镜像文件零碎来说,只读是十分要害的属性,因为只读文件系统不须要思考数据写入和删除造成的碎片和垃圾回收,能够提前在制作文件系统的时候优化数据块和索引的散布,这样能够大幅提高文件系统的读取性能。
以后 IAS 反对的只读文件系统还减少了基于字母程序排序的目录项索引(directory index),能够大大减速目录项的Lookup
操作。
ImageApparate 在 TCR 中应用形式
创立减速组件
以后 ImageApparate 在 TCR 中为 alpha 性能须要白名单开启。开启减速组件须要抉择对应 CFS 的高性能版,请确认所在地区有此版本 CFS。
创立减速规定,只有规定中匹配的镜像或者 Tag 才会主动减速。之后再向 TCR 推送镜像后能够看到匹配减速规定的镜像会生成后缀为-apparate
的OCI
制品。
在 TKE 集群中创立 TCR 插件时开启镜像减速配置,之后能够给须要减速的集群中节点打标签kubectl label node xxx cloud.tencent.com/apparate=true
,集群中 Pod 的镜像能够依然应用原镜像名字(例如上述test/nginx:1.9),减速插件反对主动选取已减速的镜像来进行挂载。如果镜像已被减速,那么察看 TKE 集群中 Pod 的 image
字段能够看到已被替换为 test/nginx:1.9-apparate。
后续工作
当容器镜像是按需加载后,Layer(层)可能曾经不再是复用的最小单位了, ImageApparate 后续也会摸索基于文件或者块镜像格局以及转换工具以取得更高的性能和效率。在接口侧镜像附加存储IAS
也会反对更多数据源,包含和 TKE P2P 组件的集成,按需加载与 P2P 联合能够更好的应答超大规模镜像加载场景,大大加重源站压力。
内测邀请
ImageApparate(幻影)镜像减速服务现已开启内测,咱们诚挚邀请您参加内测申请 ~ 名额有限,快快辨认下方二维码,中转内测申请页面进行信息提交:
参考资料
[1]FAST '16: https://www.usenix.org/confer...
[2]CFS: https://console.cloud.tencent...
[3]Image Manifest V 2, Schema 2: https://docs.docker.com/regis...
[4]EROFS: A Compression-friendly Readonly File System for Resource-scarce Devices: https://www.usenix.org/system...
【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!