如果你是Docker的新手,你可能会发现理解所有的术语是个挑战。似乎每个人对Docker术语的含义都有不同的看法,而且有时术语可以互换使用。
例如,你和其他正在学习Docker的人一样,可能想知道Docker镜像和Docker容器有什么区别。它们之间的对比是微妙的,但却很重要。
本文将探讨Docker镜像和容器之间的区别,帮助你了解如何以及何时使用它们。
Docker概述
像Docker、Flatpak和Snaps这样的解决方案都有相同的目标,即把一个应用打包成一个单一的捆绑包,以安装在任何Linux发行版中。
Solomon Hykes在2013年将Docker作为一个开源项目推出。他们的第一个商业版本在2014年准备投入生产。
Docker容器化平台通过使用容器来帮助创建、部署和运行应用程序。可以把容器想象成软件的运输容器--它可以容纳文件和程序等重要内容,以便应用程序可以有效地从生产者交付给消费者。
容器化最大的好处之一是,它使开发者能够将他们的应用程序与在任何Linux发行版上运行所需的所有依赖项打包。这消除了手动安装每个依赖项的需要。
多个容器可以同时运行,每个容器基于相同或不同的镜像。Docker在创建操作系统的多个实例的方式上与虚拟机类似。然而,Docker允许你创建在同一操作系统上运行的容器。因此,在一个给定的硬件组合上可以运行比虚拟机更多的容器。
Docker容器甚至可以在虚拟机内运行。与创建虚拟机相比,Docker提供了一个额外的抽象和自动化层,使其更容易使用。
容器化平台在开发者和系统管理员中越来越受欢迎,因为它包含了应用程序的完整文件系统及其所有依赖关系。这种设置实现了不可改变的基础设施,并保证了部署的不可替代性--无论你重复操作多少次,它们都会保持完全相同。
一个Docker守护进程在后台运行,以管理图像、容器等。客户端和守护进程使用套接字或通过RESTful API进行通信。
什么是Docker镜像?
映像是只读的模板,包含创建容器的指令。Docker镜像可以创建在Docker平台上运行的容器。
可以把镜像想象成一个蓝图或快照,即运行时容器中会有什么。
一个镜像是由多个堆叠的层组成的,就像照片编辑器中的层,每个层都会改变环境中的某些东西。图像包含代码或二进制文件、运行时、依赖性和其他文件系统对象,以运行一个应用程序。图像依赖于主机操作系统(OS)的内核。
例如,要建立一个网络服务器镜像,从包括Ubuntu Linux(一个基础操作系统)的镜像开始。然后,在上面添加Apache和PHP等软件包。
你可以使用Dockerfile手动构建镜像,这是一个包含创建Docker镜像的所有命令的文本文件。你也可以从一个叫做注册表的中央仓库,或者从Docker Hub这样的仓库中使用命令docker pull [name] 。
当Docker用户运行一个镜像时,它会变成一个或多个容器实例。容器的初始状态可以是开发者想要的任何东西--它可能有一个已经安装和配置好的Web服务器,或者除了一个以root身份运行的bash shell之外什么都没有。但在实践中,大多数镜像包括一些预配置的软件和配置文件。
Docker镜像是不可改变的,所以一旦创建,你就不能改变它们。如果你需要改变一些东西,可以用你的改变创建另一个容器,然后把这些保存为另一个镜像。或者,以现有的镜像为基础运行你的新容器,然后改变那个镜像。
在成功构建一个应用程序后,Docker可以进一步将镜像导出为其他镜像。互相衍生的图像通常被称为父图像和子图像。
一个镜像可以有多个标签,但每个标签都是唯一的。标签可以区分镜像,例如ubuntu:最新的或ubuntu:14.04。
镜像本身并不运行,但你可以从Docker镜像中创建和运行容器。
什么是容器?
容器是一个隔离的地方,应用程序在那里运行,不会影响到系统的其他部分,也不会影响到系统的应用程序。因为它们是隔离的,所以容器非常适合安全地运行像数据库或网络应用程序这样的软件,这些软件需要访问敏感资源,而不给系统上的每个用户以访问权。
由于容器在Linux上原生运行并共享主机的内核,它是轻量级的,不比其他可执行文件使用更多内存。如果你停止一个容器,它不会自动重新启动,除非你这样配置它。然而,容器可以比虚拟机更有效,因为它们不需要整个操作系统的开销。它们与其他容器共享一个内核,在几秒钟内启动,而不是几分钟。
你可以使用容器将一个应用程序与它所需要的所有组件打包,然后作为一个单元将其全部运送出去。这种方法很受欢迎,因为它消除了开发、QA和生产环境之间的摩擦,使软件运输更快。在软件容器内构建和部署应用程序,消除了在与其他开发人员合作编写代码时 "在我的机器上运行 "的问题。
应用程序还可以在任何基础设施和任何云中运行。你可以将应用程序和它们的底层基础设施与其他应用程序隔离开来。
Docker镜像与容器
Docker镜像在Docker容器中执行代码。你在Docker镜像上添加一个可写的核心功能层,以创建一个运行的容器。
把Docker容器看成是一个运行中的镜像实例。你可以从同一个镜像中创建许多容器,每个容器都有自己的独特数据和状态。
虽然镜像不是创建容器的唯一方法,但它们是一种常见的方法。
采用容器的一个关键好处是开发、操作和测试的标准化和简单化。然而,为了让团队充分利用容器,他们需要确保开发人员、运营工程师和测试人员创建一致的环境。
持续集成和持续部署(CI/CD)管道可以构建、测试和打包容器。然后,部署将该容器分发到运行环境,在那里它可以作为应用程序的一部分执行。
像CircleCI这样的持续集成解决方案使开发人员能够自动构建、测试和部署。CircleCI可以使用Docker容器,使您的应用程序部署到多个环境更容易。
例如,CircleCI可以建立Docker镜像,并将其推送到像Docker Hub这样的容器镜像注册中心。从那里,它可以将图像实例化到Kubernetes、OpenShift或其他地方的容器中。
这个流程是这样的。
- 你向你的Git repo提交修改。
- 这个提交会触发CircleCI的构建工作,从Git中检查出源代码并对代码进行单元测试。
- 如果单元测试通过,CircleCI会将构建的镜像推送到Docker Hub。
- 如果单元测试失败,CircleCI会提醒开发人员并停止工作流程。
像Docker层缓存和测试分割的功能也可以帮助你更快地构建和测试你的图像,缩短你的部署时间。更多关于使用持续集成平台来协调Docker构建、测试和部署的好处,请访问如何用Docker构建CI/CD管道。
总结
尽管Docker镜像和容器有类似的目的,但它们有不同的用途。镜像是一个环境的快照,而容器则运行软件。
容器和镜像都允许用户指定应用程序的依赖性和配置,并描述一台机器运行该应用程序所需的一切。然而,容器和图像有不同的生命周期。例如,你可以在基于容器的系统(如Pivotal Cloud Foundry)上使用容器,但不能使用图像。同样,你可以在Heroku或OpenShift这样的非容器系统中使用镜像,而不是容器。
这不是一个选择容器或图像的问题。它们是相互依赖的,你需要两者来使用Docker。
现在你了解了Docker镜像和容器之间的细微差别,你可以充分利用Docker平台。当与Docker一起工作时,自动化可以帮助您快速集成,并释放出开发人员的时间来创建新的应用功能。了解更多关于CircleCI的Docker和Kubernetes集成如何提高您软件开发过程的效率。