容器运行时从docker到containerd的迁移

容器运行时(ContainerRuntime),运行于kubernetes(k8s)集群的每个节点中,负责容器的整个生命周期。其中docker是目前应用最广的。随着容器云的发展,越来越多的容器运行时涌现。为了解决这些容器运行时和k8s的集成问题,在k8s1.5版本中,社区推出了CRI(ContainerRuntimeInterface,容器运行时接口)(如图1所示),以支持更多的容器运行时。

Kubelet通过CRI和容器运行时进行通信,使得容器运行时能够像插件一样单独运行。可以说每个容器运行时都有自己的优势,这就允许用户更容易选择和替换自己的容器运行时。

图1 CRI在kubernetes中的位置

一、CRI&OCI

CRI是kubernetes定义的一组gRPC服务。Kubelet作为客户端,基于gRPC框架,通过Socket和容器运行时通信。它包括两类服务:镜像服务(ImageService)和运行时服务(RuntimeService)镜像服务提供下载、检查和删除镜像的远程程序调用。运行时服务包含用于管理容器生命周期,以及与容器交互的调用(exec/attach/port-forward)的远程程序调用。

如图2所示,dockershim,containerd和cri-o都是遵循CRI的容器运行时,我们称他们为高层级运行时(High-levelRuntime)

图2 常用的运行时举例

OCI(OpenContainerInitiative,开放容器计划)定义了创建容器的格式和运行时的开源行业标准,包括镜像规范(ImageSpecification)和运行时规范(RuntimeSpecification)

镜像规范定义了OCI镜像的标准。如图2所示,高层级运行时将会下载一个OCI镜像,并把它解压成OCI运行时文件系统包(filesystembundle)。

运行时规范则描述了如何从OCI运行时文件系统包运行容器程序,并且定义它的配置、运行环境和生命周期。如何为新容器设置命名空间(namepsaces)控制组(cgroups),以及挂载根文件系统等等操作,都是在这里定义的。它的一个参考实现是runC。我们称其为低层级运行时(Low-levelRuntime)。除runC以外,也有很多其他的运行时遵循OCI标准,例如kata-runtime。

二、ContainerdvsCri-o

目前docker仍是kubernetes默认的容器运行时。那为什么会选择换掉docker呢?主要的原因是它的复杂性

如图3所示,我们总结了docker,containerd以及cri-o的详细调用层级。Docker的多层封装和调用,导致其在可维护性上略逊一筹,增加了线上问题的定位难度(貌似除了重启docker,我们就毫无他法了)。Containerd和cri-o的方案比起docker简洁很多。因此我们更偏向于选用更加简单和纯粹的containerd和cri-o作为我们的容器运行时

图3 容器运行时调用层级

我们对containerd和cri-o进行了一组性能测试,包括创建、启动、停止和删除容器,以比较它们所耗的时间。如图4所示,containerd在各个方面都表现良好,除了启动容器这项。从总用时来看,containerd的用时还是要比cri-o要短的。

图4 containerd和crio的性能比较

如图5所示,从功能性来讲,containerd和cri-o都符合CRI和OCI的标准。从稳定性来说,单独使用containerd和cri-o都没有足够的生产环境经验。但庆幸的是,containerd一直在docker里使用,而docker的生产环境经验可以说比较充足。可见在稳定性上containerd略胜一筹。所以我们最终选用了containerd

图5 containerd和cri-o的综合比较

三、DeviceMappervs.Overlayfs

容器运行时使用存储驱动程序(storagedriver)来管理镜像和容器的数据。目前我们生产环境选用的是DeviceMapper。然而目前DeviceMapper在新版本的docker中已经被弃用,containerd也放弃对DeviceMapper的支持。

当初选用DeviceMapper,也是有历史原因的。我们大概是在2014年开始k8s这个项目的。那时候Overlayfs都还没合进kernel。当时我们评估了docker支持的存储驱动程序,发现DeviceMapper是最稳定的。所以我们选用了DeviceMapper。但是实际使用下来,由DeviceMapper引起的docker问题也不少。所以我们也借这个契机把DeviceMapper给换掉,换成现在containerd和docker都默认的Overlayfs

从图6的测试结果来看,Overlayfs的IO性能比DeviceMapper好很多。Overlayfs的IOPS大体上能比DeviceMapper高20%,和直接操作主机路径差不多。

图6 后端存储文件系统性能比较

四、迁移方案

最终,我们选用了containerd,并以Overlayfs作为存储后端的文件系统,替换了原有的docker加DeviceMapper的搭配。那迁移前后的性能是否得到提升呢?我们在同一个节点上同时起10,30,50和80的pod,然后再同时删除,去比较迁移前后创建和删除的用时。从图7和图8可知,containerd用时明显优于docker。

图7 创建pod的用时比较

图8 删除pod的用时比较

五、迁移挑战

从docker+DeviceMapper到containerd+Overlayfs,容器运行时的迁移并非易事。这个过程中需要删除DeviceMapper的thin_pool,全部重新下载用户的容器镜像,全新重建用户的容器。

如图9所示,迁移过程看似简单,但是这对于已运行了5年且拥有**100K+**光怪陆离的应用程序的集群而言,如何将用户的影响降到最低才是最难的。Containerd在我们生产环境中是否会出现“重大”问题也未可知。

图9 具体的迁移步骤

针对这些挑战,我们也从下面几个方面做出了优化,来保证我们迁移过程的顺利进行

01 多样的迁移策略

最基本的是以容错域(FaultDomain,fd)为单元迁移。针对我们集群,是以rack(机架)为单元(rackbyrack)迁移。针对云原生(cloud-native)且跨容错域部署的应用程序,此升级策略最为安全有效。针对非云原生的应用程序,我们根据其特性和部署拓扑,定制了专属他们的升级策略,例如针对Cassini的集群,我们采用了jenga(层层叠)的升级策略,保证应用程序0宕机。

02 自动化的迁移过程

以rackbyrack的策略为例,需要等到一个rack迁移完成以后且客户应用程序恢复到迁移前的状态,才能进行下一个rack的迁移。因此我们对迁移控制器(Controller)进行了加强,利用控制平面(ControlPlane)监控指标(Metrics)数据平面(DataPlane,即应用程序)告警(Alerts),实现典型问题的自动干预和修复功能,详见图10。如果问题不能被修复,错误率达到阈值,迁移才会被暂停。对于大集群,实现了人为的0干预。

图10 自动化迁移流程

03 高可用的镜像仓库

一个rack共有76台机器。假设每个机器上只有50个pod,就可能最多有3800个镜像需要下载。这对镜像仓库的压力是非常大的。除了使用本地仓库,这次迁移过程中还使用了基于gossip协议的镜像本地缓存的功能,来减少远端服务端的压力,具体参见图11。

图11 镜像仓库架构

04 可逆的迁移过程

虽然我们对containerd的问题修复是有信心的,但是毕竟缺少生产环境经验,得做好随时回退的准备。一旦发现迁移后,存在极大程度影响集群的可靠性和可用性的问题,我们就要换回docker。虽然迁移后,在线上的确发现了镜像不能成功下载,容器不能启动和删除等问题,但是我们都找到了根本原因,并修复。所以令人庆幸的是,这个回退方法并未发挥其作用。

六、用户体验

容器运行时是kubernetes的后端服务。容器运行时的迁移不会改变任何的用户体验。但是有一个Overlayfs的问题需要特别说明一下。如果容器的基础镜像(BaseImage)centos6,利用Dockerfile去创建镜像时,如果用yum去安装包,或者在运行的centos6容器中用yum安装包的,会报以下错误:

因为yum在安装包的过程中,会先以只读模式,然后再以写模式去打开rmpdb文件。

如图12所示,对于Overlayfs来说,以只读模式打开一个文件的话,文件直接在下层(lowerlayer)被打开,我们得到一个fd1。当我们再以写模式打开,就会触发一个copy_up。rmpdb就会拷贝到上层(upperlayer)。文件就会在上层打开得到fd2。这两个fd本来是想打开同一个文件,事实却并非如此。

图12

图13

解决方案就是在执行yum命令之前先装一个yum-plugin-ovl插件。这个插件就是去做一个初始的copy_up,如图13所示。将rpmdb先拷贝到上层,参考Dockerfile如下:

如果基础镜像是centos7,则没有这个问题,因为centos7的基础镜像已经有这个规避方法了。

七、总结

目前我们50个集群,20K+的节点已经全部迁到containerd,历时2个月(非执行时间)。从目前情况来看,还比较稳定。虽然迁移过程中也出了不少问题,但经过各个小组的不懈努力,此次迁移终于顺利完成了。

本文转载自公众号eBay技术荟(ID:eBayTechRecruiting)

原文链接

https://mp.weixin.qq.com/s/9dhmQeCPuA_TysMwhzKqGA

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章