本书只要介绍分布式系统,它是由运行在许多不同机器上的不同组件组成的应用程序。但是,本书的第一部分专门讨论在于单个节点上的模式。理由很简单,容器是本书所介绍的模式的基础构件,位于同一台机器上的多个容器组也是构成分布式系统模式的原子元素。
动机
虽然你可能很清楚为什么将分布式应用程序分割为一组容器运行在不同的机器上,但是你可能想问为什么要将组件运行在在同一台机器的不同容器中。为了理解这些容器组的动机,思考容器化背后的目标是很有必要的。通常,容器的目标是围绕特定资源建立边界(例如,此应用程序需要两个内核和8GB的内存)。同样,边界可以描绘团队所有权(例如,该团队拥有该镜像)。最后,边界还可以分散关注点(例如,这个镜像是做某件事的)。
上述这些原因都表明了将单台机器上的应用程序拆分为一组容器的意义。首先考虑资源隔离,假设一个应用程序可能由两个组件组成:一个是面向用户的应用程序服务器,另一个是后台配置文件加载器。很显然,对于面向终端用户的程序,请求延迟是最高优先级,因此面向用户的应用程序需要足够的资源以确保其高速响应。另一方面,后台配置加载器主要是尽力而为服务;如果在用户请求量较高的时段内及时有些轻微的延迟,系统也会正常工作。同样,后台配置加载器不应该影响最终用户接收的服务质量。由于这些原因,管理员希望将面向用户的服务和后台的配置加载器分离到不同的容器中。这使管理员可以将不同的资源需求和优先级分别附加到两个不同的容器上,例如,确保后台加载器在服务程序空闲或者无负载时可从服务程序借用一定的资源。同样,如果存在由内存泄漏或其他内存资源过度使用导致的资源争用问题时,可确保在两个容器的达到单独资源需求之前终止后台加载程序。
除了此资源隔离之外,还有其他将单节点应用程序拆分为多个容器的原因。考虑团队任务的规模,六到八人的团队规模是十分合理的。为了能够以这种方式构建团队,并且仍然需要构建完整的系统,我们需要为每个团队分配小型且重点突出的工作。此外,如果设计合理,通常一些可重复使用的模块,可供许多团队使用。例如,考虑让本地文件系统与git源代码库保持同步的任务。如果将此Git同步工具作为单独的容器来构建,那么可以在PHP,HTML,JavaScript,Python和众多其他Web服务环境中重复使用它。如果在每个容器中均单独部署,例如,将Python运行时和Git同步不可分割地绑定在一个容器中,那么这种情况下模块化复用是不可能的。
最后,即使应用程序很小,并且所有容器都由一个团队拥有,但关注点分离可确保您的应用程序能就有较好的可理解性,并且可以易于测试,更新和部署。小型、重点突出的应用程序更易于理解,与其他系统的耦合更少。这意味着在部署git同步容易时无需重新部署应用服务器,让rollouts依赖和影响范围更小。这反过来又会使得rollout和rollback更加可靠,同时为部署应用程序带来更大的灵活性和灵活性。
总结
我希望上述这些例子会促使您考虑将应用程序(即使是单个节点上的应用程序)分解为多个容器。后续章节描述的一些模式,可以帮助时引导您构建模块化容器组。与多节点分布式模式相比,所有单点模式都假设模式中所有容器之间是紧密依赖关系。特别是,假设模式中的所有容器都可以可靠地在一台机器上共同调度。文章还假定模式中的所有容器都可以任意共享文件系统的卷以及诸如网络命名空间、共享内存等其他关键容器资源。这种紧密的分组在Kubernetes中被称为pod,但这个概念通常适用于不同的容器协调器。