如何选择?API网关、Ingress控制器还是服务网格

NGINX | 2021年12月09日

在2021年举办的几乎每场有关Ingress控制器和服务网格的网络研讨会中,我们都会听到以下问题的不同表述:“此工具与API网关有何不同?”或“在Kubernetes中,是否既需要API网关,又需要Ingress控制器(或服务网格)?”

出现这种困惑完全可以理解,原因有两个:

  • Ingress控制器和服务网格可以满足许多API网关用例的需求。
  • 一些供应商将其API网关工具定位为Ingress控制器或服务网格的替代方案,也有一些供应商将这三种功能整合到一个工具中。

本文将介绍这些工具有何不同,以及在 Kubernetes 特定的 API 网关用例中应使用哪种工具。如需深入了解相关内容并观看演示,请观看网络研讨会“Kubernetes API 网关用例”。

定义

从本质上讲,API网关、Ingress控制器和服务网格都属于代理,旨在将流量引入您的环境,并在环境内部进行转发。

什么是API网关?

API网关将来自客户端的API请求路由到相应的服务。但对于这个简单定义,一个常见的重大误解是认为API网关是一种独立的技术。事实并非如此。“API网关”描述的是一组可通过不同类型的代理实现的用例,最常见的是ADC或负载均衡器和反向代理,而Ingress控制器或服务网格也日益得到采用。

对于一款工具要用作API网关必须具备哪些能力,业界尚未形成广泛共识。我们通常发现,客户需要以下能力(按用例分组):

韧性用例

  • A/B测试、金丝雀部署和蓝绿部署
  • 协议转换(例如,在JSON与XML之间转换)
  • 速率限制
  • 服务发现

流量管理用例

  • 基于方法的路由和匹配
  • 请求和响应标头及正文操作
  • 第 7 层请求路由

安全用例

  • API架构强制执行
  • 客户端身份验证和授权
  • 自定义响应
  • 精细化访问控制
  • TLS终止

几乎所有这些用例在Kubernetes中都很常见。协议转换以及对请求和响应的标头与正文进行操作则较少见,因为这些用例通常与旧版API相关,而此类API并不适合Kubernetes和微服务环境。

如需详细了解API网关用例,请参阅我们博客中的《将NGINX部署为API网关(第1部分)》。

什么是 Ingress Controller?

An Ingress控制器(也称为Kubernetes Ingress Controller,简称KIC)是一种专用的第4层和第7层代理,可将流量引入Kubernetes并转发至服务,再将流量传出(称为入站和出站流量或南北向流量)。除了流量管理之外,Ingress控制器还可用于可观测性和故障排除、安全与身份管理,以及除高级场景之外的API网关用例。

如需进一步了解如何使用Ingress控制器实现基本流量管理之外的更多功能,请参阅博客文章《Ingress控制器选择指南,第1部分:明确需求》。

什么是服务网格?

A 服务网格负责处理Kubernetes服务之间的流量(称为服务到服务流量或东西向流量),通常用于实现端到端加密(E2EE)。随着越来越多的组织启动高级部署或提出E2EE要求,服务网格的采用率虽低但正在增长。服务网格可用作靠近应用的分布式轻量级API网关,这一功能在数据平面层面通过服务网格边车实现。

请阅读我们的博客文章《如何选择服务网格》,详细了解服务网格,以及何时适合采用服务网格。

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

正如Mark Church在NGINX Sprint 2.0主题演讲中谈到的,Kubernetes与应用网络的未来:“API网关、负载均衡器和服务网格将越来越相似,并提供类似的功能。”我们完全赞同这一观点,并想进一步指出,关键在于根据使用场景和使用方式选择合适的工具。毕竟,砍刀和黄油刀都能用来切东西,但您大概不会用砍刀切早餐的吐司。

那么,如何确定哪种工具适合您?简单来说,如果需要在Kubernetes中使用API网关功能,通常最好选择可通过YAML等Kubernetes原生配置工具进行配置的工具,一般是Ingress控制器或服务网格。不过,您可能会问:“我的API网关工具比Ingress控制器(或服务网格)多出这么多功能,不用它岂不是会错过什么?”并不会!功能更多并不代表工具更好,尤其是在Kubernetes中,工具过于复杂可能会带来严重问题。

注意: Kubernetes 原生(不同于Knative),是指专为 Kubernetes 设计和构建的工具。通常,这些工具可与 Kubernetes CLI 配合使用,可通过 Helm 安装,并可与 Kubernetes 功能集成。

大多数Kubernetes用户更倾向于选择可按Kubernetes原生方式配置的工具,因为这样无需改变开发或GitOps体验。支持YAML的工具可带来三大优势:

  • Kubernetes团队熟悉YAML,因此,如果使用现有Kubernetes工具实现API网关功能,几乎不需要学习,甚至可以直接上手。这有助于团队运用现有技能开展工作,无需学习如何配置可能只是偶尔使用的新工具。
  • 您可以像自动化其他Kubernetes工具一样,自动化支持YAML的工具。能够顺畅融入现有工作流的工具更容易获得团队认可,从而提高团队采用该工具的可能性。
  • 可以使用Ingress控制器、服务网格或两者来精简Kubernetes流量管理工具栈。毕竟,每增加一跳都会产生影响,没有必要引入额外的延迟或单点故障。当然,减少Kubernetes中部署的技术数量也有助于控制预算并提升整体安全性。

南北向API网关用例:使用Ingress控制器

Ingress控制器有望支持多种API网关用例。除了定义中概述的用例外,我们发现,组织最看重的是能够实现以下功能的Ingress控制器:

  • 身份验证和授权卸载
  • 基于授权的路由
  • 第 7 层路由和匹配(HTTP、HTTP/S、标头、Cookie、方法)
  • 协议兼容性(HTTP、HTTP/2、WebSocket、gRPC)
  • 速率限制

示例场景:方法级路由

您希望实现方法级匹配和路由,并使用Ingress控制器拒绝API请求中的POST方法。

一些攻击者会发送不符合API定义的请求类型,以寻找API中的漏洞。例如,向定义为仅接受GET请求的API发送POST请求。Web应用防火墙(WAF)无法检测此类攻击,因为它们只检查请求字符串和请求正文中是否存在攻击。因此,建议在Ingress层使用API网关来阻止恶意请求。

方法级路由拓扑图,其中NGINX Ingress Controller会拒绝向仅接受GET请求的API发送的POST请求等不合规请求

例如,假设刚刚将新API /coffee/{coffee-store}/brand 添加到集群中。第一步是使用NGINX Ingress Controller公开该API,只需将其添加到upstreams字段即可。

apiVersion: k8s.nginx.org/v1kind: 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/{coffee-store}/brand路径,并添加两个使用$request_method变量的条件,以区分GET请求和POST请求。使用HTTP GET方法的所有流量都会自动转发到coffee服务。使用POST方法的流量则会被定向到错误页面,并显示消息“You are rejected!”。这样就能保护新API免受不需要的POST流量影响。

routes: - path: /coffee/{coffee-store}/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

如需详细了解如何结合错误页面使用方法级路由和匹配,请参阅NGINX Ingress Controller文档。如需了解使用Ingress控制器实现API网关功能的安全相关示例,请阅读博客文章《使用Okta和NGINX Ingress Controller为Kubernetes实现OpenID Connect身份验证》。

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

对于大多数API网关用例,并不需要服务网格,甚至在初期也未必有帮助,因为大多数预期功能都可以且应当在Ingress层实现。但随着架构日益复杂,使用服务网格更有可能带来价值。我们认为较有价值的用例与端到端加密(E2EE)和流量拆分有关,例如A/B测试、金丝雀部署和蓝绿部署。

示例场景:金丝雀部署

您希望在服务之间设置金丝雀部署,并根据HTTP/S条件进行条件路由。

这样做的优势在于,可以逐步推出API变更(例如新功能或新版本),而不会影响大部分生产流量。

目前,NGINX Ingress Controller在NGINX Service Mesh管理的两个服务Coffee.frontdoor.svc和Tea.frontdoor.svc之间路由流量。这些服务接收来自NGINX Ingress Controller的流量,并将其路由到相应的应用功能,包括Tea.cream1.svc。您决定重构Tea.cream1.svc,并将新版本命名为Tea.cream2.svc。为了让Beta测试人员对新功能提供反馈,您根据他们的唯一会话Cookie配置金丝雀流量拆分,确保普通用户只使用Tea.cream1.svc。

使用NGINX Service Mesh进行金丝雀部署的拓扑图

使用NGINX Service Mesh时,首先在Tea.frontdoor.svc前端代理的所有服务(包括Tea.cream1.svc和Tea.cream2.svc)之间创建流量拆分。要启用条件路由,请创建一个名为tea-hrg的HTTPRouteGroup资源,并将其与该流量拆分关联。这样,只有来自Beta用户的请求(会话Cookie设置为version=beta的请求)才会从Tea.frontdoor.svc路由到Tea.cream2.svc。普通用户仍只能使用Tea.frontdoor.svc后端的版本1服务。

apiVersion: split.smi-spec.io/v1alpha3kind: 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的流量比例启动金丝雀部署,这意味着所有Beta测试人员都会使用Tea.cream2.svc。当然,也可以根据Beta测试策略采用任意合适的初始比例。Beta测试完成后,可以使用简单的金丝雀部署(不使用Cookie路由)来测试Tea.cream2.svc的韧性。

请参阅我们的文档,详细了解如何使用NGINX Service Mesh进行流量拆分。上述流量拆分配置采用自引用方式,因为根服务也被列为后端服务。Service Mesh Interface规范(smi-spec)目前不支持此配置;不过,该规范目前处于Alpha阶段,可能会发生变化。

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

虽然Kubernetes中的大多数API网关用例都可以(也应该)通过Ingress控制器或服务网格来解决,但在某些特殊情况下,适合使用NGINX Plus等API网关工具。

业务需求

虽然多个团队或项目可以共享一组Ingress控制器,也可以针对不同环境使用专用的Ingress控制器,但在某些情况下,您可能会选择在Kubernetes内部署专用API网关,而不是利用现有的Ingress控制器。在Kubernetes内同时使用Ingress控制器和API网关,可以为组织满足业务需求提供更大的灵活性。相关场景包括:

  • API网关团队不熟悉Kubernetes,也不使用YAML。例如,如果团队熟悉NGINX配置,那么在Kubernetes中将NGINX Plus部署为API网关,可以减少阻碍并降低学习难度。
  • 您的平台运维团队希望仅将Ingress控制器用于应用流量管理。
  • 您有一个API网关用例,仅适用于集群中的一项服务。无需使用Ingress控制器将策略应用于所有南北向流量,您可以部署API网关,仅在需要的位置应用该策略。

将API迁移到Kubernetes环境

将现有API迁移到Kubernetes环境时,可以将这些API发布到部署在Kubernetes外部的API网关工具。在这种情况下,API流量通常先经过外部负载均衡器(用于集群间的负载均衡),再转发到配置为API网关的负载均衡器,最后到达Kubernetes集群内的Ingress控制器。

在Kubernetes中支持SOAP API

大多数现代API都使用REST构建,部分原因是RESTful或gRPC服务和API能够充分利用Kubernetes平台。不过,您可能仍有一些尚未重新架构的SOAP API。由于SOAP API未针对微服务进行优化,因此不建议在Kubernetes中使用;但在完成重新架构之前,您可能仍需将SOAP API部署到Kubernetes中。该API可能需要与基于REST的API客户端通信,因此需要在SOAP与REST协议之间进行转换。虽然Ingress控制器可以实现此功能,但由于资源开销极大,我们不建议采用这种方式。建议将API网关工具部署为每个Pod或每项服务的代理,以便在SOAP与REST之间进行转换。

Kubernetes 内外部的 API 流量管理

只有相对少数的客户希望管理跨越 Kubernetes 环境内外的 API。如果 API 管理策略的优先级高于选择 Kubernetes 原生工具,那么在 Kubernetes 中部署一个可与 API 管理解决方案集成的“Kubernetes 友好型”API 网关可能是合适的选择。

注意:与Kubernetes原生工具不同,Kubernetes友好型工具(有时也称为Kubernetes适配型)并非专为Kubernetes设计,也无法使用Kubernetes配置进行管理。不过,这类工具灵活轻量,可在Kubernetes中运行,而不会显著增加延迟,也不需要大量变通方案。

NGINX入门

NGINX为这三类部署场景均提供相应选项。

Kubernetes 原生工具:

  • NGINX Ingress Controller,基于NGINX Plus的Kubernetes Ingress控制器,可处理高级流量控制与整形、监控与可见性,以及身份验证和单点登录(SSO)。
  • NGINX Service Mesh:轻量级、开箱即用且对开发者友好的服务网格,采用NGINX Plus作为企业级边车代理。

申请30 天免费试用包含 NGINX App Protect WAF 和 DoS 的 NGINX Ingress Controller,并下载永久免费使用的 NGINX Service Mesh,即可开始使用。

如需在Kubernetes环境内部或外部部署一款与Kubernetes兼容的API网关:

  • NGINX Plus,集负载均衡器、反向代理、Web服务器和API网关于一体,提供高可用性、主动健康检查、DNS系统发现、会话持久性和RESTful API等企业级功能。可与NGINX Controller集成,[现为F5 NGINX Management Suite]以提供完整的API生命周期解决方案。

要详细了解如何将NGINX Plus用作API网关,请申请30天免费试用,并参阅《将NGINX部署为API网关》。


分享
标签: F5 NGINX, Tech, 2021

关于作者

相关博客文章

NGINX Plus R26 正式发布
NGINX | 2022/02/15

NGINX Plus R26 正式发布

NGINX Plus R26通过缓存JSON Web密钥集加快JWT验证,并强化TLS握手,从而提升安全性。NGINX JavaScript的新功能包括增强对异步函数的支持,以及实现WebCrypto API。

使用NGINX App Protect DoS保护gRPC应用,抵御严重的DoS攻击
NGINX | 2022/02/10

使用NGINX App Protect DoS保护gRPC应用,抵御严重的DoS攻击

gRPC具备开发人员设计和部署现代应用所需的速度与灵活性,但其开放性也使其极易受到第7层DoS攻击。NGINX App Protect DoS可保护gRPC应用免受此类破坏性攻击。

Ingress Controller 选型指南(第 2 部分):风险与面向未来的规划
NGINX | 2021/09/13

Ingress Controller 选型指南(第 2 部分):风险与面向未来的规划

了解选择错误的Ingress控制器可能带来的风险,以及如何从关键方面着手,让您的选择更好地适应未来需求。

NGINX Plus R19 正式发布
NGINX | 2019/09/03

NGINX Plus R19 正式发布

NGINX Plus R19扩展了监控功能,不仅提供更多指标,还新增了指标分析方式;增加试运行模式,用于测试限速效果;增强键值存储,以支持IP地址范围;并使限速更加动态。

NGINX现已正式加入F5
NGINX | 2019/05/09

NGINX现已正式加入F5

NGINX现已正式成为F5的一部分。Gus Robertson现任F5 NGINX业务部门负责人。他阐述了两家公司在人才、文化和愿景方面融合的价值,以及双方将如何携手增强NGINX的开源产品和商业产品。

使用NGINX和NGINX Plus实现高性能缓存
NGINX | 2016/08/24

使用NGINX和NGINX Plus实现高性能缓存

我将介绍NGINX在内容缓存和性能方面的工作原理,并分享一些控制NGINX内容缓存方式的技巧。