API网关、入口控制器或服务网格:何时使用什么以及为什么

API网关将API请求从客户端路由到适当的服务。但对这个简单定义的一个很大误解是,API网关是一种独特的技术。

本文来自微信公众号“开源云中文社区”。

在几乎每次关于入口控制器和服务网格的对话中,我们都会听到一些不同的问题,“这个工具与API网关有什么不同?”或“我需要Kubernetes中的API网关和入口控制器(或服务网格)吗?”

这种混淆是可以理解的,原因有两个:

——入口控制器和服务网格可以满足许多API网关用例。

——一些供应商将其API网关工具定位为使用入口控制器或服务网格的替代方案,或者将多种功能整合到一个工具中。

在这里,我们将讨论这些工具的区别,以及用于Kubernetes特定API网关用例的工具。

定义

在其核心,API网关、入口控制器和服务网格都是一种代理类型,旨在将流量引入你的环境及其周围。

什么是API网关?

API网关将API请求从客户端路由到适当的服务。但对这个简单定义的一个很大误解是,API网关是一种独特的技术。事实并非如此。相反,“API网关”描述了一组可以通过不同类型的代理实现的用例,最常见的是ADC或负载均衡器和反向代理,越来越多的是入口控制器或服务网格。事实上,我们经常看到用户,从初创企业到企业,将开箱即用的NGINX部署为具有反向代理、web服务器或负载均衡器的API网关,并定制配置以满足其用例需求。

对于工具作为API网关的“必备”功能,业界并没有太多共识。我们通常看到客户需要以下能力(按用例分组):

弹性用例:

——A/B测试、金丝雀部署和蓝绿部署

——协议转换(例如JSON和XML之间)

——速率限制

——服务发现

流量管理用例:

——基于方法的路由和匹配

——请求/响应头和主体操作

——第7层的请求路由

——重试和保持

安全使用案例:

——API架构强制

——客户端身份验证和授权

——自定义响应

——细粒度访问控制

——TLS终止

几乎所有这些用例都在Kubernetes中常用。协议转换、请求/响应头和主体操作不太常见,因为它们通常与不太适合Kubernetes和微服务环境的遗留API绑定。它们也倾向于指示不太可能在Kubernetes中运行的单体应用程序。

什么是入口控制器?

入口控制器是一个专门的第4层和第7层代理,它将流量送入Kubernetes、服务,然后再次退出(称为入口-出口或南北流量)。除了流量管理之外,入口控制器还可以用于可见性和故障排除、安全性和身份,以及除最高级API网关用例之外的所有其他用途。

什么是服务网格?

服务网格处理Kubernetes服务之间的流量(称为服务到服务或东西向流量)。它通常用于实现端到端加密(E2EE),并将TLS应用于所有流量。服务网格可以用作与应用程序非常接近的分布式(轻量级)API网关,通过服务网格sidecars可以在数据平面级别实现。

注意:选择服务网格是一个值得考虑的过程。

在Kubernetes环境中使用Kubernetes原生工具

如何决定哪种工具适合你呢?我们将使其变得简单:如果需要Kubernetes内部的API网关功能,通常最好选择一个可以使用本地Kubernete配置工具(如YAML)进行配置的工具。通常,这是一个入口控制器或服务网格。但我们听到你说:“我的API网关工具比我的入口控制器(或服务网格)有更多的功能。我错了吗?”不!更多的功能并不等于更好的工具,特别是在Kubernetes中,工具的复杂性可能是一个杀手。

注意:“Kubernetes native”(与Knative不同)是指为Kubernete设计和构建的工具。通常,它们使用Kubernetes CLI,可以使用Helm安装并与Kubernete功能集成。

大多数Kubernetes用户更喜欢可以以Kubernete原生方式配置的工具,因为这避免了对开发或GitOps体验的更改。YAML友好的工具提供三大优势:

——YAML是Kubernetes团队熟悉的语言,因此如果使用现有的Kubernete工具实现API网关功能,那么学习曲线很低,甚至不存在。这有助于团队在现有技能范围内工作,而无需学习如何配置他们可能偶尔使用的新工具。

——可以以与其他Kubernetes工具相同的方式自动化YAML友好的工具。任何完全适合工作流程的东西都会受到团队的欢迎,从而增加他们使用它的可能性。

——可以通过使用Kubernetes原生工具来收缩Kubernettes流量管理工具堆栈。每一次额外的跳跃都很重要,没有理由增加不必要的延迟或单点故障。当然,减少Kubernetes中部署的技术数量也有利于预算和总体安全。

南北API网关用例:使用入口控制器

入口控制器有可能启用许多API网关用例。除了定义中概述的那些之外,我们发现组织最重视能够实现以下功能的入口控制器:

——卸载身份验证和授权

——基于授权的路由

——第7层路由和匹配(HTTP、HTTP/S、标头、cookie、方法)

——协议兼容性(HTTP、HTTP/2、WebSocket、gRPC)

——速率限制

示例场景:方法级路由

你希望使用入口控制器实现方法级匹配和路由,以拒绝API请求中的POST方法。

一些攻击者通过发送不符合API定义的请求类型来查找API中的漏洞,例如,向定义为仅接受GET请求的API发送POST请求。Web应用防火墙(WAF)无法检测到此类攻击。它们只检查请求字符串和主体是否受到攻击,因此最好在入口层使用API网关来阻止坏请求。

360截图16251112669372.png

例如,假设新的API/coffee//brand刚刚添加到集群中。第一步是使用入口控制器公开API,只需将API添加到upstream字段即可。

apiVersion:k8s.nginx.org/v1

kind:VirtualServer

metadata:

name:cafe

spec:

host:cafe.example.com

tls:

secret:cafe-secret

upstreams:

-name:tea

service:tea-svc

port:80

-name:coffee

service:coffee-svc

port:80

要启用方法级匹配,请在routes字段中添加/coffee//brand路径,并添加两个条件,使用$request_method变量区分GET和POST请求。使用HTTP GET方法的任何流量都会自动传递给coffee服务。使用POST方法的流量被引导到一个错误页面,并显示消息“你被拒绝了!”,就这样,你已经保护了新的API免受不需要的POST流量的影响。

routes:

-path:/coffee//brand

matches:

-conditions:

-variable:$request_method

value:POST

action:

return:

code:403

type:text/plain

body:"You are rejected!"

-conditions:

-variable:$request_method

value:GET

action:

pass:coffee

-path:/tea

action:

pass:tea

东西API网关用例:使用服务网格

对于大多数API网关用例,服务网格是不需要的,甚至在最初是没有帮助的,因为可能希望完成的大部分工作都可以而且应该发生在入口层。但随着架构的复杂性增加,你更有可能从使用服务网格中获得价值。我们发现最有益的用例与E2EE和流量分割有关,例如A/B测试、金丝雀部署和蓝绿部署。

示例场景:金丝雀部署

你希望在基于HTTP/S标准的有条件路由的服务之间建立金丝雀部署。

其优点是,可以逐步推出API更改(如新功能或版本),而不会影响大部分生产流量。

目前,入口控制器在NGINX服务网格管理的两个服务之间路由流量:Coffee.frontdoor.svc和Tea.frontdoor.sevc。这些服务从入口控制器接收流量,并将其路由到适当的应用程序功能,包括Tea.ream1.svc。你决定重构Tea.ream2.svc,调用新版本Tea.ream2.svc。你希望测试人员提供有关新功能的反馈,因此根据测试人员的独特会话cookie配置金丝雀流量分割,确保普通用户只体验Tea.ream1.svc。

360截图16251112669372.png

使用服务网格,首先在Tea.frontdoor.svc提供的所有服务之间创建流量分割,包括Tea.ream1.svc和Tea.ream2.svc。要启用条件路由,请创建HTTPRouteGroup资源(名为tea-hrg)并将其与流量分割相关联,结果是,只有来自测试版用户的请求(会话cookie设置为version=beta的请求)才会从Tea.frontdoor.svc路由到Tea.ream2.svc。普通用户仍然只能体验Tea.fromtdoor.svc之后的版本1服务。

apiVersion:split.smi-spec.io/v1alpha3

kind:TrafficSplit

metadata:

name:tea-svc

spec:

service:tea.1

backends:

-service:tea.1

weight:0

-service:tea.2

weight:100

matches:

-kind:HTTPRouteGroup

name:tea-hrg

apiVersion:specs.smi-spec.io/v1alpha3

kind:HTTPRouteGroup

metadata:

name:tea-hrg

namespace:default

spec:

matches:

-name:beta-session-cookie

headers:

-cookie:"version=beta"

这个示例以0-100分割开始金丝雀部署,这意味着所有测试人员都会体验Tea.ream2.svc,但当然,你可以从符合测试策略的任何比率开始。测试完成后,可以使用一个简单的金丝雀部署(没有cookie路由)来测试Tea.ream2.svc的弹性。

何时(以及如何)为Kubernetes应用程序使用API网关工具

尽管Kubernetes的大多数API网关用例可以(也应该)通过入口控制器或服务网格来解决,但在某些特殊情况下,API网关工具是合适的。

业务要求

在Kubernetes内部同时使用入口控制器和API网关可以为组织实现业务需求提供灵活性。一些场景包括:

——API网关团队不熟悉Kubernetes,也不使用YAML。例如,如果他们对NGINX配置感到满意,那么如果他们将NGINX部署为Kubernetes中的API网关,则可以减少摩擦并减少学习曲线。

——平台运维团队倾向于将入口控制器解决方案仅用于应用流量管理。

——有一个API网关用例,它只适用于集群中的一个服务。你可以部署API网关,仅在需要时应用策略,而不是使用入口控制器将策略应用于所有的南北通信。

将API迁移到Kubernetes环境

当将现有API迁移到Kubernetes环境中时,你可以将这些API发布到部署在Kubernete外部的API网关工具中。在这种情况下,API流量通常通过外部负载均衡器(用于集群之间的负载均衡),然后路由到配置为充当API网关的负载均衡器,最后路由到Kubernetes集群内的入口控制器或网关API模块。

API网关用例的网关API的未来

如果没有对Kubernetes网关API(与API网关不同)的简要讨论,本文将是不完整的。网关API通常被视为Ingress API的继承者,可用于南北和东西交通。这意味着实现可以执行入口控制器功能、服务网格功能或两者。最终,网关API实现有可能充当所有Kubernetes流量的API网关。

网关API处于测试阶段,包括NGINX在内的许多供应商都在尝试实现。值得密切关注这个领域的创新,甚至可以自己尝试测试版。

结论:正确用例的正确工具

对于Kubernetes新手,甚至对于有大量经验的人来说,API可能会令人痛苦地困惑。我们希望这些规则能够为如何高效地构建Kubernetes架构提供指导。

当然,你的经验可能有所不同,用例或情况可能是独特的。但是,如果坚持使用Kubernetes原生工具来简化工具堆栈,并且只考虑在上面概述的非常特定的情况下使用单独的API网关(特别是在Kubernete之外),那么旅程应该会更加顺畅。

THEEND

最新评论(评论仅代表用户观点)

更多
暂无评论