Cube诞生背景
随着云原生技术的推广及落地,容器技术在企业生产环境中的使用比重越来越大。Kubernetes作为容器编排的事实标准,在企业服务中被大量采用。UCloud容器团队在2018年推出了Kubernetes产品UK8S, 这款产品基于UCloud公有云环境实现,无缝集成了UCloud IaaS层计算、网络及存储的服务,使客户能够快速获取到生产可用的Kubernetes集群,并拥有灵活控制集群的能力。
但在UK8S产品推广及接入客户过程中,容器团队也陆续收到一些用户反馈的问题:
**
- 维护Kubernetes集群增加了额外的负担;用户除了管应用还需要后端资源,并未能实现以应用为中心的业务管理。
- Kubernetes体系较为复杂,学习曲线比较陡峭,需要客户团队有一定技术储备;对于已经使用了容器但尚未尝试Kubernetes的客户也是如此,一方面需要了解Kubernetes的技术体系,另一方面需要修改应用架构适配Kubernetes。
- 希望能有一款即开即用的容器产品,通过容器直接拉起应用,不需要等待虚拟机就绪再部署应用,缩短应用就绪等待时间。**
为解决上述用户问题,容器团队开发了一款新的serverless容器产品Cube&version=12040210&nettype=WIFI&lang=zh_CN&fontScale=100&exportkey=AeyrACYKyIn6fp2sFm1vTgs%3D&pass_ticket=4wqmpVNc2jvkdI3dVYbM1f74r5bD%2FzhEMtm19sXCUL0fO4Be09DNFqEUoj08GHxM&fontgear=2.000000),目前正处在公测阶段。除了降低用户使用容器的门槛,该产品还具有以下特性:
- 免运维:没有维护资源负担,不需要关心运行位置,以应用为中心,以容器镜像为应用打包标准。
- 按需付费:按照应用实际使用资源付费。
- 自动扩缩容:基于海量资源,提供API,可按需拉起和关闭应用,自动调度资源。
- 高可用:产品本身高可用,同时提供应用自愈能力。
技术选型
在实现Cube产品特性的过程中,容器团队需要解决几个技术问题:
1. 容器运行时的选型
公有云产品必然要考虑多租户隔离问题。不同于UK8S产品以云主机为基础构建的隔离性,Cube产品则直接在宿主物理机上运行容器。标准docker实现的容器并不能实现同台宿主机上不同用户不同容器之间的强隔离,因此Cube产品需要一款同时具备虚拟机强隔离性和容器快速启动特点的容器运行时方案。
容器团队注意到AWS开源了轻量级虚拟机firecracker,具有资源占用少、启动速度快、易于维护等诸多优点,并已用于实际生产环境,非常符合Cube业务场景,因此最终采用了以firecracker轻量级虚拟机为基础的容器运行时方案。从下面两张图可以看出,通过对云计算场景特别的精简和优化, firecracker相对于目前主流的虚拟化组件qemu在启动速度和内存消耗方面有明显的优势。
VMM启动时间和内存占用对比,图片引用来源&version=12040210&nettype=WIFI&lang=zh_CN&fontScale=100&exportkey=AeyrACYKyIn6fp2sFm1vTgs%3D&pass_ticket=4wqmpVNc2jvkdI3dVYbM1f74r5bD%2FzhEMtm19sXCUL0fO4Be09DNFqEUoj08GHxM&fontgear=2.000000)
2. 容器管理服务
支持虚拟机容器运行时的容器管理服务也有多种开源方案,例如containerd/cri-o,kata-container和firecracker-containerd等。经过比较,容器团队选择了cri-o + firecracker-containerd的组合。这二者在功能上能够满足单机容器管理的需求,而且和其他选型相比,代码架构更加清晰,调用链路简单明了,便于后续根据产品需求定制和改造。
3. 容器调度服务
Kubernetes已经成为了容器调度的事实标准,具备丰富的功能和良好的可扩展性。因此容器团队采用Kubernetes作为基本调度框架,并根据产品需求做相关改造,最终基本的服务架构如下所示:
优化改进
虽然采用开源方案可以加快开发进度,但为满足产品需求仍需解决一些问题,主要包括以下几个方面:
1. 容器镜像
在标准的容器镜像实现中,镜像是通过分层结构存储在宿主上的。当创建容器时,容器运行时会在镜像层之上创建一个可写层,并挂载在宿主上供容器实例使用。但Cube容器并不是直接在宿主上运行的,也不需要在宿主上挂载容器根目录。因此容器团队修改了cri-o中镜像层的相关实现,直接将容器可写层以块设备的方式挂载到轻量级虚拟机中而非宿主上,减低了宿主对Cube容器的干扰。
另外,为了解决新镜像拉取缓慢导致的容器实例启动慢的问题,容器团队提出了镜像远程挂载的解决方案。将容器镜像以块设备的形式存储在缓存集群,当需要在此镜像上生成容器实例时,先将容器镜像通过远程挂载的形式挂载到宿主上,然后容器运行时会在宿主上创建一层可写层生成容器实例。同时后台会将远程镜像同步到宿主本地,进一步加速读取,降低集群风险。上述方法可使宿主上首次获取镜像的时间缩短至3s以下,并有进一步优化空间。目前这一功能以镜像缓存的产品形式提供给用户使用,并正在逐步整合到普通镜像拉取过程中。
2. 使用公有云资源
网络方面,Cube容器的网络模型和云主机的基本相同。在将相关网络功能以cni插件的形式实现之后,Cube容器就可以很好的接入到公有云vpc网络中。
存储方面,Cube容器目前支持了两种类型的存储:可以多点读写的网络文件系统nfs和仅单点读写的云硬盘udisk。在文件存储功能上,Cube产品实现了在轻量级虚拟机中自动挂载nfs的功能,用户只需在配置文件中指定好挂载点和挂载参数,就能直接在容器中使用网络文件系统,并可以同时支持vpc网络内用户自建的nfs和UCloud公有云产品ufs。在块设备功能上,容器团队扩展了firecracker块设备的实现。通过添加对vhost-user协议的支持,Cube轻量级虚拟机可以直接对接到spdk服务,从而实现了对高性能的rssd型云硬盘挂载和使用。
3. 容器运行环境
为了减少额外资源消耗,容器团队在容器管理服务和容器运行时上做了大量优化工作。
容器团队修改了cri-o管理容器组的架构,采用了单pod对应单shim的模型。通过一个shim管理一个pod内全部容器,可以显著的降低shim资源消耗,简化容器管理。对于轻量级虚拟机,容器团队也对kernel/rootfs/init进程等做了充分地精简优化,只保留了最基本的功能,以加快启动速度,减小安全攻击面,降低资源消耗。另外,容器团队还在轻量级虚拟机中内置了infra container的实现,Cube作为pod运行时可以不必挂载额外的infra容器。
4. k8s改造
Kubernetes作为一个通用的容器调度框架,能够满足大部分容器管理的需求。但针对Cube特定的使用场景,容器团队仍需对k8s组件做一些改造。在控制面,容器团队采用了自定义的调度器,可以更好的满足多租户场景下任务优先级,调度速度,资源管理的需求。在宿主节点上,鉴于Cube容器运行时的特点,容器团队精简了一些不需要kubelet实现的功能,例如在宿主上挂载configmap/volume目录,运行cni插件,收集特定目录日志等,增强了容器与宿主之间的隔离安全性。
Cube未来展望
在完成了上述开发改造后,Cube产品成功上线,并取得良好效果。后续Cube产品会继续沿着帮助用户提升效率、降低开销、简化维护、节约成本的思路持续迭代更新。在容器性能方面,容器团队会继续优化轻量级虚拟机IO路径,减少虚拟化及管理组件的性能损耗,确保用户容器实例稳定高效运行。在服务管理方面,Cube产品层面会推出多种的容器管理控制器,并实现Cube实例直接接入Kubernetes集群的能力,为用户提供多层次的资源调度方式,方便用户按实际需要管理维护。
如果您对UCloud Cube产品感兴趣,欢迎扫码加入Cube测试交流群!