谈docker容器

##什么是容器
在云计算或者说虚拟机普及的过程中,用户常常会问虚拟机是什么?虚拟机有什么优势?性能如何?她是如何提高硬件利用率?。。。当然我们会给客户解释CPU与内存虚拟化、资源超分配、分布式存储等等概念。到现在,虚拟机完全被普及,虚拟机带来的优势适合诸多业务场景,逐渐打消了人们对虚拟机的各种疑虑。那么,被不少激进的IT人宣称的,会替代虚拟机的容器又是什么呢?
网上许多关于容器的介绍都是针对docker,其实容器并不是docker,docker只是容器技术的一种实现,或者说是就是把容器的管理以命令行的方式呈现出来。之前有个老外写了篇100行Golang代码实现容器(https://www.infoq.com/articles/build-a-container-golang),
基于这个代码实现的容器,更能体现容器技术的本质,容器的核心应该是三个方面:

  1. 命名空间:隔离,容器内的应用只能看到该容器内的资源(用户信息、进程信息,网络信息、挂载信息等)
  2. Cgroup:为不同的容器提供资源限制,定义容器对宿主机资源(CPU、内存等)的最大使用量。
  3. 分层文件系统:基于写时复制(COW)、联合挂载的文件系统,为容器提供文件系统
    再来看一下,以docker(Moby)为代表的容器,官方的描述:
    1
    A container image is a lightweight, stand-alone, executable package of a piece of software that includes everything needed to run it: code, runtime, system tools, system libraries, settings. Available for both Linux and Windows based apps, containerized software will always run the same, regardless of the environment. Containers isolate software from its surroundings, for example differences between development and staging environments and help reduce conflicts between teams running different software on the same infrastructure.
    翻译一下:

       容器镜像是一个轻量级、独立、可执行软件的打包,这个包内包含了需要运行该软件的代码、运行环境、系统工具、系统库、配置。基于Linux和Windows的应用,容器化后的软件可以运行在windows或者Linux,无需感知环境的变化。容器将软件与其他不想关的资源隔离,例如不区分开发环境、演示环境,减少不同团队在相同基础环境运行不同软件带来的冲突
    ##容器与镜像

参考下面最经典的docker技术架构图。

BP

###按照这幅图上的3个命令梳理一下

  1. docker build
    如前文所说,docker只是把容器管理以命令行的方式呈现,docker对容器生态最大的贡献是他的镜像(Image)

    容器镜像可以认为一个应用+运行环境的模板,和虚拟机模板类似,但是与虚拟机模板不同的是:这个镜像一般比较小,通常只是包含应用的执行文件以及特定的运行环境,不会包含操作系统的文件,制作镜像是需要定义一个描述镜像内容的描述文件就OK了,docker里面叫做dockerfile,不会像虚拟机模板那样,需要在虚拟化环境上进行一次操作系统安装,

    镜像是平台无关的,平台无关就是制作了一次镜像,可以运行在windows、linux、阿里云、Vmware、华为云等等,不像虚拟机,你在阿里云上制作的虚拟机模板只能在阿里云使用,在AWS上制作的虚拟机模板只能在AWS使用。容器镜像的平台无关性是容器发展迅速的重要原因,这个特性解放了应用开发商与服务开发商,也让平台提供商有了新的发展方向。

    回到这条命令上来,通常我们执行docker build 是需要编写dockerfile文件,如下所示,是制作大数据Ambari Server镜像的dockerfile文件

    avatar


    当定义了这个dockerfile后,在命令行执行

    1
    2
    3
       docker build . -t ambari-server:1.0
    ````
       就可以获取到我们制作的容器镜像了,制作完成后,只是放在了本地机器上了,需要执行一个命令

    docker push ambari-server:1.0

    1
    2
    3
    4
    5
    6
    7
    8
    9
    将镜像保存到镜像仓库(registry),这样其他主机才能使用到该镜像

    2. docker pull

    这个命令就是在主机上将容器镜像从镜像仓库下载下来,实现了镜像的远程获取、分发能力。这个镜像下载并不是全量下载,而是只是把该主机上缺少的镜像下载下来,这里就涉及到容器镜像的分层特性,这里就不展开说了。

    3. docker run:

    那么容器是如何从镜像变为容器呢,我们只需要执行docker run 命令

    docker run -itd ambari-server:1.0 bash

    执行这个命令后,
    1、docker 会在宿主机上分配一个目录,将镜像的文件挂载到这个目录2  <br />
    2、docker会在docker Daemon进程上fork出一个子进程,这个子进程是命名空间隔离的,你在容器内看不到宿主机的信息  <br />
    3、docker会为这个容器分配IP地址  <br />
    

登录到这个容器后,你看到的进程信息和网络信息如下
avatar

avatar

##容器与应用

虚拟机强调资源的分配的管理,而容器更强调对应用的管理,随着容器的出现,容器逐渐开始影响软件架构。与虚拟机相比,容器有哪些优势?可以看下表的对比分析
上表的对比一般都是各个容器厂商的宣传卖点,容器为应用真正带来了哪些?或者说应用的哪些需求推动了容器的普及?
###应用部署
容器为应用部署带来的变化主要体现在开发环境、测试环境、生产环境的一致性上,依赖于docker的镜像,在应用开发完成后,架构师就可以定义应用的镜像,这个镜像里面包含了应用的运行环境(Tomcat、JDK、Nginx等),也包含了应用的可执行文件(War文件、Jar文件等),将之前需要在项目现场做的工作交由最熟悉的架构师完成,交付人员在项目现场只需要执行一个简单的docker run命令就可以了。
###应用迁移
将应用部署在虚拟机时,应用迁移一般有两种方式
a.将应用所在的虚拟机以虚拟机模板的方式导出,如果是跨云的话,还需要做虚拟机模板的格式转化,将虚拟机模板再导入到另一个云环境,然后再去修改各种参数配置

b.虚拟机模板格式无法转化(例如从AWS迁移到阿里云),这时只能重新部署了。
如果你使用容器转载你的应用,既不会存在这样的问题了,容器镜像与容器技术属于平台无关性,只要把镜像复制过去,然后启动容器就OK了。
###应用升级:
应用升级对于复杂的系统是个很棘手的事情,升级前需要做备份,升级失败要做恢复,有了容器就简单多了,停掉旧版本的容器,启动新版本的容器,升级失败,只需要停掉新版本容器,启动旧版本容器就可以了。
在IT领域,最重要的就是应用,或者说一个新的名词-SAAS,无论云计算、大数据还是机器学习,这些其实都是为应用提供支撑,让应用更好的运维、让应用更好的呈现数据价值、让应用能够进化到自我学习等。云计算的PAAS,其实就是为应用提供多种支撑的,只是由于多种因素,PAAS一直不温不火。。直到容器的出现,容器是为应用而生,更进一步说,容器是云时代的应用载体。