***本文介绍了Docker镜像,容器和Registry,以及他们如何给基础设施和软件复用带来益处。***
Docker原名dotCloud,以建立单一应用程序的Linux容器为目的在2012年以一个开源项目起步。此后Docker 成为一个大受欢迎的开发工具,越来越多地作为运行环境使用。很少能有像Docker一样迅速地受到开发者欢迎的技术。
Docker如此受欢迎的一个原因是它提供“开发一次,随处运行”的承诺。Docker提供一种简单的方法来将应用程序以及运行时依赖打包进单一的容器;它还提供了一种运行时抽象,使容器跨不同版本的Linux内核运行。
开发者可以使用Docker在他或她的工作站做一个容器化应用,然后轻松地把容器部署到任何启用Docker的服务器中。无论是在云或内部部署,都不需要为服务器环境重新测试或重新调试。
此外, Docker 提供了一种允许开发人员和运维团队轻松共享和重用容器内容的软件共享和分发机制。这种分发机制加上跨机器的可移植性,有助于解释Docker在运维团队以及开发者之间受欢迎的原因。
## Docker组件
Docker既是开发工具也是运行环境。要了解Docker,我们必须首先了解Docker容器镜像的概念。容器总是始于镜像并被视为镜像实例。镜像是一个静态的规范,规定了容器在运行时应该是什么样的,包括容器内的应用程序代码以及运行配置设置。Docker镜像包含只读层,这意味着一旦创建镜像就不能对其修改。
图1展示了一个容器镜像的例子。其描述一个安装Apache的Ubuntu镜像。镜像是由三个基础Ubuntu层外加一个更新层,以及一个Apache层和顶部的自定义文件层组成。
![alt 文本](http://blog.tenxcloud.com/wp-content/uploads/2016/06/%E5%AE%B9%E5%99%A8101-1.png)
*图一:Docker镜像层*
运行中的Docker容器是一个镜像实例。来自同一镜像的容器使用相同的应用程序代码和运行时依赖会彼此相同。但容器不同于只读的镜像,运行的容器在只读内容上包括一个可写层(容器层)。包括任何写入和更新数据和文件的运行时变化都保存在容器层中。因此,多个并发的、共享相同底层镜像的运行容器可能包含的容器层是大不相同的。
当运行的容器被删除,可写容器层将也会被删除,不会持久化。持续化变更的唯一方法就是在删除容器之前显示调用一次docker commit指令,当你执行docker commit指令的时候,运行中容器的内容,包括可写层,会被写进一个新的容器镜像并存储到磁盘。它会成为一个新的镜像,不同于容器实例化时使用的镜像。
使用docker commit命令,你可以创建一个继承的、Docker镜像离散集,各自构建于以前的镜像上。此外,Docker使用写时复制策略减少共享相同基本组件的容器和镜像的存储空间。这有助于优化存储空间,减少容器的启动时间。
图2描述了镜像和运行容器的区别。注意每个运行容器可以有不同的可写层。
![alt 文本](http://blog.tenxcloud.com/wp-content/uploads/2016/06/%E5%AE%B9%E5%99%A8101.2.png)
*图2:Docker镜像以及运行Docker容器*
除了镜像的概念之外,Docker有一些不同于传统Linux容器的特定组件。
● Docker daemon也被称为Docker引擎,Docker daemon是容器和Linux内核之间的一个薄层,Docker daemon 是持久的运行环境,它管理应用程序容器。任何Docker容器可以运行在任意启用Docker-daemon的服务器上,而不用考虑底层操作系统的问题。
● Dockerfile。开发者使用Dockerfiles构建容器镜像,这些镜像之后成为运行容器的基础。Dockerfile是一个包含组装容器镜像所需的所有配置信息和命令的文本文件。有了Dockerfile,Docker daemon可以自动创建容器镜像。这个过程大大简化了创建容器的步骤。
更特别的是,在Dockerfile中,首先你需要指定一个基础镜像作为构建过程的开始。然后你指定一系列命令,之后可以来创建新的容器镜像。
● Docker命令行界面工具。Docker提供一套CLI命令用于管理基于镜像的容器生命周期。Docker命令涵盖构建,导出和标记的开发功能,以及运行功能,例如运行、删除、启动和停止一个容器等等。
你可以对一个特定的Docker daemon或registry执行Docker命令。例如,如果你执行docker ps命令,Docker将返回一个在daemon中运行的容器列表。
## Docker内容分发
除了运行环境和容器格式,Docker还提供了一个通常被称为registry的软件分发机制,它有利于容器内容的发现和分发。
registry的概念是Docker成功的关键,因为它提供了一套实用工具来打包,运输,存储,发现以及重复利用容器的内容。Docker公司运行了一个被称作Docker Hub的公开免费的registry。
● Registry。Docker registry是容器镜像发布和存储的地方。registry可以是远程或本地的。它可以是公开的,这样每个人都可以使用。它也可以是私人的,局限于一个组织或一组用户。Docker registry自带一套通用的API来允许用户构建、发布、搜索、下载、以及管理容器镜像。
● Docker Hub。Docker Hub是一个由Docker管理的、基于云实现的、公共的容器registry。Docker Hub提供镜像发现,分发,和协同工作流支持。此外,Docker Hub 有一组由Docker颁布的官方镜像。这些镜像来源于已知的软件出版商如Canonical、Red Hat 和MongoDB。你可以使用这些官方镜像作为构建自己的镜像或应用程序的基础。
图3描述了用户构建镜像并将它上传到registry的工作流。无论在哪里,其他用户都可以从registry拉取镜像来制作生产容器并将它们部署到 Docker主机上。
![alt 文本](http://blog.tenxcloud.com/wp-content/uploads/2016/06/%E5%AE%B9%E5%99%A8101.3.png)
*图3:Docker registry workflow.*
## Docker容器的不变性
Docker容器最有趣的特性之一是其不变性以及由此产生的无状态的容器。
正如我们在上一节中所描述的,Docker镜像一旦形成就不会改变。从镜像派生的运行中的容器拥有一个暂时存储运行变化的可写层。如果在删除之前提交了容器,可写层的变化将被保存到一个不同于之前的新的镜像中。
*版本控制* 。通过要求显示地提交,Docker强制你做版本控制。你可以跟踪一个镜像的继承版本;回滚到以前的图像(到前一个系统组件)是完全有可能的,因为以前的镜像被保存并不会被修改。
*更干净的更新以及更容易管理的状态变化* 。有了不变的基础设施,你不必再升级你的服务器基础设施,这就意味着不需要更改配置文件,不需要软件更新,不需要操作系统升级等等。当需要更改时,你只需制作新的容器,并将它们推出来替换旧的就可以了。对于状态变更来说这是一个更为独立和易于管理的方法。
*最小的漂移* 。为了避免漂移,你可以定期主动地刷新系统中的所有组件,以确保它们是最新的版本。相比于使用传统的大型软件,使用封装了更小系统组件的容器来实践会更容易。
## Docker的差异
Docker的镜像格式,用于容器管理的广泛的API,创新的软件分发机制使得Docker成为开发和运维团队都喜爱的平台。Docker给企业带来了显著的效益。
*最小的,声明式系统* 。如果作为小型单一用途的应用程序的话Docker容器能发挥最大优势。这样会产生最小尺寸的容器,从而支持快速交付、持续集成和持续部署。
*可预测的操作* 。系统运维最头痛的问题是基础设施或应用总出现看似随机的行为。通过迫使你做出更小、更易管理的更新并提供一种机制来减少系统的漂移,Docker能帮你构建更多可预测的系统。当消除了漂移,你就会得到“软件总会以相同的方式运转”的保证,不管部署多少次。
*广泛的软件复用* 。Docker容器从其他镜像中复用层,这样自然会促进软件重用。通过registry对镜像的共享是另一个大规模组件复用的绝佳示例。
*真正的multicloud可移植性* 。Docker能提供真正的平台独立性,它允许容器在不同的云平台,内部的基础设施以及开发工作站之间自由迁徙。
Docker已然正在改变组织构建系统以及交付服务的方式。它开始重塑我们思考软件设计的方式和软件交付的经济性。在这些变化真正扎根之前,企业需要更好地了解如何为Docker环境管理安全和策略。但那是另一篇文章的主题。
本文由[时速云][1]翻译,如若转载,需注明转载自“[时速云][1]”
原文链接:http://www.infoworld.com/article/3077875/linux/containers-101-docker-fundamentals.html
[1]:https://www.tenxcloud.com/anniversary
有疑问加站长微信联系(非本文作者)