返回 登录
0

再谈容器与虚拟机的那点事

本文作者:林帆,ThoughtWorks公司DevOps技术咨询师。著有《CoreOS实践之路》一书。

本文为《程序员》原创文章,未经允许不得转载,更多精彩文章请订阅2016年《程序员》http://dingyue.programmer.com.cn

容器技术起源于虚拟化技术的发展,欣欣向荣的Docker着实是容器技术潮流中的一朵十分耀眼的浪花。在Docker诞生之初,它常常被放在虚拟机技术的对立面,甚至还有过Docker将替代虚拟机的夸大宣传,在许多集群以及虚拟化方案设计的讨论中,也总会将两者拿来比较一番利弊。

现如今Docker已经比较普及,这些曾经的传言不攻而破。容器以及Docker并没有替代虚拟机,而是与之十分和谐的共存,两者各自具有不同的特征和相应适合的应用场景。但脑洞大开的探索者们总想同时获得容器的便捷性和虚拟机的安全性,为此在两者的边界上进行了许多创造性的尝试。在这篇文章里,我们将顺着这个话题,聊聊当下比较成熟的几款虚拟机和容器的结合产物。

容器式的虚拟机,虚拟机式的容器

关于容器与虚拟机的差异,具有普遍共识的特征归纳起来大致有以下几点:

  • 容器实例与主机共享操作系统内核,通过内核提供的运行时隔离能力为服务提供独立的用户域、文件系统、网络以及进程运行空间。虚拟机的每个实例自带操作系统,因而是一种硬件级的虚拟化隔离。
  • 容器通常是专用于运行特定服务的,它的镜像通常只包含运行该服务所需的上下文内容,许多广泛使用的镜像都只有几十MB,甚至几MB大小。虚拟机则需要提供包括内核在内的通用进程运行环境,它的镜像偏向于大而完整的全功能集合,即使一个最小的精简镜像的体积也有几百MB。
  • 容器的使用方式倾向于开箱即用,镜像提供的是一个『不可变的基础设施环境』。虚拟机则倾向于让用户根据所用的系统,自定义初始化操作,使用Ansible、Puppet这样的配置工具来进行基础设施的管理。
  • 容器在启动速度和运行性能上更有优势,虚拟机在安全性上更有优势。

如果从这些十分清晰的定义来看,近一年来开源界出现的一些虚拟化『边界破坏者』们已经完全无视了这些规则。它们要么是运行在虚拟机中的操作系统,却有着容器一样的使用体验,要么是基于容器技术的运行时隔离,却应该当成虚拟机使用。因此,尽管这些技术的实现细节上差异巨大,它们都有一个共同特征:携带着容器和虚拟机各一部分的基因,具备两者优势的结合。

这些璀璨的群星我们无法逐一细辨,只能通过窥一斑而见全豹的技术敏感力和洞察力,从这些虚拟化技术的新星中,挑选比较明亮的几颗,与大家共同鉴赏。

小而美的Linux系统:RancherOS

GitHub项目地址:https://github.com/rancher/os/
项目Star数量:2200+
项目启动时间:2015年2月

RancherOS是Rancher Labs公司设计的一款专为运行Docker而定制设计的Linux发行版。它的定制到了什么程度呢,在最初发布后的近一年时间里,Docker就是整个RancherOS系统PID为1的根进程,其实说白了就是将一个Docker后台进程托管在Linux内核上。与其说它是Linux发行版,倒不如说是一个运行在硬件设备上的Docker进程,而内核的存在仅仅是为了使用它的驱动,让Docker有个运行的地方。

图片描述

图一 RancherOS系统结构

RancherOS系统的设计结构如图一所示,这是一个双Docker进程的运行结构,所有的系统服务,包括管理操作系统设备的udev服务,管理系统网络的netconf、dhcpcd服务,管理日志的rsyslogd服务,以及与用户交换使用的Shell进程,都以容器的形式运行与下层的System Docker中,而与这些服务一起的还有另一个Docker服务进程,称为User Docker,用来以非root用户方式运行用户自定义的应用级服务。

由于Docker进程有时候会发生意外崩溃,而根进程一旦奔溃将导致所有程序状态不可逆终止的严重后果,在2016年2月发布的v0.4.3版本中,加入了一个只有几行代码的极简init进程替代了Docker的根进程位置,然而这并没有改变Docker在RancherOS系统中的地位。RancherOS操作系统本身十分轻巧,最新版本的系统ISO镜像文件只有区区32.5M。这里面的主要内容其实只有三个部分:Linux内核、一个压缩过的Docker二进制文件、以及一个内置所有系统服务文件的Docker镜像。

从常规的定义来说,这是一个自带内核的操作系统,因此RancherOS是需要按照虚拟机的方式运行和管理的。事实上也正是如此,RancherOS可以直接运行在kvm、xen、vmware和virtualbox等主流的虚拟机和硬件虚拟化平台之上。然而RancherOS的使用,除了需要借助一些工具(例如cloud-init和ros),完全就像是在使用Docker:整个操作系统的Shell是基于Docker的BusyBox镜像制作的,用户要是用不爽了可以拿Ubuntu或者Debian的Shell镜像换掉。若需要添加编译内核模块所需的内核头文件,也只需下载指定的Docker镜像然后启动相应服务即可。

在Rancher Labs建立的生态圈中,还有一个重要成员是Docker容器的调度管理平台Rancher。这个今年3月末刚刚完成1.0版本发布的项目,能够运行在包括RancherOS在内的各种主流Linux系统之上,实现虚拟机和容器的同步可视化管理,因此也弥补了RancherOS在使用和管理方式上与主流系统的差异性带来的学习成本,从而将其轻量、高效的优势充分放大,将Docker的效力发挥到极致。

运行在硬件上的Docker:Hyper

GitHub项目地址:https://github.com/hyperhq/hyperd
项目Star数量:800+
项目启动时间:2015年5月

如果说RancherOS还只是个运行了Docker的Linux操作系统的话,Hyper则是真正的将容器的运行直接搬到了硬件虚拟层上。

hyper pull ubuntu
hyper run -d -t –name machine ubuntu
hyper exec machine ls

看到这组命令的时候你想到了什么?这是在启动一个Docker容器吗?

事实上刚刚这组命令启动了一个kvm/xen虚拟机(具体是哪一种在Hyper安装时就确定了),然后在这个虚拟机里执行了一次『ls』命令。那么第一条命令中的那个『hyper pull』是在做什么呢?脑洞大开的时候到了,这条命令下载了DockerHub仓库里的官方ubuntu镜像,而之后启动虚拟机使用的正是这个Docker镜像!

正如上例子所演示的那样,Hyper是一个能够把Docker镜像当成虚拟机镜像,将其直接运行在kvm或xen的虚拟化硬件资源上的强大工具。它使用了一个高度精简的Linux内核,系统的启动时间仅为大约20ms,达到了与容器同一级别的启动速度。如表一所展示的那样,它结合了容器与虚拟机的主要优点。

图片描述

表一 虚拟机、容器与Hyper的比较

Hyper的使用体验实在太像Docker,它不仅支持从官方的DockerHub或者自建的私有Docker仓库获取镜像,还支持将本地的虚拟机镜像推送回Docker的镜像仓库中,甚至能够支持推送到那些需要登录验证的仓库。如果将Hyper制作成平台化的工具,用户将很难感知其后端运行的究竟是容器还是虚拟机,从而在提升隔离安全性的同时获得容器一样的便捷体验。

目前Hyper的发展分成了两个版本,开源版本和平台版本。前者允许用户在自己的Linux主机上安装和配置Hyper服务,后者则是将主机托管在Hyper的平台上,用户需按使用的时间和节点的规模付费,价格大约只有同等配置的传统虚拟机的一半。开源的版本单独建立了官方网站『http://hypercontainer.io』,而最初的官方站点『https://hyper.sh』现在已经作为平台版Hyper的根据地。

在Hyper的生态圈中,包含了很多来自OpenStack以及Kubernetes社区的元素。例如能够将Hyper运行在OpenStack上的Nova驱动插件Hypernova,将Hyper于Kubernetes进行整合的项目Hypernetes,以及将OpenStack的网络模块Neutron用于Kubernetes以便于构建Hyper集群的Kubestack项目等。利用这些现成的平台,站在巨人的肩膀上,Hyper已经打造出了一片属于自己的天地。

用户态的操作系统隔离:LXD

GitHub项目地址:https://github.com/lxc/lxd
项目Star数量:900+
项目启动时间:2014年11月

LXD是一种提供虚拟化主机的方式,这一类工具其实并不算新鲜,早在Linux-VServer和OpenVZ的时代它们就曾经十分风光。那么这个一年多前才诞生的晚辈有何值得圈点之处呢?

实际上,之所以将LXD列为容器和虚拟机的结合产物,是因为它的实现主要基于LXC,而Docker最早的实现也是基于LXC的。这意味着它虽是用于虚拟主机的解决方案,骨子里的实现机制却与容器本质上如出一辙。值得指出的是,LXD并不兼容Docker的容器镜像,也没有采用AUFS那种层级式的不可变基础设施模式,仅仅是支持对虚拟主机的运行状态快照和还原,但它有自己的另一个杀手锏:服务热迁移。

服务热迁移指的是将服务在不中断当前运行状态的情况下,从一个物理节点移动到另一个物理节点,图二中跃起的金鱼十分形象的展示了这种服务迁移的方式。这一功能依赖于Canonical公司创造的CRIU技术,CRIU全称是Checkpoint/Restart In Userspace,这是一种能够将特定服务的所有运行时信息保存成磁盘文件数据,然后在另一个地方进行原样还原的,同时正如它的名字所表述的那样,这项技术仅仅通过用户态的代码实现,无需对Linux内核做任何修改。

图片描述

图二 服务热迁移

相比于OpenVZ修改内核以实现软件虚拟化的做法,LXD所用的两个核心技术都是在用户态实现的,类似Docker这样即装即用的省心设计,使得它的实施门槛比起早期的虚拟主机方案要低得多,因此普及起来更加容易。至于LXD与Docker的关系其实十分微妙,两者本也算是同门师兄弟,却由于各自志向不同,踏上不同的道路。Docker通常是用来运行特定服务的,属于PaaS层的服务,在一个Docker容器中启动许多后台进程并不是值得被称赞的实践。而LXD侧重虚拟主机层面上的应用,属于IaaS层的服务,用户可以在上面安装很多Linux应用,并运行很多的进程,甚至在其中像普通Linux那样安装Docker并使用它创建服务的容器。

不过需要指出的是,直到目前,LXD还仅仅能够运用在Ubuntu系统上,它是Canonical主导的LinuxContainers开源技术栈中的一部分,这个技术栈还包括PaaS层的容器实现LXC、专用的文件系统LXCFS、以及实现CGroup嵌套的后台服务CGManager,在网站『https://linuxcontainers.org』上有更详细的介绍。Canonical正在积极的让LXD能够在其他的Linux发行版中运行起来,这项技术的未来发展依然值得期待。

总结

天下大势分久必合,合久必分,容器与虚拟机这对曾经的欢喜冤家如今已经碰撞出了不少创意的火花。不论是RancherOS的『容器式的操作系统』,还是Hyper的『容器式虚拟机』,又或者LXC那样的『虚拟机式容器』,技术的融合总是能创造出许多新的机遇和惊喜。

当大家还在谈论容器化服务的时候,技术的先知者们早就已经开始了新的探索。随着容器生态圈的继续扩大,容器技术正在与越来越多的行业搭界,不论是过去八竿子打不着的大数据、物联网领域,还是已经闹得沸沸腾腾的微服务、虚拟化,一个更加广阔的后容器技术时代正在到来,让我们拭目以待。

评论