PaaS与容器化
容器技术
容器技术是一种轻量级的虚拟化解决方案,自Docker开源之后,容器技术受到了广泛的关注和讨论。在云技术方面,相对于传统的虚拟机,容器技术有着明显的优势,比如减少对磁盘空间的占用、提高服务器的资源利用率。更重要的是,容器尤其适用于在PaaS云中管理并协调应用,因为在PaaS云技术中,可以把容器作为应用程序的打包机制,使管理应用更加方便,更加高效。本文中将分析以Docker为代表的容器技术,以及PaaS云技术向容器生态系统的演变的现状和必要性。
云技术实现对大规模共享资源的弹性管理,需要依赖于虚拟化技术。虚拟机是整个基础设施架构的支撑,提供虚拟化的操作系统。容器与虚拟机类似,但容器是一种更加轻量级的虚拟化解决方案,占用更少的资源,响应速度也要比虚拟机快的多。
虚拟机和容器都属于虚拟化技术,但是它们应用的场景有些不同。容器是一种操作系统级的虚拟化,可以在PaaS中作为一个交付软件的工具。虚拟机是一种硬件级别上的虚拟化,可以对硬件资源进行分配和管理,应用于IaaS的硬件虚拟化技术。容器在某些特定的用例情景下可以作为虚拟机的替代方案,前提是硬件资源的分配已经在中间的云架构中完成了。
为了满足应用在云平台的可移植性和互操作性,就需要一个便携式、轻量级的运行环境和包管理器。容器技术就是一个很好的解决方案,容器化的基本思想就是提供轻量级、便携式的运行环境,并拥有开发测试并部署应用到大规模的服务器上的能力以及容器互联的能力。
如今,现代化的分布式应用逐渐成为主流,相应地产生了对容器集群管理和应用编排的需求。Kubernetes是Google开源的容器集群管理系统,其提供应用部署、维护、 扩展机制等功能,利用Kubernetes能方便地管理跨机器运行容器化的应用。Kubernetes作为Docker生态圈中重要一员,是Google多年大规模容器管理技术的开源版本。无论是公有云还是私有云甚至混合云,Kubernetes都可以提供一个各种应用、环境的容器管理框架。目前受到各大巨头及初创公司的青睐,如Microsoft、VMWare、Red Hat、CoreOS、Mesos等,纷纷加入给Kubernetes贡献代码。PaaS作为一种平台技术,而容器是一种虚拟机技术,这篇报告将介绍容器对PaaS产生了哪些影响,特别是对PaaS技术的发展有何意义,也会介绍一下技术相关的产品,例如Kubernetes, docker等,这些产品在一定程度上反映了技术的发展趋势。
虚拟化和容器技术的需求
虚拟化技术的产生是为了解决对可控制的单元进行调度处理的需求,而与调度处理相关的资源包括文件系统、内存、网络以及系统信息。虚拟机就是虚拟化技术的核心,在云架构中,虚拟化解决了调度、打包以及资源访问的问题。然而,虚拟机实例需要在主机上保存一个非常大的文件来存储虚拟机实例的整个文件系统,而且通常情况下,运行一个虚拟机实例就要在主机上运行一个很大的进程。另外,安全性的问题在很大程度上是通过隔离来控制的,这样就会留下很大的限制。每一个虚拟机实例都需要一个完整的系统镜像,其中也要包含运行库及其他必要的运行环境,启动时间也很缓慢,可能需要1到10分钟。在图1中对虚拟机和容器在虚拟化方面作了一些对比
程序打包和应用管理是PaaS层需要解决的问题,而在虚拟化的环境中,解决方案必须依赖于一些成熟的技术,包括底层平台的共享、基础设施的安全性控制、轻便并满足互操作性的应用管理。而容器技术正好可以满足这些需求,当然还有很多具体的细节需要考虑。
一个容器包含打包好的、独立的、准备部署的应用,如果必要的话,还会包含应用需要的中间件和运行库(如图1)。Docker是一个很成功的框架,构建容器引擎,能够以轻便的方式打包运行在容器中的应用。这就意味着容器涵盖了一个应用层或者应用层的一个节点,同时也要考虑一个问题,那就是在多层应用程序架构中,需要管理各个容器之间的依赖关系。这种管理功能要有一个完善的编排计划,描述每个组件,组件之间的依赖关系以及各个组件的生命周期。然后,PaaS根据这个计划通过代理制定工作流,这个代理就是Docker这种容器运行引擎。当然PaaS平台需要支持应用以容器的方式进行部署。
轻量级虚拟化与应用打包
Linux容器工具
新的Linux发行版提供了namespaces和cgroups这种内核机制,从而实现在共享的操作系统上隔离进程,这些是通过Linux容器工具LXC来支持的(如图2中描述)。Docker就是基于LXC技术来实现的,在容器技术中,启动容器是由守护式容器作为一个应用进程来启动的,就像Docker中的dockerd就是一个守护式容器,守护式容器是用户空间进程树的根进程,是容器引擎中很重要的一部分。
Namespaces,在编程语言中也有用到这个概念,实现的是代码的隔离。在操作系统中,Namespaces提供系统资源的隔离,包括进程、网络、文件系统。docker提供5种namespaces命名空间:
- PID (Process ID), 进程隔离。
- NET (Network), 管理网络接口。
- IPC (Inter Process Communication), 管理跨进程通信的访问。
- MNT (Mount), 管理挂载点。
- UTS (Unix Timessharing System), 隔离内核和版本标识。
Control groups,控件组。cgroups是linux提供的可以限制、记录、隔离进程组所使用的物理资源的机制。最初是由google工程师提出,而后,2007年在linux kernel2.6.24中整合进来。cgroups就是为了轻量级虚拟化(也就是现在的容器技术)而产生的,没有cgroups就没有容器技术。
cgroups功能包括资源限制、优先级设定、资源计量、资源控制,为docker提供文件系统的隔离 进程隔离 网络隔离 资源隔离和分组。资源限制,比如memory子系统可以为进程组设定内存使用的上限,如果超出进程组使用的内存达到了限额,再申请内存就会发生out of memory的消息;优先级设定,可以设定哪些进程组使用更大的cpu 磁盘io的资源;资源计量,可以计算进程组使用的多少资源;资源控制,可以将进程组挂起和执行。
基于linux的namespaces和cgroups内核特性,容器作为操作系统级的虚拟化技术,非常适合为PaaS云平台提供管理应用的功能。容器基于一个轻量的镜像运行,运行在容器中的进程几乎是完全隔离的,这里再说明一下,虽然虚拟机也是基于镜像启动,但是虚拟机的镜像是一个包含整个操作系统的镜像,是重量级镜像。Docker Images
Docker,使用Go开发,可以将应用程序自动部署到容器的开源引擎。Docker在虚拟化的容器执行环境当中,增加了一个应用程序部署引擎,该引擎的目标就是提供一个轻量、快速的环境,能够运行开发者的程序,也方便将程序部署到测试环境然后再部署到生产环境。
Docker images 就是一个只读的模板。比如:一个 image 可以包含一个 ubuntu 的操作系统,里面安装了apache 或者你需要的应用程序。images 可以用来创建 docker containers,docker 提供了一个很简单的机制来创建 images 或者更新现有的 images,甚至可以直接从其他人那里下载一个已经做好的 images来生成实例。那么Docker image镜像在docker中有什么作用?
Docker image镜像是容器的基石。容器基于镜像启动和运行,镜像就像是容器的源代码,保存了用于启动容器的各种条件。
镜像是一个层叠的只读文件系统。最底层是引导文件系统(bootfs),这很像典型的linux引导文件系统,docker用户基本永远不会和引导文件系统有交互,实际上当一个容器启动后,它将会被移入内存中,bootfs则会被卸载。第二层是rootfs,位于bootfs之上,rootfs可以是一种或多种操作系统(Ubuntu或centos),在传统的linux引导过程中,rootfs会先以只读的模式加载,当引导结束并完成了完整性检查后,它才会被切换为读写模式,但是在docker里rootfs永远只会是只读模式,并且docker利用联合加载技术,又会在rootfs之上加载更多的只读文件系统。联合加载技术是指一次同时加载多个文件系统,但是在外面看来,只能看到一个文件系统,联合加载会将各层文件系统叠加到一起,这样最终文件系统会包含所有的底层文件和目录,在docker中,这样的文件系统就称为镜像。
如图3,一个镜像可以放在另一个镜像的顶部,位于下面的镜像称为父镜像。最底部的镜像称为基础镜像,也就是rootfs。应用容器化与管理应用
容器技术的生态系统包含容器引擎和容器仓库。容器引擎用来运行容器,仓库用来上传和下载镜像,它有公有仓库和私有仓库两种形式,他们都可以用来上传和下载images。Docker的公有仓库叫 Docker Hub。它提供了一个巨大的 image 库可以让用户下载,你也可以在自己的局域网内建一个自己的私有仓库。容器可以从个人的镜像启动,也可以从仓库的镜像启动,图4展示了一个容器化的应用,容器可以把一些应用组件通过镜像层打包进去,不同的用户应用及平台组件可以组合进一个容器里,图5中列出了几种不同应用场景下容器将应用和运行环境组合到一起的示例。
在容器中更偏向于一个容器只运行一个应用,这种架构依旧可以利用原有的容器组合成新的应用栈,例如,在一个应用中更换web服务器,或者重用共同的组件,例如,监控工具、类似于memchached的单独存储服务,可以很容易地进行应用程序的构建和管理。相对于将多个应用运行在一个容器里,这种结构的缺点是要运行大量的容器,这些容器单独运行和管理。
有时候,容器要对相互依赖的应用以及分布式应用进行打包,这种场景下,存储管理和网络管理就是两个需要考虑的问题。
在Docker中有两种管理数据的方式,即数据卷和数据卷容器。数据卷是一个可供一个或多个容器使用的特殊目录,可以提供很多有用的特性:数据卷可以在容器之间共享和重用、对数据卷的修改会立马生效、对数据卷的更新,不会影响镜像、卷会一直存在,直到没有容器使用。如果你有一些持续更新的数据需要在容器之间共享,最好创建数据卷容器。数据卷容器,其实就是一个正常的容器,专门用来提供数据卷供其它容器挂载的。如果删除了挂载的容器,数据卷并不会被自动删除。如果要删除一个数据卷,必须在删除最后一个还挂载着它的容器时使用 docker rm -v 命令来指定同时删除关联的容器。这可以让用户在容器之间升级和移动数据卷。
网络管理基于两种方法实现,网络端口映射和容器互联。容器可以运行一些网络应用,在Docker中,要让外部也可以访问这些应用,可以通过 -P 或 -p 参数来指定端口映射。当使用 -P 标记时,Docker 会随机映射一个 49000~49900 的端口到内部容器开放的网络端口。容器的连接(linking)系统是除了端口映射外,另一种跟容器中应用交互的方式。该系统会在源和接收容器之间创建一个隧道,接收容器可以看到源容器指定的信息。容器引擎
本文中使用Docker来阐述一些核心概念,但是在不同的操作系统中还有很多其他的类型的容器技术,这里就简单介绍一下Linux、Windows以及一些PaaS平台中特定的容器技术。
- Linux: Docker、LXC Linux容器、OpenVZ和其他衍生产品,如BSD、HP-UX以及Solaris。
- Windows: Sandboxie
- PaaS平台:Cloud Foundry中的Warden/Garden、Openshift中的LXC
操作系统虚拟化和容器化依然在发展,容器化技术通过提供一些标准API和工具对容器和网络进行管理,并且让资源的使用更加容易管理,总之,容器技术旨在提供操作系统级的支持。PaaS中的容器化
虚拟机是基础设施层与PaaS平台之间的媒介,虚拟机在基础设施层为PaaS层提供应用组件,而容器技术在PaaS平台中更适用于应用打包和应用管理。PaaS的特征
PaaS通常提供一些机制来支持开发应用、为云平台设计应用、将应用放到开发者的开发环境中、使用服务、迁移数据库、映射自定义域名、IDE插件、构建集成工具等功能。PaaS还有一些功能包括构建集群、调度以均衡虚拟机的负载等。在PaaS云中,基于容器的解决方案通过互通性、轻量级以及虚拟化打包等特性支持PaaS中的这些功能。容器对于应用构建、开发和管理提供互操作性,在PaaS云平台之外的中创建的容器可以直接移入PaaS平台。目前,现有的PaaS平台已经接受了由Docker提供的容器化和应用打包功能,而且很多PaaS平台使用容器运行平台的工具。PaaS的演变
Docker的容器引擎给云平台特别是在云端构建应用程序的方式带来重大影响,Kubernetes是一项实施了容器集群管理的开源技术,用来管理应用程序容器。应用在容器中封装、运行,而Kubernetes负责容器集群管理,所有的应用都在基于Kubernetes的Linux容器上运行。如今,谷歌开放了Kubernetes的源代码,其他云平台也可以利用Kubernetes的强大功能,管理Linux容器(包括Docker容器)。
目前,现有的PaaS平台正朝着基于容器的架构发展,包括第一代的Azure、第二代PaaS云的Cloud Foundry和OpenShift以及当前第三代PaaS的Dawn、Deis、Flynn、Octohost和Tsuru。