转载

Clear容器介绍

容器技术很火,人见人爱。开发人员喜欢它,因为可以借助它更容易地创建用户可以使用的程序;DevOps和信息技术部门喜欢它,因为它很容易管理和部署。从很大程度上可以说,Docker的出现让容器技术重现光芒,Docker改变了整个服务器端应用开发的业界现状,它的影响不亚于iPhone对客户端应用生态圈的影响。

当然,“容器”这个词不仅仅用于应用程序,它也用来描述一种技术,可以在隔离的环境下运行软件程序的技术。这样的容器是使用控制组来管理资源,用内核命名空间来限制容器应用所能使用的资源。对于大部分LWN读者来说,这是大部分人接触到“容器”时的第一印象。

很多宣扬容器理念的人会从虚拟机很昂贵,启动慢说起,然后介绍容器可以提供更加高效的方式。反驳者会说内核容器安全性不足。较真的人在这个问题上可以争论很久,但现实是容器相当多的潜在用户认为这可能还是个锦上添花的领域。有很多开源项目和创业公司致力于改善容器和命名空间的安全性。

我们(Intel Clear Container组织)在容器安全性问题上采取了比较特别的方式,追溯回最基本的问题:到底虚拟机技术有多么昂贵?虚拟机领域的性能主要可以用两个参数来衡量:启动时间和内存额外消耗。第一个参数直接影响到你的数据中心能多快得处理请求(比如用户登录到邮件系统需要多少时间);第二个参数会影响一个服务器上能有多少数量的容器。

我们计划构建一个系统(我们称之为“Clear容器”),在此之上可以将虚拟机技术的隔离特长和容器所能带来的部署优势集成到一起。为此,我们不再使用一般和虚拟机关联的”机器“这个词,也不假装成是可以和所有OS兼容的独立PC。

从结果来看,启动一个安全容器,它使用虚拟化技术,需要150毫秒,每个容器内存额外消耗大概是18到20MB(这意味着可以在128GB内存的服务器上能够运行超过3500个这样的安全容器)。虽然安全容器的启动没有使用内核命名空间的Docker容器快,但是对于大部分应用程序来说也已经足够了。而且我们还在优化中。

那么我们是怎么做到的呢?

Hypervisor

KVM是hypervisor层的一种可选技术方案,我们研究了QEMU层。QEMU很适合运行Windows和遗留的Linux客户机,但是灵活性不够。不仅仅所有的模拟需要消耗内存,而且它还要求客户机的底层固件必须满足一些条件。所有这些都增加了虚拟机的启动时间(500到700毫秒)。

但是,我们的方案里使用的是kvmtool,精简版hypervisor(LWN之前曾经介绍过 kvmtool )。使用kvmtool,我们就不再需要BIOS或者UEFI,而是可以直接进入Linux内核。当然kvmtool也不是完全没有消耗,启动kvmtool,创建CPU上下文环境大概需要花费30毫秒。我们改进了kvmtool,可以支持内核里的就地执行,而不需要解压内核镜像,只是mmap() vmlinux文件,然后直接进入,这样可以节约内存和时间。

内核

Linux内核启动非常快。在一台物理机器上,内核的大部分启动时间是花在初始化硬件上。但是,在虚拟机里,不存在这样的硬件延迟,因为虚拟机本身就是虚拟的,实际上只需要使用设备的virtio类,这会更容易初始化得多。我们也改进了一些预启动的CPU初始化延迟,但是即便如此,虚拟机上下文中内核的初始化还需要大概32毫秒,这中间还有很多优化的空间。

我们也解决了内核的一些bug。一些bug的解决已经上传了,还有些会在后续几周里陆续上传。

用户空间

2008年,我们曾经在Plumbers会议上讨论过 5秒启动 ,从此之后,很多事情发生了变化,最大的变化就是systemd。Systemd使得创建迅速启动的用户空间环境变得非常容易。我很愿意分享我们优化用户空间的方法,但事实是,将OS用适当的方式放在一起,用户空间就已经可以非常快地启动了(不超过75毫秒)。(在用高速取样录制启动情况时,稍微比这个时间多了一点,不过多出来的时间全是测量方法造成的消耗。)

内存消耗

内存消耗方面很有帮助的特性是 DAX ,4.0内核的ext4文件系统支持。如果对于宿主CPU而言,你的存储可以被当做内存,DAX使得系统可以在文件存储地就地执行。换句话说,当使用DAX的时候,可以完全跳过页缓存和虚拟内存子系统。对于使用mmap()的应用程序,这意味着真正的零拷贝,对于使用read()系统调用(或类似操作)的代码而言,你只会有数据的一份拷贝。DAX是为快速类闪存的存储而设计的,这类存储对于CPU而言就是内存。但是在虚拟机的环境里,这类存储是很容易模拟的。只需要在宿主机上将磁盘镜像文件映射到客户机的物理内存上,在客户机内核里使用一个小的设备驱动将这段内存空间作为DAX可用的块设备暴露给内核就可以了。

DAX解决方案为在客户机用户空间里得到所有操作系统代码和数据提供了零拷贝,零内存消耗的方案。另外,当hypervisor层使用了MAP_PRIVATE标记时,存储会立即变成copy-on-write。客户机对文件系统的写入不是持久的,因此当客户容器终止后这些数据会丢失。MAP_PRIVATE方案使得可以在容器间共享相同的磁盘镜像,也意味着如果某个容器污染了操作系统镜像,这些改变并不会存在于之后的容器里。

降低内存消耗的第二个重要特性是宿主机的内核同页合并( kernel same-page merging, KSM )。KSM是在进程和KVM客户机之间内存的重复数据删除的方式。

最终,我们优化了核心的用户空间,达到最小的内存消耗。最终的时间包括在resident daemons初始化之后调用glibc malloc_trim()函数,将glibc占用的malloc()缓存交还给内核。Glibc默认实现了一种滞后作用,占用一些已经释放的内存以免很快又需要它。

下一步

我们的工作是 rkt (实现appc规范,之前LWN也有 文章 介绍过)的观点论证。一旦这些工作更为成熟,我们也会考虑添加到Docker里。关于如何开始,如何得到代码的更多信息在 clearlinux.org 里,我们的集成和优化工作有进展的话也会在上面及时更新。

原文链接: An introduction to Clear Containers (翻译:崔婧雯 校对:)

===========================

译者介绍

崔婧雯,现就职于IBM,高级软件工程师,负责IBM WebSphere业务流程管理软件的系统测试工作。曾就职于VMware从事桌面虚拟化产品的质量保证工作。对虚拟化,中间件技术,业务流程管理有浓厚的兴趣。

正文到此结束
Loading...