API Gateway、Ingress Controller 、Service Mesh怎么选

定义

它们的核心,API网关、Ingress Controller和服务网格都是一种代理,他们就是将流量通过他们来管理。

什么是API Getway?

API网关将API请求从客户端路由到适当的服务。但是关于这个简单定义的一个很大的误解是认为API网关是一种独特的技术。事实并非如此。相反,API网关描述了一组用例,这些用例可以通过不同类型的代理实现,最常见的是ADC或负载平衡器和反向代理,越来越多的是入口控制器或服务网格。

API 网关"必须具备"哪些功能,业界并没有达成太多共识。 但是我们知道他通常需要以下能力(按用例分组):

弹性:

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

流量管理

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

安全管理

  • API模式实现
  • 客户端认证和授权
  • 自定义响应
  • 细粒度的访问控制
  • TLS终止

几乎所有这些用例都在 Kubernetes 中常用。协议转换以及请求/响应标头和正文操作不太常见,因为它们通常与不太适合 Kubernetes 和微服务环境的旧 API 绑定。 要了解有关 API 网关用例的更多信息,请参阅我们博客上的将NGINX 部署为 API 网关,第 1 部分。

什么是Ingress Controller

Ingress Controller(也称为 Kubernetes 入口控制器 - 简称 KIC)是一种专门的第 4 层和第 7 层代理,它将流量传入 Kubernetes、服务并再次返回(称为入口-出口或南北向流量) )。除了流量管理之外,入口控制器还可用于可见性和故障排除、安全和身份等用例。

请参阅我们博客上的"选择 Ingress 控制器指南,第 1 部分:确定您的要求",了解有关如何使用 Ingress 控制器进行基本流量管理以外的更多信息。

什么是### Service Mesh

服务网格处理 Kubernetes 服务之间的流量(称为服务到服务或东西向流量),通常用于实现端到端加密 (E2EE)。服务网格的采用规模很小,但随着越来越多的组织启动高级部署或对 E2EE 有需求,其采用率也在不断增长。服务网格可以用作非常接近应用程序的分布式(轻量级)API 网关,这可以通过服务网格边车在数据平面级别上实现。

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

正如我们从 Mark Church 在他关于 Kubernetes 和应用程序网络的未来的 NGINX Sprint 2.0 主题演讲中听到的那样,"API 网关、负载均衡器和服务网格将继续看起来越来越相似,并提供相似的功能"。我们完全同意这一说法,并进一步补充说,这一切都是为了根据您将在何处(以及如何)使用它来选择适合工作的工具。毕竟,砍刀和黄油刀都用于切割,但你可能不会在早上的吐司上使用前者。

那么您如何决定哪种工具适合您呢?我们简单来看:如果您需要 Kubernetes 内的 API 网关功能,通常最好选择可以使用本机 Kubernetes 配置工具(例如 YAML)进行配置的工具。通常是Ingress Controller或服务网格。但我们听到您说,"我的 API 网关工具比我的 Ingress 控制器(或服务网格)拥有更多的功能 - 难道我没有错过吗?"不!更多的功能并不等于更好的工具,特别是在 Kubernetes 中,工具的复杂性可能是一个杀手。

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

大多数 Kubernetes 用户更喜欢用 Kubernetes 原生方式配置的工具,因为这样可以避免改变开发或 GitOps 体验。 YAML工具具有三大优势:

  • YAML 是 Kubernetes 团队熟悉的语言,因此如果您使用现有的 Kubernetes 工具来实现 API 网关功能,则学习曲线很小,甚至根本不存在。这有助于您的团队在现有技能范围内工作,而无需学习如何配置他们可能偶尔使用的新工具。
  • 您可以像其他 Kubernetes 工具一样自动化 YAML 友好的工具。任何完全适合您的工作流程的东西都会受到您的团队的欢迎 - 增加他们使用它的可能性。
  • 您可以使用 Ingress Controller、服务网格或两者来缩小 Kubernetes 流量管理工具堆栈。毕竟,每一个额外的跃点都很重要,没有理由增加不必要的延迟或单点故障。当然,减少 Kubernetes 中部署的技术数量也有利于您的预算和整体安全性。

南北 API 网关用例:使用Ingress Controller

Ingress Controller可以支持许多 API 网关用例。除了定义中概述的内容之外,我们发现最看重能够实现以下功能的 Ingress 控制器:

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

示例场景:方法级路由

您想使用Ingress Controller拒绝API请求中的POST方法。 一些攻击者通过发送不符合API定义的请求类型来寻找API中的漏洞 - 例如,将POST请求发送到仅接受GET请求的API。 Web应用程序防火墙(WAF)无法检测到这类攻击 - 他们仅检查请求字符串和body以进行攻击 - 因此,最好在Ingress层使用API网关来阻止恶意请求。

例如,假设新的API/Coffee/{coffee-store}/brand 刚刚添加到您的群集中。 第一步是使用NGINX Ingress Controller暴露API - 只需将API添加到上游字段中即可。

yaml 复制代码
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

启用方法级匹配,您可以在路由字段中添加 /coffee/{coffee-store}/brand 路径,并添加两个使用$ request_method变量来区分GET和POST请求的条件。 使用HTTP GET方法的任何流量将自动传递给咖啡服务。 使用POST方法的流量重定向到一个错误页面,并带有消息"您被拒绝!" 就这样,您保护了新的API不会接受到不需要的POST流量。

yaml 复制代码
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文档。 有关与API网关功能使用Ingress Controller使用的安全性相关示例,请在我们的博客上使用OKTA和NGINX INGRESS COLLLANTER为KUBERNETES实现OpenID连接身份验证

东西API网关用例:使用Server Mesh

对于大多数API网关用例,不需要服务网格,因为您可能想完成的大部分可能会在入口层上发生并且应该发生。 但是,随着复杂性的增加,您更有可能从使用服务网格中获得价值。 我们发现最有益的用例与E2EE和流量分裂有关,例如A/B测试,金丝雀部署和蓝绿色部署。

案例:金丝雀部署

您想根据HTTP/S标准在有条件的路由下设置服务之间的金丝雀部署。

优点是您可以逐渐推出API更改(例如新功能或版本),而不会影响大多数生产流量。 当前,您的NGINX Ingress Controller在由Nginx服务网络管理的两个服务之间路由流量:Coffee.frontdoor.svcand 和Tea.frontdoor.svc。

这些服务从Nginx Ingress Controller接收流量,并将其路由到适当的应用程序功能,包括Tea.Cream1.svc。 您决定重构Tea.cream1.svc,调用新版本tea.cream2.svc。 您希望您的Beta测试人员提供有关新功能的反馈,以便根据Beta Testers的独特会话cookie配置金丝雀流量拆分,以确保您的常规用户到tea.cream1.svc。

使用NGINX Server Mesh,您首先在所有由Tea.frontdoor.svc前面的服务之间创建流量,其中包括Tea.Cream1.svc和Tea.Cream.Cream2.SVC。 要启用条件路由,您可以创建一个httproutegroup资源(命名为tea-hrg)并将其与流量拆分相关联,其结果是只有从beta用户请求(带有session cookie设置为version = beta的请求)才能从 tea.frontdoor.svc to tee.cream2.svc。 您的常规用户继续仅在tea.frontdoor.svc。

yaml 复制代码
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"
相关推荐
酷爱码29 分钟前
springboot 动态配置定时任务
java·spring boot·后端
计算机-秋大田42 分钟前
基于SpringBoot的美食烹饪互动平台的设计与实现(源码+SQL脚本+LW+部署讲解等)
vue.js·spring boot·后端·课程设计·美食
加油,旭杏1 小时前
【go语言】grpc 快速入门
开发语言·后端·golang
brzhang1 小时前
墙裂推荐一个在 Apple Silicon 上创建和管理虚拟机的轻量级开源工具:lume
前端·后端
沈韶珺2 小时前
Visual Basic语言的云计算
开发语言·后端·golang
沈韶珺3 小时前
Perl语言的函数实现
开发语言·后端·golang
美味小鱼3 小时前
Rust 所有权特性详解
开发语言·后端·rust
我的K84093 小时前
Spring Boot基本项目结构
java·spring boot·后端
慕璃嫣4 小时前
Haskell语言的多线程编程
开发语言·后端·golang
晴空๓4 小时前
Spring Boot项目如何使用MyBatis实现分页查询
spring boot·后端·mybatis