跳到主要内容

容器技术导入

一个新技术的出现,一定是为了解决一个问题的,而一个问题的出现一定有其背景和历史。我们在学习技术的同时,一定不要忽略了本原的问题,而迷失在了技术的细节中。 ——我说的

随着PaaS(Platform as a service)技术的普及,软件应当以什么样的方式进行交付成为了一个关键的问题,而容器通过“容器镜像”的概念,解决了软件应用打包这个根本性难题。

容器技术诞生的背景

我们希望编写的代码可以“一次编写,到处运行”,但实际情况却是同一份代码,打包后,换一个环境就启动不了了,或者跑起来各种报错。这种问题在PaaS里变得更为棘手,我们需要做很多修改和配置以摸清PaaS的脾气,才能顺利的让软件跑起来。

究其原因,是因为软件的运行是依赖环境的,我们写的代码虽然是同一份,但环境却是千差万别的。就好像我们造了一辆跑车,希望它能顺利地跑起来,但环境有可能是水泥路,也有可能是崎岖不平的山地,甚至还可能是片湖泊。

那我们能不能把软件和它所依赖的环境看做一个整体,打到一个包里,作为一个整体来交付呢?当然可以,这样,软件是一致的,环境也是一致的,不管把它们丢到哪里,都能保证程序可以正常运行。

容器(确切地说,是容器镜像)就是这么一个概念,它把程序和它所依赖的环境看做一个整体,比如你的程序在本地运行,依赖的环境是CentOS 7.2,那么就把这个操作系统的ISO和你的程序放在一起打包,这样不论在哪里解压这个压缩包,都可以得到和你本地一模一样的环境。这就解决了本地和云端环境不一致的关键问题。

或许你会说,虚拟机技术也能解决同样的问题,但虚拟机的缺点在于它太笨重了,并且会消耗更多的资源。同样的程序,用容器技术打包可能只有几MB,几秒就能启动起来;而使用虚拟机技术则需要几GB和几分钟。在程序运行的性能上,容器也比虚拟机要高很多。“敏捷”和“高性能”是容器相较于虚拟机最大的优势,也是它能够在PaaS这种更细粒度的资源管理平台上大行其道的重要原因。

容器技术简析

那容器是如何做到这些这种轻量级的打包交付的呢,让我们简单分析一下。

我们写的代码(编译后的可执行程序),平常都安安静静地躺在磁盘上,而一旦运行起来,它就变成了计算机里的数据和状态的总和,这就是它的动态表现,也就是进程。容器技术的核心,就是约束和修改进程的动态表现,从而为其创造出一个独立一致的环境。

下面我们以Linux操作系统为例,简单介绍下容器技术的核心实现原理。

Cgoups: 约束

Cgroups(Control Groups)是Linux内核提供的一种可以限制进程使用资源的机制,可以对CPU、内存、磁盘、网络带宽等资源实现精细化的控制。比如对于一个8核CPU的机器,你可以限制某个进程仅使用其中的2个核(上限),把剩下的留给其他进程。它最主要的作用,就是限制一个进程组能够使用的资源上限。

Namespace: 隔离

Namespace是Linux提供的一种内核级环境隔离的方法,可以让进程只看到与自己相关的一部分资源、文件、设备等,而感知不到其他进程的存在。这样,处于不同namespace中的进程拥有独立的全局系统资源,改变一个namespace中的资源对其他namespace中的进程没有任何影响。比如,一个服务器上运行着10个进程,现在我新建了一个namespace,并在其中启动了一个进程,那么这个进程会以为自己运行在一个独立的Linux环境中,并且只有自己一个进程在运行,它看不到这个服务器上的其他10个进程。

rootfs: 文件系统

在Linux中,有一个chroot命令可以改变进程的根目录到指定的目录(或通过pivot_root系统调用),通过这种方式,可以为容器进程提供隔离后执行环境的文件系统,这就是rootfs,根文件系统。

由于rootfs里打包的不只是应用,而是整个操作系统的文件和目录,也就意味着,应用以及它运行所需要的所有依赖,都被封装在了一起。也正是由于rootfs的存在,容器才有了一个被反复宣传至今的重要特性:一致性。

此处要注意的是,rootfs只是一个操作系统所包含的文件、配置和目录,并不包括操作系统内核。在同一台机器上的所有容器,共享这个宿主机操作系统的内核。这是容器相对于虚拟机的主要缺点。

整合

通过以上三种核心技术,Linux可以为一个进程提供一个受控的、独立的运行空间,而容器,其实就是一种特殊的进程而已。

  • namespace 技术修改了应用进程看待整个计算机“视图”,即它的“视线”被操作系统做了限制,只能“看到”某些指定的内容;
  • cgroups 限制了进程可以使用的资源配置;
  • rootfs 切换了进程的根目录,为进程提供了隔离后一致的文件系统。

我们将这个结构一分为二地看,rootfs提供的是容器的镜像,也就是静态视图;namespage+cgroups提供的隔离环境是容器的动态视图。

现在,也许你能看出来,容器其实是一种沙盒技术,像一个集装箱一样,把你的应用“装”起来。这样,应用与应用之间,就因为有了边界而不至于相互干扰;而被装进集装箱的应用,也可以被方便地搬来搬去,这就是PaaS最理想的状态。

而具体到目前最为火热的Docker项目,它就是在这些容器核心技术的基础上,做了更多有利于开发者使用的事情,从而坐上了容器技术的第一把交椅。