《Docker 实战:打造可靠的生产环境容器化应用》第一章:介绍

150 阅读16分钟

Docker是由Solomon Hykes创立的一家名为dotCloud的公司的创始人兼首席执行官,于2013年3月15日在加利福尼亚州圣克拉拉市的Python开发者大会上进行了一个五分钟的闪电演讲,没有预先公告,也没有太多的宣传。在此公告时,只有大约40人在dotCloud之外有机会使用Docker进行实验。

在此公告后的几周内,Docker受到了意外的媒体关注。源代码迅速作为一个完全开源的项目发布在GitHub上。在接下来的几个月里,越来越多的行业内人士开始听说Docker,以及它将如何改变软件的构建、交付和运行方式。一年后,几乎没有人在行业内不知道Docker,但很多人仍不确定它到底是什么,以及为什么人们对它如此兴奋。

Docker是一个工具,它承诺轻松封装创建任何应用程序的可分发构建,并在任何环境中进行规模化部署,优化敏捷软件组织的工作流程和响应能力。

Docker的优势

起初,许多不熟悉Docker的人将其视为一种虚拟化平台,但实际上,它是第一个广泛使用的建立在更新的容器化技术之上的工具。Docker和Linux容器对包括Vagrant、KVM、OpenStack、Mesos、Capistrano、Ansible、Chef、Puppet等工具和技术在内的许多行业领域产生了重大影响。这个清单上列出的产品对Docker的市场份额产生了直接影响,你可能已经注意到了。查看这个列表,大多数工程师会认识到这些工具涵盖了很多不同的用例,但所有这些工作流程都被Docker永久性地改变了。这主要是因为Docker显著改变了每个步骤涉及专家管理的耗时过程的期望。大多数人期望DevOps管道是完全自动化的,并且在一个步骤到另一个步骤的流程中没有任何人为干预。该列表中的技术也普遍受到称赞,因为它们可以提高生产力,这正是Docker如此受关注的原因。Docker位于过去十年中一些最有启发性的技术的中心位置,并且可以在几乎每个流程步骤上带来显著的改进。

如果你要对Docker和某个特定领域的领先竞争者(例如配置管理)进行功能对比,Docker很可能看起来像是一家普通的竞争对手。它在某些领域比其他领域更强大,但Docker带来的特点是跨越广泛的工作流挑战的功能集合。通过将应用程序测试和部署工具(如Vagrant和Capistrano)的简便性与管理虚拟化系统的简便性相结合,然后提供使工作流自动化和编排易于实现的接口,Docker提供了一个非常有益的特性集合。

很多新技术会来来去去,对最新的热潮持怀疑态度总是有益的。当Docker是一项新技术时,可以轻易地将其视为只解决了开发人员或运营团队的一些特定问题的技术。如果你将Docker视为一种伪虚拟化或部署技术,它可能并不显得非常吸引人。但Docker远不止表面看起来的那么简单。

即使在较小的组织中,要在团队之间正确地进行沟通和处理过程也很困难且往往昂贵。然而,我们生活在一个需要在团队之间传递详细信息的世界中,以取得成功。发现并实施一个减少此类沟通复杂性同时有助于生产更健壮软件的工具是一个巨大的胜利。这正是为什么Docker值得深入研究的原因。它并不是万灵药,如何在组织中实施Docker需要一些关键的思考,但Docker和Linux容器提供了解决一些实际组织问题的好方法,帮助企业更快地交付更好的软件。提供一个设计良好的Linux容器工作流程可以带来更快乐的技术团队,同时为组织的底线带来真正的节约。

那么企业最感到痛苦的地方是什么?按照当今世界的期望速度交付软件是很难做到的,随着企业从一两名开发人员发展为多个开发团队,围绕交付新版本的沟通负担变得更加沉重且难以管理。开发人员必须了解将软件交付到的环境的许多复杂性,生产操作团队需要越来越多地了解他们交付的软件的内部结构。这些都是通常要努力学习的好技能,因为它们可以带来对整个环境更好的理解,从而鼓励设计出健壮的软件,但随着组织的增长加速,这些同样的技能非常难以有效扩展。

每个公司环境的细节通常需要很多直接不为相关团队带来价值的沟通。例如,要求开发人员向运维团队询问特定库的1.2.1版本的发布将使他们放慢速度,并且对公司没有直接的业务价值。如果开发人员可以简单地升级他们使用的库版本,编写代码,用新版本进行测试并进行交付,交付时间将被明显缩短,并且部署更改时涉及的风险将减少。如果运维工程师可以在不必与多个应用程序开发团队协调的情况下升级主机系统上的软件,他们可以更快地进行移动。Docker有助于构建一种软件中的隔离层,从而减轻了人类世界的沟通负担。

除了帮助解决沟通问题,Docker在软件架构方面持有一种鼓励构建更健壮应用程序的观点。其架构理念以原子或一次性容器为中心。在部署过程中,旧应用程序的整个运行环境被丢弃。应用程序环境中的任何东西都不会比应用程序本身的寿命更长,这是一个简单的想法,但带来了重大影响。这意味着应用程序不太可能意外地依赖于前一个版本留下的工件。这意味着短暂的调试更改不太可能会在将来的版本中存在,因为它们从本地文件系统中拾取。这意味着应用程序在服务器之间高度可移植,因为所有状态都必须直接包含在部署工件中并且是不可变的,或者发送到外部依赖项,如数据库、缓存或文件服务器。

所有这些都导致应用程序不仅更具可扩展性,而且更可靠。应用程序容器的实例可以随时出现并消失,对前端网站的正常运行时间几乎没有影响。这些都是已经在非Docker应用程序中成功的经过验证的架构选择,但是Docker强制实施的设计选择意味着容器化的应用程序必须遵循这些最佳实践。这是非常好的事情。

Docker 工作流的优势

很难将Docker带来的所有优势统一分类。当良好实施时,它对组织、团队、开发人员和运维工程师都有多方面的好处。它使得架构决策更加简单,因为从主机系统的角度来看,所有应用程序本质上都是相同的。它使得编写和共享工具更加容易。没有什么东西是没有好处而只有挑战的,但Docker明显偏向于好处。以下是您在使用Docker和Linux容器时获得的更多优势:

  • 利用开发人员已经掌握的技能打包软件

许多公司不得不为发布和构建工程师创建职位,以管理创建适用于其支持的平台的软件包所需的所有知识和工具。像rpm、mock、dpkg和pbuilder等Linux工具可能很复杂,每个工具都必须独立学习。Docker将所有要求捆绑在一个包装格式中,称为开放容器倡议(OCI)标准。

  • 将应用程序软件和所需的操作系统文件系统捆绑到单一的标准化镜像格式中

过去,您通常需要打包不仅是应用程序,还包括许多依赖项,包括库和守护进程。然而,您无法确保执行环境的100%相同。对于本地编译的代码,这意味着您的构建系统需要与生产环境具有完全相同的共享库版本。所有这些使得打包变得难以掌握,并且很难在许多公司可靠地完成。通常,运行Scientific Linux的人会尝试部署在Red Hat Enterprise Linux上测试过的社区软件包,希望该软件包与他们所需的接近。使用Docker,您可以将应用程序部署到与运行所需环境相同的环境中,Docker的分层镜像使这成为一个高效的过程,确保您的应用程序在预期的环境中运行。

  • 使用打包好的工件在所有环境中的所有系统上进行测试和交付相同的工件

当开发人员提交更改到版本控制系统时,可以构建一个新的Docker镜像,该镜像可以通过整个测试过程,并在不需要重新编译或在过程的任何步骤重新打包的情况下部署到生产环境,除非有特殊需求。

  • 抽象化软件应用程序与硬件的关系而不损失资源

传统的企业虚拟化解决方案,如VMware,通常用于在物理硬件和运行在其上的软件应用程序之间创建抽象化层,以消耗资源为代价。管理虚拟机(VM)和每个VM运行的内核的超级监视器使用硬件系统的一部分资源,这些资源不再可供托管的应用程序使用。另一方面,容器只是另一个进程,通常直接与底层Linux内核交互,因此可以利用更多资源,直到达到系统或基于配额的限制。

当Docker首次发布时,Linux容器已经存在了很多年,Docker构建的许多其他技术也不是全新的。然而,Docker强大的架构和工作流选择的独特组合形成了一个比其各部分更强大的整体。Docker单独使得从2008年起就已经公开使用的Linux容器对于所有计算机工程师来说都变得易于接近和实用。Docker相对容易地将容器融入到真实公司的现有工作流程和流程中。前面讨论过的问题被很多人感受到,以至于对Docker项目的兴趣比任何人都能合理预期的要快得多。 从2013年的起步,Docker经历了快速的迭代,现在拥有庞大的功能集,并在全球范围内部署在大量生产基础设施中。它已成为任何现代分布式系统的基础层之一,并激发了许多其他人对这种方法的扩展。现在许多公司利用Docker和Linux容器作为解决他们在应用程序交付过程中面临的一些严重复杂性问题的解决方案。

Docker不是什么?

Docker可以用来解决许多传统工具通常被用来解决的挑战,然而,Docker的功能广泛性通常意味着在特定功能上它可能不够深入。例如,一些组织可能发现在迁移到Docker后可以完全移除它们的配置管理工具,但是Docker的真正优势在于虽然它可以替代某些传统工具的某些方面,但通常与它们兼容或甚至在与它们结合使用时更加强大。在以下列表中,我们探讨一些Docker并不直接替代但通常可以与之结合使用以取得良好效果的工具类别:

  • 企业虚拟化平台(VMware,KVM等)

容器不是传统意义上的虚拟机。虚拟机包含完整的操作系统,运行在由底层主机操作系统管理的超级监视器上。超级监视器创建虚拟硬件层,使得可以在单个物理计算机系统上运行多个具有完全不同操作系统的虚拟机。使用容器,主机和容器共享相同的内核。这意味着容器利用更少的系统资源,但必须基于相同的底层操作系统(例如Linux)。

  • 云平台(OpenStack,CloudStack等)

与企业虚拟化类似,容器工作流与更传统的云平台在表面上有很多相似之处。它们通常被利用来允许应用程序在响应不断变化的需求时进行水平扩展。然而,Docker并不是一个云平台。它只处理在现有Docker主机上部署、运行和管理容器。它不允许您创建新的主机系统(实例)、对象存储、块存储和许多其他通常由云平台管理的资源。也就是说,随着您开始扩展Docker工具,您将开始体验到更多与云平台传统相关联的好处。

  • 配置管理(Puppet,Chef等)

虽然Docker可以显著提高组织管理应用程序及其依赖关系的能力,但它并不直接替代传统的配置管理。Dockerfile用于定义容器在构建时的外观,但它们不管理容器的持续状态,也不能用于管理Docker主机系统。然而,Docker可以显著减少复杂的配置管理代码的需求。随着越来越多的服务器成为Docker主机,公司使用的配置管理代码库可以变得更小,而Docker可以用于在标准化OCI镜像中发布更复杂的应用程序要求。

  • 部署框架(Capistrano,Fabric等)

Docker通过创建容器镜像来封装应用程序的所有依赖关系,使得部署的许多方面变得更加简单,这些容器镜像可以在所有环境中无需更改地部署。然而,Docker本身不能用于自动化复杂的部署过程。通常仍需要其他工具来组合整个工作流程。也就是说,由于Docker和其他Linux容器工具集(如Kubernetes(k8s))提供了部署的明确定义接口,所需的部署容器的方法在所有主机上都是一致的,并且单个部署工作流程应该足够满足大多数(如果不是全部)基于Docker的应用程序的需求。

  • 开发环境(Vagrant等)

Vagrant是开发人员使用的虚拟机管理工具,通常用于模拟与应用程序将要部署的生产环境非常相似的服务器堆栈。Vagrant可以轻松在macOS和基于Windows的工作站上运行Linux软件。由Vagrant管理的虚拟机帮助开发人员尝试避免常见的“在我的机器上工作”场景,即软件在开发人员的机器上运行良好,但在其他地方无法正常运行。然而,与之前提到的许多例子一样,当您开始充分利用Docker时,在开发中减少模仿各种生产系统的需求,因为大多数生产系统将仅是Linux容器服务器,可以在本地轻松地进行复制。

  • 工作负载管理工具(Mesos,Kubernetes,Swarm等)

必须使用编排层(包括内置的Swarm模式)来协调在一组Linux容器主机上运行的工作负载,跟踪所有主机及其资源的当前状态,并记录运行的容器清单。这些系统旨在自动执行保持生产集群健康所需的常规任务,同时提供有助于人们与高度动态的容器化工作负载交互的工具。

每个部分都指出了Docker和Linux容器所打破和改进的重要功能。Linux容器提供了一种在受控和隔离的环境中运行软件的方式,而Docker引入的易于使用的命令行界面(CLI)工具和容器镜像标准使得与容器一起工作变得更加简单,并确保在整个系统上构建软件的方式是可重复的。

重要术语

以下是我们在整本书中将继续使用的一些术语,您应该熟悉它们的含义:

  1. Docker客户端(Docker client) :这是用于控制大部分Docker工作流并与远程Docker服务器通信的docker命令。
  2. Docker服务器(Docker server) :这是用于启动Docker服务器进程的dockerd命令,它通过客户端构建和启动容器。
  3. Docker或OCI镜像(Docker or OCI images) :Docker和OCI镜像由一个或多个文件系统层和一些重要的元数据组成,表示运行容器化应用程序所需的所有文件。单个镜像可以复制到多个主机。镜像通常具有仓库地址、名称和标签。标签通常用于标识镜像的特定版本(例如,docker.io/superorbita…)。Docker镜像是与Docker工具集兼容的任何镜像,而OCI镜像是符合开放容器倡议标准的特定镜像,保证与任何符合OCI标准的工具一起使用。
  4. Linux容器(Linux container) :这是从Docker或OCI镜像实例化的容器。特定容器只能存在一次;然而,您可以很容易地从相同的镜像创建多个容器。术语"Docker容器"是不准确的,因为Docker只是利用操作系统的容器功能。
  5. 原子或不可变主机(Atomic or immutable host) :原子或不可变主机是一种小巧、经过精心调整的操作系统镜像,例如Fedora CoreOS,支持容器托管和原子操作系统升级。

总结

如果您没有足够的先验知识,完全理解Docker可能会有一定的挑战。在下一章中,我们将提供Docker的全面概述:它是什么,预期如何使用它,以及在充分考虑这一切的情况下,实施Docker会带来哪些优势。