基于Docker的虚拟化技术研究
2017-10-12郭甲戌胡晓勤
◆郭甲戌 胡晓勤
(四川大学计算机学院 四川 610065)
基于Docker的虚拟化技术研究
◆郭甲戌 胡晓勤
(四川大学计算机学院 四川 610065)
虚拟化作为一种资源抽象管理的技术,在云计算中发挥着重要的作用。新兴的容器化解决方案比传统虚拟机提供了更多的灵活性和更高的效能,已经证明可以成为云计算中虚拟化的轻量级替代。Docker作为轻量级容器管理引擎为新一代云计算平台提供了支持。本文研究了现有虚拟化技术,并使用通用的基准测试HPL来评估传统KVM虚拟机和Docker容器的性能差异。结果表明,容器技术在计算能力方面比虚拟化有更多的优势,而且自身开销低。但是Docker也有自身的适用场景和隔离安全性方面的不足,大规模地使用Docker时,需要慎重考虑。
虚拟化;容器;Docker
0 引言
传统的虚拟化技术[1]比如KVM(Kernel Virtual Machine),通过引入虚拟机监控器,又叫做虚拟化层(Hypervisor)[2],来实现拦截计算元件对物理资源的直接访问,并将其重新定向到虚拟资源池中。虚拟机监控器运行的环境,也就是真实的物理平台,称之为宿主机。而虚拟出来的平台通常称为客户机,里面运行的系统也通常称为客户机操作系统。最近诸如 Docker[3]等轻量级虚拟化技术已经得到业界的广泛关注,作为一种操作系统级的虚拟方法,Docker允许在相同的内核空间中创建不同的命名空间实例,从而紧密地集成到主机操作系统中,减少虚拟机带来的开销[4]。
1 基于Hypervisor和基于容器的虚拟化
目前来说,主要有两种模式的虚拟化,分别基于虚拟机监控程序平台和基于容器技术的轻量级虚拟化平台[5,6]。图1比较了基于Hypervisor(a,b)和基于容器(c)虚拟化架构的不同。
图1.a展示了可以直接在硬件资源上运行Hypervisor的虚拟机,这类产品包括Vmware ESXi,著名的开源虚拟化软件XEN以及微软的Hyper-v。从某种意义上说,这种类型的虚拟机监控程序可以视为一个特别为虚拟机而特别优化的操作系统内核。
图1.b指系统上电后仍然运行一般意义上的操作系统(也就是宿主机操作系统),而虚拟机监控程序作为特殊是应用程序运行在宿主机上,这类虚拟机产品包括开源的 KVM以及 Vmware Workstation和Oracle VirtualBox等。
图1.c则显示了容器化虚拟技术的架构,不同于传统的虚拟机,容器虚拟化不会嵌入自己的内核,而是直接在宿主机的内核上运行,通过删除虚拟层和客户机系统来缩短了系统调用的执行消耗,同时,容器还可以共享宿主机的软件资源(比如一些库),这使得容器非常的轻量级,提供了接近裸机性能的可能[7]
图1 不同的虚拟化架构
1.1 从容器到Docker
容器并不是一个完全新兴的概念,最早的容器技术可以追溯到1982年Unix系列操作系统上的chroot工具。而最近基于Linux的容器则是依靠内核的支持,根据内核提供的系统调为接口。有两种基于内核的方式实现的容器:Linux container(LXC)使用cgroups和namespaces,以及OpenVZ分支。
在LXC的基础上,Docker进一步优化了容器的使用体验,并且提供了各种容器管理工具,让用户无需关注底层的操作,可以简单明了地管理和使用容器。在Linux上,Docker使用cgroups来实现对进程资源(比如CPU,内存,网络)的限制,同时使用内核的namespace特性来实现对不同进程的隔离。
1.2 Docker核心机制
Docker容器在主机上创建一个隔离的受控的环境,在其中代码可以安全地运行(理想情况下)。这种隔离主要通过两种内核特性kernel namespaces 和control groups。Namespaces用来拆分进程对系统的视图,目前内核有 6个不同的命名空间--PID,IPC,NET,MNT,UTS,USER--用来隔离系统的各个方面。每一个命名空间中都有与其类型相关的内核对象,并且在/proc和/sys的文件系统来对每个进程进行限制。
1.3 Docker daemon
Docker Daemon作为一个运行在主机上的守护进程,负责启动容器,控制它们的隔离等级(cgroups,namespaces,以及SELinux/Apparmor),以及监视它们的触发动作,比如重新启动等,并且在运行的容器中生成shell来进行管理。Daemon可以改变主机上的iptables规则来生成相应的网络接口,还负责镜像的管理,比如拉取和推送镜像,根据dockerfiles来创建镜像,对镜像签名等。Daemon本身必须以root运行,获得所有的权限。主机可以通过Unix 套接字来进行连接,也可以使用TCP套接字进行连接。
1.4 Docker hub
Docker hub作为官方的在线镜像仓库,允许开发者们上传镜像和普通用户的下载镜像。开发者可以创建一个免费的账户来得到一个公开的个人仓库,或者使用付费账户,使仓库变为私有。Docker daemon hub、和仓库类似于一种软件包的管理工具,一个本地的docker daemon程序从本机和远程仓库上都可以下载镜像,其中一些仓库是官方的,其余的则是非官方的由第三方机构提供。
2 Docker安全
Docker的安全问题存在于三个方面:由Docker守护进程管理的用户空间级别进程的隔离性、内核对隔离的强制性以及网络安全性。
2.1 隔离性
Docker容器完全依赖于Linux内核,包括namespaces,cgroups和capabilities。namespaces隔离和capabilities默认情况下是启用的,但是cgroups则需要在启动每个容器时添加参数-a -c选项来启用。默认的容器隔离配置的很严格的,唯一的缺陷是所有容器共享网桥,会出现网络的隐患。
但是,Docker的全局安全性可以通过容器启动时的选项来降低,这会带来隐患。此外,安全配置可以由Docker daemon启动时传入的变量来进行全局设置。例如,可使用-insecure-registry选项,它禁用安全传输层(TLS)的证书检测,会使安全性降低,而-icc=false选项,它禁止容器直接的网络通信,则会增加安全性,但是它又会阻止多容器应用程序的运行,因此很少使用。
2.2 主机加固
主机加固通过Linux内核安全模块来强制对容器进行安全相关的限制约束。Docker目前允许使用配置文件来支持SELinux、Apparmor和Seccomp等安全模块。例如,默认的Apparmor配置文件允许对文件系统、网络和容器的所有权限。类似地,默认的SELinux策略将所有的Docker容器放在同一个域中,因此,虽然这种主机的加固保护主机免受容器的影响,却不能保护容器受到其他容器的影响。
2.3 网络安全
Docker使用网络来进行镜像的分发和对 docker守护进程的控制。为了分发镜像,docker使用哈希验证从远程仓库下载的镜像,通过TLS建立与源的连接。而docker守护进程则通过套接字接口来控制,这使得docker可以被远程的主机操作。默认的用来监听的端口号是 unix socket,就是/var/run/docker.sock所有者为root:docker,也可以使用tcp端口。访问socket使得攻击者可以拉取和运行任何容器,还能获得对主机的最高权限。对于 Unix socket来说,在docker用户组的用户都可以获得root权限,对于TCP socket来说,任何连接者都可以获得主机的最高权限,因此,连接必须使用 TLS进行加固,它对连接的双发进行加密和认证(还需要额外的证书管理)
3 Docker虚拟化的应用
大部分人都将 Docker直接与虚拟机做比较,因为两个技术在设计上是等效的。但其实轻量级容器虚拟化的设计目标是完全不同于虚拟机的。有三种适合Docker的应用。
开发者使用微服务模式来使用 Docker--一个容器必须托管单个服务,在其中运行着单个的进程或者守护进程的子程序。因此,一个容器不应该视为一个虚拟机:没有包的管理,没有 init进程,没有ssh连接。所有的管理操作(容器的停止,重启,备份,更新,创建等)都应该通过主机来进行操作,这就需要root权限。
使用Docker来可重用和自动部署应用程序。Docker镜像通过一个通用的构建文件(dockerfiles)随时随地的构建,它指定了从基本镜像构建镜像的步骤。这种构建镜像的通用方法使得进程和镜像构建过程几乎不受主机影响,只取决于内核,而不是依赖库。
使用Docker搭建PPAS平台。现在主流的PaaSs平台都已经集成了 Docker,比如 Amazon Web Services和 Google Container Engine,创建虚拟机的集群,然后通过编排工具来管理各个虚拟机中的容器。Docker作为一个容器引擎向PaaS提供了基础的资源隔离和标准化打包部署能力,使基于其上的PaaS平台构建简单高效。
4 实验KVM vs Docker基准测试实验
虚拟化往往会给系统性能带来损失,为了显示 Docker在虚拟化方面的计算性能损失的优势,我们选择计算密集型和数据密集型的测试程序进行试验,本次实验中,使用 Intel Optimized LINPACK Benchmark[8]来比较容器和虚拟机的性能。
实验环境:我们在一台 PC机上进行测试,物理机采用 64位Ubuntu 14.04系统,处理器为Intel Corei5-3210处理,6GB内存。Docker版本为1.12,QEMU/KVM版本为1.0。在Docker容器和KVM虚拟机中都使用Centos7.2系统。为了能够对比两者虚拟化对性能带来的损失,对应于测试的计算规模,我们对测试的容器和虚拟机给定了充足的资源。首先,针对问题的大小,我们的测试系统都可以发挥出最佳的性能从而比较出两者虚拟化性能的差异。然后,我们限制资源,在资源增加下的条件下对两者进行基准测试,来比较不同资源下两者的性能表现。
实验结果如下图,图2显示了Docker 容器到性能已经很接近宿主机的性能,而KVM虚拟机的性能只达到容器一半左右。图3显示了在分配不同CPU核心的情况下,Docker容器和KVM虚拟机的性能比较,从中可以看出容器的性能一直领先于虚拟机。而且在配置比较低的时候领先优势更为明显。
图2 裸机、容器与虚拟机性能对比
图3 不同cpu核数下的性能对比
5 结束语
本文研究了 Docker容器化虚拟技术和传统 KVM虚拟化技术,还对于 Docker的使用给出了针对性的建议,并且针对两者在计算性能上的差别,使用LINPACK基准测试实验来显示Docker的性能优势。但是应用软件虚拟化的性能评价目前来说缺乏一个统一的标准,我们仅在 CPU计算能力上对两者进行了测试和比较。还有应用程序的启动时间、隔离度、安全性以及可靠性等方面都需要进行量化指标进行测试。因此下一步的工作应该在更多的维度对容器进行测试。并且制定标准,给出对不同应用场合下Docker使用的指导。
总体来说,Docker还在处于飞速发展的阶段,从简单的对应用的虚拟化到对各个容器集群的编排,以至于发展到现在以Kubernetes为代表的云平台,有理由相信,在应用本身越来越成为市场核心的今天,Docker 的应用也将越发广泛,尤其是在业界的大力支持下,很有可能成为市场的标准化技术。
[1]Wikipedia.Virtualization[EB/OL].https://en.wikipedia.org/wiki/Virtualization.
[2]任永杰.KVM 虚拟化技术[M].北京:机械工业出版社,2013.
[3]Docker[EB/OL].https://www.docker.io/.
[4]汪恺,张功萱,周秀敏.基于容器虚拟化技术研究[J].计算机技术与发展,2015.
[5]刘思尧,李强,李斌.基于 Docker 技术的容器隔离性研究[J].软件,2015.
[6]伍阳,基于 Docker 的虚拟化技术研究[EB/OL].信息技术,2016.
[7]Minh Thanh Chung,Nguyen Quang-Hung.Using Docker in High Performance Computing Applications[C].IEEE Sixth International Conference on Communications & Electronics.
[8]J. J. Dongarra, P. Luszczek, and A. Petitet. The linpack benchmark:past, present and future,Concurrency and Computation[J].practice and experience,2003.