现如今的开发人员希望可以开发出具备弹性和可扩展的分布式系统。该系统受益于软件复用和开源模型创新,针对安全性问题能够轻易完成补丁更新并进行低风险的升级。该系统不可能通过带有各种嵌入式语言库的应用程序框架来实现。最近,一篇关于“多运行时微服务体系结构”的文章,其中探讨了分布式系统的需求,例如生命周期管理,高级网络,资源绑定,状态抽象以及这些抽象概念多年来的变化。
在以Kubernetes为中心的分布式系统的发展过程中,形成了以Kubernetes Operators和sidecar作为分布式系统交付的主要创新机制。
基于Kubernetes构建的软件应用,其架构的发展正朝着Kubernetes Operators和sidecar模型发展。Kubernetes Operators和sidecar可能会成为主流的软件分发和消费方式,在极端情况下甚至会像我们过去那样取代软件库和框架。Sidecar模型允许以不同语言编写的应用程序组合完成交付,而无需与运行时捆绑。
接下来让我们看一下Kubernetes Operators和sidecar的一些具体示例,然后我们将探索这种新的模型如何影响我们后续的开发模式。
一、智能化进程外延
在Kubernetes中,sidecar是通过在单个Pod中组织多个容器而实现的核心设计模式之一。Pod功能可确保将容器与指定节点绑定,并通过网络,文件系统或其他IPC来进行协作。并且Operator可以将sidecar与平台的其余部分进行自动化管理和集成。sidecar代表了语言无关性,可扩展的数据平面,为定制应用程序提供了分布式原语。Operator代表了集中化管理和控制平面。
让我们看一下基于Sidecar模型的一些流行的开源项目。
Envoy
Istio,Consul等服务网格使用诸如Envoy之类的透明服务代理为分布式系统提供增强型联网功能。Envoy具备高安全性、高级流量管理、弹性、深度监控和跟踪特性。
不仅如此,它支持越来越多的七层协议产品,例如Redis,MongoDB,MySQL和Kafka。它增加了响应缓存功能,甚至还支持WebAssembly,这些功能将支持各种自定义插件。Envoy是透明服务代理如何将高级网络功能添加到分布式系统而不将其涵盖在分布式应用程序组件的运行时的一个典型示例。
Skupper
除了典型的服务网格外,还有一些项目(如Skupper)可通过外部代理透传应用程序网络流量。Skupper通过7层虚拟网络解决了多集群Kubernetes的通信难题,并提供了高级路由和连接功能。但是,它没有将Skupper嵌入到业务服务运行时中,而是在每个Kubernetes名称空间运行一个实例。
Cloudstate
Cloudstate是Sidecar模型的另一个示例,但这一次是为serverless开发模型提供有状态抽象。它通过GRPC提供有状态原语,用于EventSourcing,CQRS,Pub / Sub,键值存储和其他用例。这次是serverless编程模型涵盖Operators和sidecar的例子。
Dapr
Dapr是由Microsoft发起的一个相对较年轻的项目,它还是使用sidecar模型来提供以开发人员为中心的分布式系统原语。Dapr为状态管理,服务调用和故障处理,资源绑定,发布/订阅,分布式跟踪等提供抽象。尽管Dapr和Service Mesh提供的功能有些重叠,但两者在本质上却大有不同。带有Istio的Envoy被注入并在
服务中透明运行,其代表一种操作工具。另一方面,必须从应用程序运行时通过HTTP或gRPC显式调用Dapr,它是面向开发人员的显式工具。其是一个用于分布
式原语的库,可作为sidecar进行分发和使用,该模型对于使用分布式功能的开发人员变得非常有吸引力。
Camel K
Apache Camel是一个成熟的集成库。其子项目Camel K大量使用Operators模型来改善开发人员体验并与Kubernetes平台进行深度集成。虽然Camel K不依赖于sidecar,但通过其CLI和Operators,它能够在不到一秒钟的时间内重用同一应用程序容器并在远程Kubernetes集群中执行任何本地修改代码。
这些只是通过Operators和sidecar探索各种可能的一些探索项目。为了减少基于容器的分布式体系结构(如数据平面开发工具包(DPDK))引入的网络开销,需要做更多的工作,该工具包是一种用户空间应用程序,它绕过Linux内核网络堆栈直接访问网络硬件。Kubernetes项目正在进行一些工作,以创建具有更精细的生命周期保证的sidecar容器。有一些基于GraalVM实现的Java项目,例如Quarkus,它们减少了资源消耗和应用程序启动时间,这些创新的尝试使得sidecar更具有吸引力。并为更多此类项目的诞生提供了可能。
看到围绕更具体用例的项目,例如sidecar上的作业调度程序对长期运行的有状态编排(例如,BPMN引擎)进行的处理。无状态集成引擎,如Sidecar中的Enterprise Integration Patterns实现;sidecar中的数据抽象和数据联合引擎;sidecar中的OAuth2 / OpenID代理;可扩展的数据库连接池;可用于无人驾驶汽车中的serverless工作负载;应用程序网络,如辅助工具等。但是,为什么软件供应商和开发人员会切换到这种模式?
接下来介绍这种模式带来的优越性。
二、模式的优势
控制平面的运行时
作为软件供应商,可能已经考虑过将软件以API或基于SaaS的解决方案的方式提供给客户,这是最快的软件消费模型。根据软件的性质,您可能还会将软件作为工具库或运行时框架进行产品分发,也许现在是时候考虑是否将其以operator方式提供。这种软件的分发机制和体系结构具有一些可执行文件无法提供的特有的好处。
支持多语言
通过协议标准或者标准库,为多数编程语言提供开发方案。使用sidecar方式运行并通过HTTP协议对外暴露接口的方式,而无需任何特定的运行时库。即使采用gRPC和Protobuf协议用于处理低延迟和高性能的交互,生成此类客户端也比在应用程序运行时中包含第三方自定义库和实现某些接口来的容易得多。兼容性 显式的sidecar体系结构(与透明的sidecar体系结构相反)是一种软件消费方式,其作为一个独立运行时,支持面向开发人员为中心的API。它作为一种通用特性,可以添加到任何应用程序中,无论是单体,微服务,还是基于函数的架构。在Kubernetes上创建辅助工具很简单,并且在其他软件编排平台上也可行。容错性
业务逻辑始终是内部定制和开发的。分布式系统原语是众所周知的产品功能,并且已作为平台功能或产品库使用。您可能正在使用来自第三方的开源项目或商业软件来实现消息传递,网络弹性和监视。这些第三方软件的发布周期、关键代码的修复和CVE补丁同样会影响您的软件发布周期。当第三方库作为单独的运行时(sidecar)使用时,升级过程会更简单,因为它位于API服务的后面,并且不与应用程序运行时解藕。软件开发团队与第三方软件之间的解藕变得更易于管理。
控制平面
当某个功能作为库使用时,它就包含在应用程序的运行时中,您有责任了解它的工作方式,其中包括配置、监控、性能和升级。语言的运行时(例如JVM)和运行时框架(例如Spring Boot或应用程序服务器)决定了如何处理配置、监视和升级方案。当软件功能作为单独的运行时使用(例如,sidecar或独立容器)时,它将以Kubernetes operator的形式提供其控制平面。由于控制平面了解其管理的软件并具备必要的智能化管理特性,否则它将作为文档和最佳实践进行分发。此外,运营商还与Kubernetes进行了深度集成,提供了平台集成和operator开箱即用的奇妙组合。operator由同一开发人员创建,他们了解容器化功能的内部结构,并且知道如何最佳地操作。operator是容器中的SRE,随着更多operator及其应用市场的兴起,operator的数量及其功能正在稳步增长。
三、未来软件发行
以sidecar方式分发软件并附带管理平面
假设您是Java框架的软件提供商,我们可以以Maven配置方式进行分发。当然更进一步,我们可以直接以容器镜像方式分发。无论采用何种方式,在当今的云原生世界中,都未达到尽善尽美的地步。用户仍然需要知道如何在零停机状态下对应用程序程序进行热更新,同时需要知道应该备份的内容以及如何配置其监控并设置告警阈值。他们必须知道如何检测复杂故障并解决。他们必须知道如何根据当前的负载配置文件来调整应用程序。
在处理上述类似的场景时,Kubernetes以operator方式提供管理平面的方案将是最优解。operator包含应用程序和以关联业务特性的配置方式来以管理工作负载的组件。
Sidecars和operators正在成为主流的软件分发和消费方式,在某些情况下甚至会像我们过去那样取代软件库和框架。
假设您提供的软件库作为依赖项包含在使用者应用程序中。可能是上面描述的后端框架的客户端库。例如,如果它是在Java中,那么您可能已经在J2EE服务器上运行,前提是Spring启动程序、构建程序、工厂和其他实现都隐藏在Java接口后面,这样你甚至可以把它移植到golang。
有了Kubernetes的operator和sidecars之后,所有这些都对消费者透明。工厂类被operator取代,唯一的配置接口是自定义资源的YAML文件。然后,operator负责配置软件,以便用户可以将其作为一个显式的sidecar来使用。在所有情况下,您的应用程序都可以通过远程API调用,并与平台功能甚至其他依赖的operator完全集成。
通过远程API而不是嵌入式库使用的软件
换种角度来看,sidecar的作用类似于OOP中继承原则的组合,但是在多语言环境中。通过组合来自不同进程的功能,而不是将它们作为依赖项包含在单个应用程序中,这是一种组织应用程序功能的不同方式。当您将软件用作库时,可以实例化一个类,并通过传递一些值来调用其方法。当您将其用作进程外功能时,您将访问本地进程。在此模型中,方法被API取代,进程内方法被HTTP或gRPC调用所取代,并使用CloudEvents之类的通信标准。这是从应用程序服务器到Kubernetes的分布式运行时的转变。这是从特定语言的界面到远程API的转变。从内存调用到HTTP,从值对象到CloudEvents,等等。
这要求软件提供商分发容器和控制器以对其进行管理。创建能够在本地构建和调试多个运行时服务的IDE。用于代码更新并配置控制平面以快速部署到Kubernetes的CLI。可以决定在自定义应用程序运行时中进行编译的内容,可以从Sidecar输出哪些能力以及从业务流程平台获得哪些功能。
从长远来看,这将导致标准API的合并,这些标准API用于消耗sidecar中的通用能力。除了特定语言的标准和API,我们将使用多语种API。例如,除了Java数据库连接(JDBC)API,Java缓存API(JCache),Java持久性API(JPA)之外,我们还将使用CloudEvents之类的基于HTTP的多语言API。以Sidecar为中心API,如用于消息传递,缓存,可靠的网络,cron作业和计时器调度,资源绑定(其他API,协议的连接器),幂等性,SAGA等。所有这些功能都将随表格中包含的管理层一起提供,甚至包含自助式用户管理界面。operator是上述特性的关键推动力,因为它们将使分散的架构易于在Kubernetes上进行管控。operator的管理接口由CustomResourceDefinition定义,代表第三方资源面向公众管理的API。
在交付速度和可操作性的驱动下,这是一种思想上的巨大转变,其转向了一种革命性的软件分发和使用的方式。这是从单一运行时架构到多运行时应用程序架构的转变。这与摩尔定律结束后硬件行业从单核平台向多核平台的转变历史。这一变化正在慢慢发生:我们已经统一采用标准化容器,我们已经基于Kubernetes确定了事实上的编排标准,随着推出的sidecar,以及operator的广泛应用,以及CloudEvents标准的深入人心,标准化的API和生态系统也会随之出现。
参考资料
Operators及Sidecars成为软件交付新模式
End
乐于输出干货的CloudNative相关技术公众号:DCOS。