分布式系统工具包:复合容器的模式

我有幸在DockerCon 2015上提出了Kubernetes的一些想法,我想我会写一篇博客文章,向那些在那里的人分享一些想法。

在过去的两年中,容器已成为越来越流行的打包和部署代码的方式。容器映像使用现有的打包和部署工具解决了许多实际问题,但是除了这些显着的优点之外,容器还为我们提供了一个从根本上重新思考构建分布式应用程序的方式的机会。正如面向服务的体系结构(SOA)鼓励将应用程序分解为模块化的,集中的服务一样,容器也应鼓励将这些服务进一步分解为紧密协作的模块化容器。通过建立边界,容器使用户能够使用模块化的可重用组件来构建其服务,这反过来又导致服务比从单体容器构建的应用程序更可靠,可扩展性更高且构建速度更快。

从许多方面来看,从虚拟机到容器的转换就像从1970年代和80年代初期的单片程序到1980年代后期及以后的模块化面向对象程序的转换一样。容器图像提供的抽象层与面向对象编程中的类的抽象边界有很多共同点,并且它提供了提高开发人员生产率和应用程序质量的相同机会。就像正确的编码方式是将关注点分离到模块化对象中一样,将应用程序打包在容器中的正确方法就是将关注点分离到模块化容器中。从根本上讲,这不仅意味着将整个应用程序分解,而且还将任何一台服务器中的部件分解成多个易于参数化和重复使用的模块化容器。这样,就像现代语言中普遍使用的标准库一样,大多数应用程序开发人员可以将其他人编写的模块化容器组合在一起,并以更快的速度和更高质量的组件来构建其应用程序。

考虑模块化容器的好处是巨大的,特别是模块化容器具有以下优点:

  • 加快应用程序开发的速度,因为可以在团队甚至更大的社区之间重复使用容器
  • 整理专家的知识,因为每个人都在一个容器化的实现上进行协作,该实现反映了最佳实践,而不是无数种功能大致相同的自产容器
  • 启用敏捷团队,因为容器边界是自然界线和团队职责合同
  • 提供关注点分离,并专注于特定功能,以减少意大利面条的依赖性和不可测试的组件

从模块化容器构建应用程序意味着要考虑协同工作以提供服务的一组共生容器,而不是每个服务一个容器。在Kubernetes中,此模块化容器服务的实施例是Pod。 Pod是一组共享资源的容器,例如文件系统,内核名称空间和IP地址。 Pod是Kubernetes集群中调度的原子单位,正因为Pod中容器的共生性要求将它们共同调度到同一台机器上,而可靠地实现这一目标的唯一方法是使容器组成为原子调度单位。

当您开始使用Pod进行思考时,自然会出现一些重复出现的模块化应用程序开发的一般模式。我相信,随着我们在Kubernetes的发展中前进,将会发现更多这些模式,但是下面是我们常见的三种模式:

范例1:Sidecar容器

Sidecar容器扩展并增强了“主”容器,它们采用现有容器并使其变得更好。例如,考虑一个运行Nginx Web服务器的容器。添加另一个将文件系统与git存储库同步的容器,在这些容器之间共享文件系统,并且您已经构建了Git Push-to-deploy。但是您已经以模块化的方式完成了该工作,其中git同步器可以由不同的团队构建,并且可以在许多不同的Web服务器(Apache,Python,Tomcat等)上重复使用。由于这种模块化,您只需编写和测试git同步器一次,即可在众多应用中重复使用。而且,如果有人编写它,您甚至不需要这样做。

边柜

范例2:大使容器

大使容器代表着与世界的本地联系。作为示例,考虑具有只读副本和单个写入主机的Redis群集。您可以创建一个Pod,以将您的主应用程序与Redis大使容器进行分组。大使是代理,负责拆分读写,并将其发送到适当的服务器。因为这两个容器共享一个网络名称空间,所以它们共享一个IP地址,您的应用程序可以在“ localhost”上打开连接并找到代理,而无需任何服务发现。就您的主应用程序而言,它只是连接到本地主机上的Redis服务器。这很强大,不仅因为关注点分离以及不同团队可以轻松拥有组件这一事实,还因为在开发环境中,您可以直接跳过代理并直接连接到在本地主机上运行的Redis服务器。

大使箱

示例#3:适配器容器

适配器容器对输出进行标准化和标准化。考虑监视N个不同应用程序的任务。可以使用不同的导出监视数据的方式来构建每个应用程序。 (例如JMX,StatsD,特定于应用程序的统计信息),但是每个监控系统都希望其收集的监控数据具有一致且统一的数据模型。通过使用复合容器的适配器模式,您可以通过创建Pod(将应用程序容器与知道如何进行转换的适配器分组在一起)来将来自不同系统的异构监视数据转换为单个统一表示。同样,由于这些Pod共享名称空间和文件系统,因此这两个容器的协调既简单又直接。

适配器容器

在所有这些情况下,我们都使用了容器边界作为封装/抽象边界,它使我们能够构建模块化的,可重用的组件,并结合起来以构建应用程序。这种重用使我们能够更有效地在不同的开发人员之间共享容器,在多个应用程序之间重用我们的代码,并且通常可以更快地构建更可靠,更强大的分布式系统。希望您已经了解Pod和复合容器模式如何使您能够更快地构建健壮的分布式系统,并实现容器代码的重用。要在自己的应用程序中尝试这些模式。我鼓励您去看看开源的Kubernetes或Google Container Engine。

  • Google软件工程师Brendan Burns