在Kubernetes中,Ingress是一个组件,可将流量从群集外部路由到群集中的服务和Pod。

简而言之,Ingress充当反向代理或负载平衡器:所有外部流量都路由到Ingress,然后路由到其他组件。

尽管最受欢迎的Ingress是ingress-nginx项目,但是在选择和使用Ingress时还有其他几种选择。

您可以从以下Ingress控制器中选择:

还有其他混合式Ingress控制器可以与现有的云提供商集成,例如Zalando的Skipper Ingress

当谈到Kubernetes中的API网关时,有一些流行的选择可供选择。

选项1 — API网关之王:Kong

如果要构建API,则可能会对Kong Ingress提供的功能感兴趣。

Kong是建立在Nginx之上的API网关。

Kong专注于API管理,并提供身份验证,速率限制,重试,断路器等功能。

Kong的有趣之处在于它以Kubernetes Ingress的形式打包。

因此,它可以在您的群集中用作用户和后端服务之间的网关。

您可以使用标准Ingress对象将API暴露给外部流量:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
    - host: example.com
      http:
        paths:
          - path: /
            backend:
              serviceName: api-service
              servicePort: 80

但是

在安装过程中,Kong的控制器会注册自定义资源定义(CRD)。

这些自定义扩展之一与Kong的插件有关。

如果您希望通过IP地址限制对Ingress的请求,则可以使用以下方法创建限制的定义:

apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
  name: rl-by-ip
config:
  hour: 100
  limit_by: ip
  second: 10
plugin: rate-limiting

您可以在Ingress中使用以下注释来引用限制:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    plugins.konghq.com: rl-by-ip
spec:
  rules:
    - host: example.com
      http:
        paths:
          - path: /
            backend:
              serviceName: api-service
              servicePort: 80

您可以在官方文档中浏览有关Kong的自定义资源定义(CRD)。

但是Kong不是唯一的选择。

选项2 –Ambassador,现代API网关

Ambassador是另一个基于Envoy构建的Kubernetes Ingress,它提供了强大的API网关。

Ambassador Ingress是Kubernetes Ingress控制器的现代代表,它提供了强大的协议支持以及速率限制,身份验证API和可观察性集成。

与Kong的主要区别在于Ambassador是为Kubernetes构建的,并与它很好地集成在一起。

Kong于2015年开源,当时Kubernetes Ingress控制器还不那么先进。

即使在设计Ambassador时就考虑到Kubernetes,它也不会利用熟悉的Kubernetes Ingress。

而是使用注释将服务公开给外界:

apiVersion: v1
kind: Service
metadata:
  labels:
    service: api-service
  name: api-service
  annotations:
    getambassador.io/config: |
      ---
      apiVersion: ambassador/v0
      kind: Mapping
      name: example_mapping
      prefix: /
      service: example.com:80
      host_rewrite: example.com
spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: 80
  selector:
    service: api-backend

新颖的方法非常方便,因为您可以在一个地方为Deployments和Pod定义所有路由。

但是,将YAML作为注释中的自由文本可能会导致错误和混乱。

在标准YAML中很难正确设置格式,更不用说在更多YAML中使用字符串了。

如果您希望对API应用速率限制,这就是Ambassador中的样子。

您有一个RateLimiting对象,它定义了需求:

apiVersion: getambassador.io/v1beta1
kind: RateLimit
metadata:
 name: basic-rate-limit
spec:
 domain: ambassador
 limits:
  - pattern: [{x_limited_user: "false"}, {generic_key: "qotm"}]
    rate: 5
    unit: minute
  - pattern: [{x_limited_user: "true"}, {generic_key: "qotm"}]
    rate: 5
    unit: minute

您可以通过以下方式在服务中引用速率限制:

apiVersion: v1
kind: Service
metadata:
  name: api-service
  annotations:
    getambassador.io/config: |
      ---
      apiVersion: ambassador/v1
      kind: RateLimitService
      name: basic-rate-limit
      service: "api-service:5000"
spec:
  type: ClusterIP
  selector:
    app: api-service
  ports:
    - port: 5000
      targetPort: http-api

Ambassador提供了有关速率限制的出色教程,因此,如果您对使用该功能感兴趣,可以直接转到Ambassador的官方文档

您可以使用用于路由的自定义过滤器扩展Ambassador,但它没有像Kong那样提供充满活力的插件生态系统。

选项3-集大成者gloo

Ambassador并不是唯一可以用作API网关的由Envoy驱动的Ingress。

Gloo是Kubernetes Ingress,也是API网关。它能够提供速率限制,熔断,重试,缓存,外部身份验证和授权,转换,服务网格集成和安全性。

Gloo的卖点是它能够自动发现您的应用程序的API端点并自动理解参数。

可能很难相信(有时他们的文档也无济于事),所以这里有个例子。

假设您有一个通讯录的REST API。

该应用程序公开以下端点:

  • GET /users/{id},获取用户的个人资料
  • GET /users,获取所有用户
  • POST /users/find,找到一个特定的用户

如果您的API是使用标准工具(例如OpenAPI)开发的,那么Gloo会自动使用OpenAPI定义来内省您的API并存储三个端点。

如果在发现阶段之后列出了Gloo服务的所有端点,那么您将看到:

upstreamSpec:
  kube:
    selector:
      app: addressbook
    serviceName: addressbook
    serviceNamespace: default
    servicePort: 8080
    serviceSpec:
      rest:
        swaggerInfo:
          url: http://addressbook.default.svc.cluster.local:8080/swagger.json
        transformations:
          findUserById:
            body:
              text: '{"id": {{ default(id, "") }}}'
            headers:
              :method:
                text: POST
              :path:
                text: /users/find
              content-type:
                text: application/json
          getUser:
            body: {}
            headers:
              :method:
                text: GET
              :path:
                text: /user/{{ default(id, "") }}
              content-length:
                text: '0'
              content-type: {}
              transfer-encoding: {}
          getUsers:
            body: {}
            headers:
              :method:
                text: GET
              :path:
                text: /users
              content-length:
                text: '0'
              content-type: {}
              transfer-encoding: {}

Gloo具有端点列表之后,您可以使用该列表在传入请求到达后端之前将转换应用于传入请求。

例如,您可能希望从传入的请求中收集所有标头,然后在请求到达应用程序之前将它们添加到JSON有效负载中。

或者,您可以公开JSON API,并让Gloo应用转换以在消息到达旧组件之前将消息呈现为SOAP。

能够发现API和应用转换使Gloo特别适用于具有多种技术的环境-或当您正处于从旧系统到新堆栈的迁移过程中。

Gloo可以发现其他种类的终端节点,例如AWS Lambdas。

当您希望混合搭配Kubernetes和无服务器时,这使其成为完美的伴侣。

将Istio用作API网关

API网关和服务网格之间有什么区别?

难道两个都没有做同一件事吗?

两者都提供:

  • 路由流量
  • 验证,例如OAuth,JWT等。
  • 限速
  • 断路器
  • 重试
  • 等等

但是,有一个区别。

诸如Kong和Ambassador之类的API网关主要侧重于处理外部流量并将其路由到集群内部。

外部流量是一个广泛的标签,其中包括:

  • 快速和慢速的客户
  • 行为良好且恶意的用户

换句话说,API网关旨在保护您的应用程序不受外界干扰。

相反,服务网格主要用于观察和保护基础结构中的应用程序。

服务网格的典型用途包括:

  • 监视和观察应用之间的请求
  • 使用加密(相互TLS)保护服务之间的连接
  • 通过断路器,重试等提高弹性

由于服务网格是与您的应用程序一起部署的,因此它们受益于:

  • 低延迟和高带宽
  • 不太可能被滥用

换句话说,服务网格的主要目的是管理内部服务到服务的通信,而API网关主要用于外部客户端到服务的通信。

但这并不意味着您不能将Istio用作API网关。

不过,可能会阻止您的是Istio的首要任务不是处理外部流量。

让我们看一个例子。

通常的做法是,通过JWT或OAuth身份验证在API网关后面保护您的API调用。

Istio提供了JWT,但是您必须在Lua中注入自定义代码才能使其与OAuth一起使用。

另一方面,Kong为此提供了一个插件,因为这是常见的要求。

企业API网关(例如Google Apigee)具有计费功能。

这些功能不太可能在服务网格中复制,因为重点不在管理API上。

如果您不关心计费该怎么办,还可以将服务网格用作API网关吗?

是的,您可以,还有一些您应该知道的事情。

关于API网关和服务网格的一般说明

根据您要实现的目标,服务网格和API网关的功能可能会大大重叠。

由于每个主要的API网关供应商都在扩展到服务网格,因此它们将来可能会重叠得更多。

  • Kong宣布了Kuma一个可以与Kong或Istio集成的服务网格
  • http://Solo.io宣布了与Gloo集成的服务网格SuperGloo
  • Containous宣布Maesh与Traefik集成的服务网格

而且,看到更多服务网格决定像Istio一样启动API网关也就不足为奇了。

总结

如果必须为Kubernetes选择API网关,应该使用哪一个?

  • 如果您需要经过生产验证的API网关,那么Kong仍然是您的最佳选择。它可能不是最光辉的,但是该文档非常有用,在线资源丰富。与其他网关相比,它的生产里程也最多。
  • 如果您需要一个灵活的API网关,可以很好地与新旧基础架构配合使用,则应该看看Gloo。自动发现API和转换请求的能力引人注目。
  • 如果您希望在服务中轻松设置所有网络,则应考虑使用Ambassador。它具有出色的教程和文档入门。请注意,YAML缩进是一个自由字符串。

如果必须选择API网关或服务网格,则应使用哪一个?

从API网关开始仍然是确保内部应用程序不受外部客户端保护的最佳选择。

随着应用程序数量的增加,您可以探索如何利用服务网格来观察,监视和保护它们之间的流量。

PS:本文属于翻译,原文


iyacontrol
1.4k 声望2.7k 粉丝

专注kubernetes,devops,aiops,service mesh。