虚拟化技术的本质诉求是“隔离”,隔离带来的好处就是给定资源的“独占”,独占意味着控制和安全。比如在某物理主机上,同时运行两个程序A和B,A和B均无资源限制,可以任意获取系统资源,在极端情况下,当A的使用超过系统分配极限时,会使得B没有资源可用从而失去响应。
传统的虚拟化技术通过在物理宿主机上“利用软件仿真、模拟运行若干个虚拟操作系统”来解决隔离问题。这样对于业务应用程序来说,面对的是一个完整意义上的使用空间。在该空间内,所有给定的“资源”,包括但不限于CPU、存储空间、内存使用、带宽限制等都100%为该应用程序服务。但是传统的虚拟化技术也有以下一些弊端。
(1)过度的冗余带来不必要的负荷。
对于面向业务的应用程序来说,其诉求是资源的独享和安全的隔离。传统虚拟化技术克隆的是整套操作系统,虽然这样做并没有什么明显的问题,但是就像是杀鸡用牛刀。物理宿主机的有效负载并没有分配到应用程序上,反而因为要虚拟网络、磁盘I/O及CPU,导致大量的运算资源被虚拟软件本身所消耗掉。对某些I/O密集型应用,如MongoDB,其磁盘读写吞吐量相对于普通物理宿主机至少下降20%,所谓杀敌一千自损八百。
(2)复杂的配置显著提高了学习和使用成本。
因为传统虚拟化技术是面向的“操作系统级”虚拟化,因此,虚拟软件本身的配置复杂度非常高,不利于运维和开发快速上手;而且大部分虚拟化软件基于商用版本,版权价格非常昂贵(以VMware为例,截至2019年7月,其个人版单用户虚拟桌面系统约为1700元/套),对于中小型企业来说不友好。
(3)对于调度配置的管理偏弱。
在某些科学计算领域,算力、内存和带宽等资源需要根据提交任务的类型,时时刻刻做调整,如果采用传统虚拟化技术,则大量时间要耗费在虚拟操作系统的动态配置变更后的重启上。更有些特殊的任务需要运行在不同类型的主机上,这需要安装并初始化一个“全新的操作系统”,再重新按照其格式进行磁盘格式分区,这种操作的耗时往往是实际需求所不能容忍的。
容器化技术就是为了解决传统虚拟化技术的弊端而诞生的。传统的虚拟化技术与容器化技术架构的不同如图4-1所示。
图4-1 虚拟化技术:从系统到容器
从图4-1可以看出,整个体系结构上容器化技术比虚拟化技术少了一层“硬件仿真”,即容器化技术是操作系统“进程级别”的隔离,完全基于现有的操作系统能力(通过调用现有系统API来实现),不需要对CPU、网卡、存储设备等进行仿真操作,这就极大地提升了运行效率。目前容器化的代表技术实现是Docker。Docker是dotCloud公司于2013年基于Go语言实现的开源容器技术,在2013年底,dotCloud改名为Docker Inc,目前在容器服务提供商中位列第一。
容器虚拟化技术相对于传统主机虚拟化有以下几个好处。
(1)基于操作系统能力的进程级API隔离,将资源有效地集中于业务运算而非虚拟化本身,极大地提高了效率。
(2)容器的安装、配置及使用都是基于现有的技术栈,运维和开发的学习成本极低。
(3)容器的初始化和销毁极快(一般基于操作系统进程的fork和destroy),同Kubernetes、Mesos或者Swarm等编排技术配合使用,可以灵活调度算力资源,根据业务需求快速切换场景。
容器虚拟化虽然有诸多好处,但也不是万能的,也存在以下问题。
(1)以Docker为例,早期该容器技术是基于LXC(Linux控制组和命名空间技术),因此其隔离级别是基于系统进程,所以并不具备很多系统级的服务,比如firewalld等,其安全管理能力不适用对此需求特别高的场景。简单来说,容器化不是操作系统,轻量级的弊端就是功能不足。
(2)容器虽然不用硬件仿真,但是对于磁盘读写,仍然需要操作系统提供挂载支持,对于特别大的文件读写,挂载点要直接设定在宿主机上,这样就产生了安全穿透问题,同时,其文件转储的I/O能力仍然不能同真实物理机相提并论。
(3)容器化技术容易导致过度滥用。目前,第三方容器的镜像仓库多如牛毛,镜像文件的质量参差不齐。作为开发者,必须小心翼翼地选择适合自己的业务容器,还要特别注意这些镜像的安全性,某种意义上说工作量也很大。
综上所述,容器化是一种新的轻量级的虚拟化技术,和传统虚拟操作系统的技术相比,有一定的优势。但容器化技术并不以取代虚拟化技术为目标,二者有不同的适用场景,一般认为:基于固定容量且安全性要求较高的企业级服务,应使用虚拟化技术;对于动态弹性计算,峰值流量处理等,应使用容器化技术。