构建面向整合服务网格的开放 API

栏目: 编程工具 · 发布时间: 4年前

内容简介:各组织正试图利用云原生技术和基础架构来重塑它们的软件技术栈。这些技术和基础架构可以极大地提高它们快速且安全交付软件的能力。随着我们的应用程序变得越来越分散,基础架构也越来越“模糊”,在每天发布数十个(或更多)版本的情况下,维护其高可用性、正确性和安全性会变得非常困难。Kubernetes 和容器帮助我们标准化了基于“不变交付”的打包和部署模型。但是一旦这些应用程序部署后,需要通过网络进行相互通信,这给开发人员和运营商带来了很多挑战。服务网格为我们提供了一个基础框架,我们可以在此基础上构建和运行服务,从而极大

本文要点

  • 服务网格公布了用于控制服务到服务(由东到西)流量的调节器(knobs)和控制杆(levers)
  • 服务网格公布的“levers”可以被专门的工作流使用来降低发布的风险并缩短平均恢复时间(MTTR)
  • 为了从服务网格中获得真正的价值,需要在网格之上编写扩展来驱动其功能。
  • 目前,服务网格的实现因 API 和技术的不同而有所不同,并且没有任何放缓的迹象。
  • 构建在不稳定性的 API 之上可能是危险的
  • 需要一种简化的、工作流友好的服务网格 API 来保护组织平台代码免受特定服务网格实现细节的影响

各组织正试图利用云原生技术和基础架构来重塑它们的软件技术栈。这些技术和基础架构可以极大地提高它们快速且安全交付软件的能力。随着我们的应用程序变得越来越分散,基础架构也越来越“模糊”,在每天发布数十个(或更多)版本的情况下,维护其高可用性、正确性和安全性会变得非常困难。Kubernetes 和容器帮助我们标准化了基于“不变交付”的打包和部署模型。但是一旦这些应用程序部署后,需要通过网络进行相互通信,这给开发人员和运营商带来了很多挑战。服务网格为我们提供了一个基础框架,我们可以在此基础上构建和运行服务,从而极大地解决了应用程序网络通信安全及渐进式交付方面的一些挑战。

服务运营商和应用程序开发人员需要解决服务到服务的通信挑战,比如服务发现、客户端负载平衡、配置传输安全性、身份识别、流量路由、基于断路器的通信弹性、网络请求监控等。搭建跨语言或框架应用程序的过程,是非常容易出错并十分乏味的。我们使用某种语言构建了应用程序,后面我们怎样支持其他语言呢?我们为某个云平台构建的应用程序,是否可以扩展到其他平台呢?服务网格通过在每个工作负载旁注入一个服务代理来解决这些问题,通过这个服务代理,工作负载可以与网络上的任何其他服务进行交互,从而能够透明且一致地解决这些问题。

服务代理通常是专用的特定的工作负载实例,它们不与群集中的其他实例共享。这种服务代理的集合称为“数据平面”。服务网格中所有服务请求都经过这些代理,这些代理对这些服务请求加以拦截来丰富诸如重试、超时、断路、服务发现、负载平衡等强大的功能。Envoy Proxy 是一个开源的服务代理,它是实现服务网格的常用方案。由于进出工作负载实例的所有请求都遍历其服务代理,因此服务代理可以捕获相应请求的度量指标,并影响网络通信的变更。服务网格的运营商与控制平面进行交互,控制平面是一个与支持数据平面的请求路径无关的组件集。

构建面向整合服务网格的开放 API

服务网格遵循二八定律。服务网格可以让我们以云、语言和框架无关的方式,解决 80% 的应用程序网络问题。但最后 20%需要我们编写自己的“胶水代码”来驱动和操作服务网格,以“编排它”交付有价值的高阶服务。服务网格发布了一组强大的独立功能集,但是需要对它们进行整合后,才能被我们的组织充分利用。服务网格支持的高阶服务示例包括:

  • 智能自动伸缩
  • 渐进式交付
  • 通信模式检测
  • 混沌注入与分析
  • 请求溯源及监管链
  • 零信任网络实践
  • AB 实验(这是渐进式交付的更成熟版本)。

服务网格帮助我们完成了任务的 80%,但要真正实现上面的这些功能,还需要编写 20%的代码来扩展网格。

构建面向整合服务网格的开放 API

构建在服务网格之上以降低风险

我们来看一个整合了多个功能的服务网格示例,这个整合后的服务网格可以帮助我们实现降低系统变更风险的最终目标。

渐进式交付 是由 Azure Devops 的产品所有者 Sam Guckenheimer 和 Redmock 分析师 James Governor 在 2018 年创造的术语,该术语用来描述为了缩小故障的影响范围而渐进地发布新应用程序功能的方式。使用流量控制、功能标记、请求路由和度量指标收集的组合,可以按照渐进式交付技术构建强大的 CI / CD 管道,从而降低交付新代码和代码变更的风险。

在应用程序或服务代码不进行任何变更的情况下,我们可以用服务网格作为框架构建渐进式交付能力,它可以协调流量控制、请求路由、度量指标收集等功能。例如,如果我们想变更推荐服务,我们可以部署一个新版本的推荐服务,并精确地控制哪些用户被路由到新部署上。按照渐进式交付方式,我们可以将“推荐”服务的 v2 版部署到生产环境中,并且只向给内部员工公开。然后,我们观察新服务的度量指标及日志,并为继续设置交付的阈值。如果我们发现这个新版本有问题,我们可以通过回滚(或减少流量)来缩小影响范围。例如,如果我们发现请求处理过程中错误增多或延迟变长,我们可以停止这个金丝雀的渐进式交付,甚至可以将其回滚。如果新版本发现正常,我们可以开放流量给更多用户(例如,1%的实时用户)。我们遵循这种方式,逐步地向其他用户组公开新服务,并通过观察度量指标和日志来决定是继续发布还是回滚。

这个服务网格使用控制平面和数据平面架构实现,其中数据平面是一个个的服务代理,通过这些服务代理可以收集请求度量指标并执行请求路由控制。控制平面是与请求路径无关的组件集,运营商和用户可以通过和它交互来收集度量指标、建立策略及变更配置来影响数据平面。

控制平面有一个 API 接口或一些固定的方法来驱动网格的配置。在大多数开源的服务网格实现中,通常会使用声明式的配置或 API 接口,它具有“声明性意图”,服务网格负责“协调完成该意图”。例如, Istio (一个开源的服务网格)的配置被声明为描述服务网络行为意图的 YAML 资源,并且 Istio 的控制平面将此意图合成到服务代理的配置中。对于上面的“推荐”服务,我们可能希望通过拆分路由到每个版本的流量比例来控制到金丝雀版本的流量。在 Istio 中,使用“VirtualService”可以做到这一点:

复制代码

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: recommendation-vs
spec:
hosts:
- recommendation.prod.svc.cluster.local
http:
- route:
- destination:
host: recommendation.prod.svc.cluster.local
subset: v1
weight:90
- destination:
host: recommendation.prod.svc.cluster.local
subset: v2
weight:10

Istio 还能使用 statsD、Prometheus、Jaeger 等 工具 从服务代理上收集度量指标来进行分布式跟踪,之后再将这些度量指标整合到后端分析引擎。这些度量指标还可用于决策是否继续交付或发布过程。分析这些度量指标,如果指标正常,我们可以指示服务网格将 20%的实时流量路由到金丝雀版本,如果指标异常,我们可以回滚部分流量(甚至全部回滚)。

构建面向整合服务网格的开放 API

服务网格的另一个实现 AWS App Mesh 使用了类似的声明式 API 来描述流量路由规则。我们创建 JSON 资源并配置到 App Mesh 的控制平面,之后控制平面会将该 JSON 资源的意图整合到 Envoy 配置中(Envoy 是 App Mesh 的数据平面):

复制代码

{
"routeName":"recommendation-route",
"spec": {
"httpRoute": {
"action": {
"weightedTargets": [
{
"virtualNode":"recommendation-v1-vn",
"weight":9
},
{
"virtualNode":"recommendation-v2-vn",
"weight":1
}
]
},
"match": {
"prefix":"/"
}
}
},
"virtualRouterName":"recommnedation-vr"
}

AWS App Mesh 可以向 CloudWatch、X-Ray 等发送度量指标和请求遥测数据。通过这些数据,渐进式交付引擎可以评估是否继续向新版本开放流量。

LinkerdConsul Connect 等其他的服务网格实现也在开发它们自己的流量控制 API,但可能也会遵循类似的声明式 API 模式。

当我们基于服务网格实现渐进式交付时,首先要考虑哪些部分属于二八定律中的 80%,哪些部分属于 20%。虽然服务网格不仅能收集服务或请求级别的度量指标,还能控制服务的流量调度(流量转移、限制、路由),但是它无法感知服务升级或回滚的过程,如触发服务进一步发布或回滚的阈值。这样的控制逻辑是非常个性化且强依赖组织的,它需要组织在服务网格之上编写 20%的胶水代码实现。为此,组织需要使用特定的服务网格控制平面 API。

需要一个开放的服务网格 API

当一个组织想要搭建它的渐进式交付能力时,或者如前所述在服务网格之上搭建其他能力时,必须围绕它所采用的特定服务网格 API 构建相应的胶水代码。目前,所有服务网格实现的这类 API 处于不断发展变化的过程中。智能化的组织已经开始构建专用的特定配置 API 来更清晰地表达他们的意图,更好地适应在服务网格之上构建的增值服务,并对不断变化的 API 进行抽象。然后,使用转换层将它的配置转换为特定服务网格实现的 API。通过抽象特定的服务网格 API,组织可以限制任何特定服务网格 API 实现的影响范围,尤其是在升级和发布非向后兼容的变更时。

构建面向整合服务网格的开放 API

抽象出特定的服务网格 API 的另一个优势是能够在以后更换服务网格技术时,不会影响基于特定服务网格编写的那 20%的代码和功能。事实上,随着服务网格实现的不断发展变化,我们会发现,服务网格越来越专注于某个功能领域(如安全性、可观察性、流量控制等)。拥有独立的、与网格无关的 API,可以让组织整合或即插即用某些网格功能。

最后,当组织尝试将内部的流程、部署与公有云中的流程、部署统一时,用于抽象网络的独立 API 将变得越来越重要。我们为扩展内部工作负载编写的 Istio 的工具,在部署到 AWS 时仍然可以使用。例如,AWS 的 App Mesh 是一个 AWS 原生服务网格,如果将它部署到 AWS,那么利用它原生的服务网格是有意义的。通过为服务网格和在服务网格之上构建的功能提供一个统一的 API,我们在应用到新平台时无需重新造轮子,并且可以在上面安全地构建它。

一方面,由于上述原因,头部组织一直在尝试定义这种“非正式的、与网格无关的 API”,另一方面,每个组织都做这件事情,有点浪费资源。如果我们通过合作的形式构建一个开源项目,该项目在服务网格实现之上提供稳定的 API,使我们能灵活地采用所需的解决方案,使用时即插即用,并且在我们的网格基础设施之上还可以拥有 20%的集成胶水代码,这将会怎么样?

构建开放服务网格 API 的方法

SuperGloo 是一个开源项目,最初开始于构建一个开放、稳定、与网格无关的 API。如果我们使用一个简化的服务网格 API,用它抽象任何的服务网格,则可以实现如下目标:

  • 为安装任何服务网格提供一致、简化的体验
  • 构建服务网格的扩展功能(使用 20%的胶水代码)并对冲服务网格环境中的任何波动(采用选择、版本变更、同类最佳等)
  • 服务网格实现和资源发现并管理它们
  • 在单一管理平台和 API 下管理多个服务网格安装实现
  • 管理一个或多个服务网格实现的多集群

SuperGloo 有一些 API ,分别用于使用“Install”和“Mesh”配置对象来安装和解释服务网格的功能。例如,使用 SuperGloo 的“Install”API 安装 Linkerd,如下所示:

复制代码

- apiVersion: supergloo.solo.io/v1
kind:Install
metadata:
creationTimestamp:"2019-05-01T14:12:58Z"
generation:1
name:linkerd
namespace:supergloo-system
resourceVersion:"5571565"
selfLink:/apis/supergloo.solo.io/v1/namespaces/supergloo-system/installs/linkerd
uid:389b5e09-6c1b-11e9-92c9-42010a8000c0
spec:
installationNamespace:linkerd
mesh:
linkerd:
enableAutoInject:true
enableMtls:true
version:stable-2.3.0

网格特征本身在 Mesh 配置中定义:

复制代码

- apiVersion:supergloo.solo.io/v1
kind:Mesh
metadata:
creationTimestamp:"2019-05-01T14:13:09Z"
generation:1
labels:
created_by:mesh-discovery
discovered_by:linkerd-mesh-discovery
name:linkerd
namespace:supergloo-system
resourceVersion:"5571484"
selfLink:/apis/supergloo.solo.io/v1/namespaces/supergloo-system/meshes/linkerd
uid:3f70f63e-6c1b-11e9-92c9-42010a8000c0
spec:
discoveryMetadata:
enableAutoInject:true
injectedNamespaceLabel:linkerd.io/inject
installationNamespace:linkerd
meshVersion:stable-2.3.0
mtlsConfig:
mtlsEnabled:true
linkerd:
installationNamespace:linkerd
version:2.3.0
mtlsConfig:
mtlsEnabled:true

Istio 和 AWS App Mesh 的操作使用类似的方法。当我们定义网格的流量规则时,事情将变得非常有趣。例如,通过 SuperGloo,我们可以使用 RoutingRule API 给网格分配流量规则。指定一个加权路由规则在“review”服务的 v1 和 v2 之间切换流量,我们可以执行以下操作:

复制代码

- apiVersion:supergloo.solo.io/v1
kind:RoutingRule
metadata:
name:example-routing
namespace:supergloo-system
spec:
destinationSelector:
upstreamSelector:
upstreams:
- name:default-reviews-9080
namespace:supergloo-system
spec:
trafficShifting:
destinations:
destinations:
- destination:
upstream:
name:default-reviews-v1-9080
namespace:supergloo-system
weight:2
- destination:
upstream:
name:default-reviews-v2-9080
namespace:supergloo-system
weight:1
targetMesh:
name:istio
namespace:supergloo-system

请注意,SuperGloo 路由到“Upstreams”,这是另一个用于抽象特定后端目标和版本组合的 API 对象。这些“Upstreams”是根据标签自动发现的(例如,在 Kubernetes 或可能在 Consul 中的标签),我们不必显式地创建它们(尽管我们可以根据需要创建它们)。 RoutingRule 还包含指定 sourceSelector 的功能,因此我们可以选择到达应用“RoutingRule”目的地的流量来源。在此背后,这些对象创建了必要的特定网格对象。

这些对象适用于任何服务网格实现。 请查阅文档 来查看完整的 API。目前,SuperGloo 支持 Istio、Linkerd 和 AWS App Mesh,将来还会支持更多网格。

围绕特定服务网格实现的统一 API 让我们通过 SuperGloo 一致地管理任何服务网格实现,包括在有多个网格或多个集群(即使只有一个网格的多个集群)的更复杂的场景下。我们编写的 20%代码可以保持与网格无关,并在网格上提供有价值的扩展。一个很好的例子就是构建渐进式交付能力。事实上,Weaveworks 的 Flagger 项目就是这样做的, 并可以利用 SuperGloo 来保持网格无关性

感想

随着组织进一步采用服务网格技术并在它上面进行二次构建,在明确的标准出现之前,他们将疲于将其有价值的 20%代码与任何一个实现相结合。即使只有一个实现,事情也会快速发展,API 也会发生变化,这种波动可能会给那些迫不及待地使用服务网格的不同实现作为解决方案的组织造成严重破坏。使用 SuperGloo,我们可以使用 20%的代码对冲这种波动性,甚至可以处理整合了多个网格或多个群集的更高级用例。

作者简介

Christian Posta(@christianposta)是 Sloo.IO 全球 CTO,Red Hat 前首席架构师,并以图书作者(Istio in Action, Manning, Microservices for Java Developers, O’Reilly 2016)、博主、演讲人、开源传道士、开源项目贡献者的身份闻名于社区,他开源的项目包含 Istio、Kubernetes 等。Christian 在大规模企业有多年工作经验,现在致力于帮助企业创建并部署大规模、云原生、高弹性、分布式架构。他喜欢辅导、培训并领导团队从事有关分布式系统、微服务、DevOps、云原生应用程序设计的项目。

查看英文原文: Towards Building an Open API For Consolidating and Federating Service Meshes


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Bulletproof Ajax中文版

Bulletproof Ajax中文版

Jeremy Keith / 刘申、宋薇 / 人民邮电出版社 / 2007-11 / 39.00元

本书介绍了如何构建无懈可击的Ajax Web应用程序,重点讲述如何在已有Web站点使用Ajax增强网站用户体验,从而尽可能地保证网站拥有最大限度的可移植性和亲和力,这正是目前大多数网站面临的需求。书中主要介绍了JavaScript、DOM、XMLHttpRequest、数据格式等,同时还提出了一种Hijax方法,即可以让Web应用程序平稳退化的方法。 本书适合各层次Web开发和设计人员阅读......一起来看看 《Bulletproof Ajax中文版》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

SHA 加密
SHA 加密

SHA 加密工具

html转js在线工具
html转js在线工具

html转js在线工具