随着云计算的发展,算力由云端向边缘端扩散,对边缘场景下容器技术的需求日益增加。微内核操作系统因内核简单,功能模块间耦合度低,在边缘场景中较宏内核操作系统具有明显的架构优势。然而,容器技术依赖于操作系统提供的视图隔离和资源隔离机制,微内核操作系统普遍缺少对容器技术的支持,这阻碍了它们在云环境中的推广应用。

针对以上问题,我们以微内核操作系统Minix为实验平台,在其之上实现了两种隔离机制。其一是借助命名空间的思想,实现了主机名称和文件挂载视图两种进程资源的逻辑视图隔离。我们针对要被隔离的资源,将Minix的用户空间划分为多个的名称空间,使每个空间包含资源的一份独立的视图。为每个用户进程分配一个空间,限制其只能读写空间中的资源视图。其二是实现进程系统物理资源的隔离。结合Minix的内存管理和进程调度策略,在用户空间实现资源的控制模块以控制系统中CPU、内存、进程等软硬件资源。用户通过读写文件的方式与系统资源隔离机制交互。系统会限制单个容器进程所能使用的CPU和内存资源的上限,避免其因争抢其他容器进程的物理资源而干扰其他容器的正常运行。

实验结果表明,以上两种方法成功实现了进程资源的逻辑视图隔离和进程间系统资源的物理隔离,为在微内核操作系统上实现容器技术提供支持,且两种机制的加入为系统带来了最多3.14%的性能开销。

该成果已在实验室github组织下开源,请访问https://github.com/CGCL-codes/Minix-Container-Support获取相关内容。

背景与动机

近些年来,随着人工智能物联网时代的到来,越来越多的边缘设备需要接入到整个计算体系中去。数据中心在吸纳了大量的计算需求后,日益膨胀,不堪重负。并且,在很多实时性要求很高的边缘应用中,由边缘到云端带来的数据传输延迟也是不可忍受的。于是算力自然而然的开始从云端向边缘转移,边缘计算的概念由此诞生。但由此又引出一个问题,在云边融合的大生态下,大到数据中心,小到智能手环这样的设备,都需要操作系统的支持。当前计算机界的主流操作系统是Linux之类的宏内核架构操作系统,那么就需要对Linux进行裁剪或扩展,以适配各种各样的设备。而目前Linux内核的源码已经接近上千万行,内核里各个系统服务之间强耦合,经常牵一发而动全身,一个微小漏洞即可导致整个系统崩溃,是非常难以进行裁剪或者扩展的。

基于此,微内核架构操作系统在蛰伏多年后,又被许多业界人士提了出来。微内核架构操作系统的核心思想就是把内核态的许多系统服务(比如网络、内存管理等)尽可能的抽象到用户态来实现,最大限度的精简内核体积,解耦系统服务。用户态的各个系统服务以进程的形式存在,系统服务之间相互隔离互不干扰,以消息的方式进行进程间通信。微内核架构操作系统具有稳定性强、易于裁剪或扩展的特性,用户态的单个系统服务崩溃后,不会影响到其他系统服务的正常运行,更不会影响到内核,系统服务之间隔离性强耦合度低的特点使得整个系统非常容易进行裁剪或扩展。

微内核架构操作系统意在整合云边端各种异构设备,这对应用在不同环境下的部署和迁移提出了巨大挑战。而容器技术是这些挑战的一条应对之策,容器可以将用户的应用程序和基础设施分离,开发者们只需要关注应用本身,而不用去管底层各种各样的异构环境。被封装好的容器应用可以在任何支持容器技术的环境下一键部署和快速启动,大大缩短了项目从开发到上线的周期。微内核的概念近几年才开始走近大众的视野,相比于宏内核,其软件生态非常不成熟,关于微内核虚拟化的研究也鲜有耳闻,也没有人对如何在微内核架构操作系统上实现容器技术做过深入的研究。但在微内核架构操作系统上实现容器技术是十分必要的,本研究尝试在微内核架构系统上实现容器运行所必须具备的底层支撑技术,为后续更加深入的研究打下坚实基础。

设计与实现

1)系统总体架构

资源隔离机制和视图隔离机制的总体架构如图1所示。

图 1 资源隔离和视图隔离总体架构

为了不破坏微内核操作系统内核精简的特性,我们采用了一种不同于传统宏内核的隔离机制实现方法,在用户空间实现所有的隔离功能模块,不需要对内核做任何修改。在我们的实现方案中,充分利用微内核操作系统模块化的特性,各个隔离功能模块间松耦合,易于裁剪和扩展。如图2所示,有了这两种隔离机制,每个容器会拥有自己的逻辑视图空间,它只能使用其视图范围内的软硬件资源,其所能使用的CPU和内存资源也被限制在了一定范围内,避免了容器之间对系统资源的无序竞争。

图 2 隔离效果示意

2)视图隔离机制

图 3 视图隔离机制总体架构

如图3所示,我们实现了主机名称和文件挂载视图两种资源的视图隔离机制。系统采用客户端服务器模型,共分为四个模块。其中用户空间的用户进程代表客户端,负责接收用户命令和显示结果。用户空间的系统进程组成服务端,由三个服务器组成,分别是进程管理(PM)服务器,基本信息管理(MIB)服务器和虚拟文件系统(VFS)服务器。在客户端服务器模型下,系统的主要功能逻辑都在服务端对应的服务器中实现,因此我们通过修改功能对应的服务器来实现进程资源的视图隔离。PM主要用于创建新进程,MIB用于读写主机名称并实现主机名的隔离,VFS用于挂载文件系统,显示文件挂载视图并实现文件挂载视图的隔离机制。

隔离机制主要由两个结构实现。其一是进程与名称空间映射表,该表由结构体数组实现,每个结构由一个进程标识符和一个名称空间索引号组成,用来关联一个进程和其所在的对应资源的命名空间。另一个是名称空间与资源映射表,该表由二维数组实现,列数组的索引号表示名称空间,内容表示名称空间对应的局部资源视图,用来关联一个名称空间和空间内的局部资源。

客户端接收到用户命令后,通过调用内核提供的系统调用函数,利用消息结构体将数据经由内核传递给目标服务器,服务器处理后再把结果通过函数返回值或参数指针返回到客户端。总体上看,资源视图隔离机制包括两大功能,一是在客户端调用创建进程的函数新建属于某个命名空间的子进程。在PM创建了子进程后,向对应服务器传入父进程和子进程的标识符,通过查询进程与命名空间映射表,找到父进程所在的名称空间,然后为子进程分配对应空间。是否向用户命令中传入隔离参数会决定是否隔离子进程。不隔离的子进程会被分配到父进程的空间,隔离的子进程则会被分配到空闲的空间中并在空间与资源映射表中继承父进程空间的资源视图。二是在客户端调用查询或修改资源的命令,向对应的服务器传入命令进程的标识符,在进程与空间映射表中找到进程关联的名称空间,然后在空间与资源映射表对应的名称空间中读写局部资源视图。

3)资源隔离机制

资源隔离机制的总体架构如图4所示。总体上可以分为四个模块,用户接口文件系统(Cgroupfs)作为一个单独的服务器在系统中存在,CPU资源隔离子系统与进程调度(Sched)服务器集成,内存资源隔离子系统与内存管理(VM)服务器集成,Freezer进程控制子系统作为一个单独的服务器在系统中存在。

图 4 资源隔离机制总体架构

Cgroupfs是一个运行在操作系统用户态的伪文件系统,它不外接任何存储设备,本质上是一个内存文件系统。用户将Cgroupfs在系统中挂载后,通过操作文件的方式向系统中写入控制信息。文件系统收到控制信息后将其保存在内存中,并将其转发给各个资源隔离子系统。

CPU资源隔离子系统的实现充分利用了微内核架构操作系统进程调度策略与机制分离的理念。在用户态改造Sched,实现用户可控的CPU资源分配策略,不需要对内核中的进程调度机制做任何更改。CPU资源隔离子系统依据用户对进程设立的权值来对不同权值的进程分配不同大小的时间片,让高权值的进程更多的占有CPU资源。

VM负责处理系统上所有的内存请求,它以物理块为基本单位进行内存管理。基于此,内存资源隔离子系统与VM集成在一起,用户也可以对某个进程设置内存上限值,内存资源隔离子系统收到这种控制信息后,会对该进程的内存占用设置上限。当该进程向系统申请内存时,VM都会委派给内存资源隔离子系统会评估该进程当前占用的内存总量是否达到上限值,如果达到上限值,则系统向该进程发出警告。

Freezer进程控制子系统基于内核中的进程调度机制来实现对进程的控制。在收到用户对进程的控制指令后,它会通过系统调用的方式向内核发送消息,改变进程的运行状态。

声明:本文来自穿过丛林,版权归作者所有。文章内容仅代表作者独立观点,不代表安全内参立场,转载目的在于传递更多信息。如有侵权,请联系 anquanneican@163.com。