Cloud Foundry’s 新容器技术: A Garden Overview

前言

编译自:

Cloud Foundry’s Container Technology: A Garden Overview

Containers in Cloud Foundry: warden meets libcontainer

CloudFoundry(CF)中很早就使用了VMware研发的Warden容器来负责应用的资源分配隔离和实例调度。可惜的是,这一本来可以成为业界标准和并掀起一阵革命的容器PaaS技术却因为Pivotal的方针路线上的种种原因被后来居上Docker吊打至今。最近CFer有醒悟的迹象,在Warden上进行了大量改进和升级,本文就来一窥CF新容器技术的一些要点。

Warden和Garden

Warden背景:

“CloudFoundry’s container technology is provided by Warden,which was created by VMware’s Pieter Noorduis and others.Warden is a subtle combination of Ruby code, a core written inC, and shell scripts to configure the host and containers.”

在此前的WardenDEA中,在每个安装好的DEA上都会运行Warden服务(Ruby写的,调用大量shell来配置host),用来管理Cgroup,Namespaces和以及进程管理。同时,Warden容器的感知和状态监控也由此服务来负责。作为一个C/S结构的服务,Warden使用了谷歌的protobuf协议来负责交互。每个容器内部都运行一个wshd daemon(C语言写的)来负责容器内的管理比如启动应用进程,输出日志和错误等等。这里需要注意的正是由于使用了protobuf,warden对外的交互部分强依赖于wardenprotocol,使得warden对开发者的易用性大打折扣。

CF-RQ-1

Wardenstructure

在CloudFoundry的下一代PaaS项目Diego中,Pivotal团队对于Warden进行了基于Golang的重构,并建立了一个独立的项目Garden。在Garden中,容器管理的功能被从server代码里分离出来,即server部分只负责接收协议请求,而原先的容器管理则交给backend组件,包括将接收到的请求映射成为Linux(假如是Linux backend的话)操作。值得注意的是:这样backend架构再次透露出了warden跨平台的野心,可以想象一旦Windowsbackend被社区(比如IronFoundry)贡献出来后的威力。更重要的是,RESTful风格的API终于被引入到了Garden里面,原作者说是为了实验和测试,但实际上Docker最成功的一点正是友好的API和以此为基础的扩展能力。

CF-RQ-2

Gardenstructure

Namespaces

容器化应用依然通过namespaces来定义它所能使用的资源。最简单的例子,应用的运行需要监听指定的端口,而传统方法中这个端口就必须在全局的host网络namespaces上可见。为了避免应用互相之间出现端口冲突,Garden服务就需要设置一组namepaces来隔离每个应用的IP和port(即网络namespace)。需要再次强调,容器化的应用资源隔离不同于传统的虚拟化技术,虽然我们在讲容器,但是我们并没有去创建“什么”,而是为实实在在运行着的应用进程划分属于它自己的“命名空间”。

Garden使用了除用户namespace之外的所有namespace技术。具体实现是使用挂载namespace的方法来用用户目录替换原host的root文件系统(使用pivot_root指令),然后unmount这个root文件系统使得从容器不会直接访问到该目录

备注:Linux在很早之前就支持了namespaces技术,从一开始为文件系统挂载点划分namespace,到最新的为用户添加namespace,具体演化参见:Articles on Linux namespaces

ResourceControl

被限制在运行在namespaces中的应用可以在这个“匿名的操作系统环境“中自由的使用类似于CPU和MEM这样的资源,但是应用仍然是直接访问系统设备的。Linux提供了一系列controlgroups来将进程划分为层级结构的组然后将它们限制到不同的约束中。这些约束由cgroup中的resourcecontrollers来实现并负责与kernel子系统进行交互。举个例子:memoryresource controller可以限制一个controlgroup中的进程能够在真实内存中使用的页数,从而确保这些进程在超出限制后被停止。

Garden使用了五种资源控制:cpuset(CPUs and memory nodes) , cpu (CPU bandwidth), cpuacct (CPUaccounting), devices (device access), and memory(memoryusage),并通过这些资源控制堆每一个容器设置一个controlgroup。所以容器中的进程将被限制在resourcecontrollers指定的资源数下运行(严格地说cpuacct仅统计CPUusage,并不做出具体限制)。

此外,Garden还使用setrlimit系统调用来控制容器中进程的资源使用;使用setquota来为容器中的用户设置配额。这一点上也同Warden相同。

NetworkingFacilities

简单来说,每个容器都运行在独立的网络namespace中,Garden负责控制进出容器的网络流量。Garden会创建一对veth(虚拟网卡)设备,为它们分配IP,然后将其中的一个放到容器的网络namespace中。接下来Garden会设置IP路由表来保证IP包能够正确地传入或传出容器。最后,网络包过滤规则会为容器创建防火墙来限制inbound和outbound的流量。这一点上与Warden原先的网络相同。

CF-RQ-3

Containernetworking

RootFile System

Warden是允许用户自己指定一个root文件系统来供容器使用的。而Garden不仅继承了这个功能,更重要的是还能支持从Docker image来构建rootfs。同时,Garden在rootfs中引入了rw权限的层,所以容器可以叠加自己的rootfs而不影响其他容器(比如container A是warden rootfs,而container B是docker rootfs)

GardenAPI

新的Garden API同样是基于Google protobuf的,包括如下所有操作:

  • Capacity– returns the memory and disk capacity of the host machine
  • Create– creates a container and returns its handle (a string which identifies the container)
  • Info –returns information about a specified container such as its IPaddress and a list of processes running in the container
  • Run –spawns a process in the container and streams its output back to theclient
  • Attach– starts streaming the output of a specified process ina specified container back to the client
  • List –lists all container handles
  • LimitBandwidth,LimitCpu, LimitDisk, LimitMemory – adjusts the limits of aspecified container for network bandwidth, CPU shares,disk usage, and memory usage, respectively
  • NetIn –maps a port on the host machine to a port in the specified container
  • NetOut– whitelists outbound network traffic from the specified containerto a specified network and/or port
  • StreamIn– copies data into a specified file in the specifiedcontainer’s file system
  • StreamOut– copies data out of a specified file in the specifiedcontainer’s file system
  • Ping –checks that the garden server is running
  • Stop –terminates all processes in a specified container but leaves thecontainer around (instopped state)
  • Destroy– destroys the specified container

Merge Warden with Docker?

与此同时,Pivotal还计划通过更通用的驱动层来将Docker直接merge到现有的系统中。主要实现方式是为前面所说的backend添加libcontainer-specific backend,如下图所示:

CF-RQ-4

这样,用户的请求将通过这个backend翻译成libcontainer API来启动Docker镜像——比如将用户的应用run在Docker而不是Warden容器中。但是这个feature是作为一个长期计划与Garden并行的,主要原因应该是libcontainer的API并没有完全ready,目前还在采用很初级的替代方案。

综上,CF的新容器技术向后来者Docker展示了友好的一面,并且把握住了Docker image这一核心value而不是费力不讨好地支持所有Docker feature。但是这此的改动还是一次被动的应对,恐怕只有Windows backend和libcontainer backend的及时release才能迅速扭转局面。

浙江大学SEL实验室是本网站上所有页面设计、页面内容的著作权人,对该网站所载的作品,包括但不限于网站所载的文字、数据、图形、照片、有声文件、动画文件、音视频资料等拥有完整的版权,受著作权法保护。严禁任何媒体、网站、个人或组织以任何形式或出于任何目的在未经本实验室书面授权的情況下抄袭、转载、摘编、修改本网站內容,或链接、转帖或以其他方式复制用于商业目的或发行,或稍作修改后在其它网站上使用,前述行为均将构成对本网站版权之侵犯,本网站將依法追究其法律责任。
本网站与他人另有协议授权下载的或法律另有规定的,在下载使用时必须注明“稿件来源:浙江大学SEL实验室”。

Leave a Reply

Your email address will not be published. Required fields are marked *