【问题标题】:K8S Ingress: How to limit requests in flight per podK8S Ingress:如何限制每个 pod 中的请求
【发布时间】:2021-01-12 13:40:22
【问题描述】:

我正在移植一个应用程序以在 k8s 中运行。我遇到了入口问题。我正在尝试找到一种方法来限制在任何给定时间对部署管理的每个后端 pod 进行的 REST API 请求的数量。

请看下图,展示了架构。

Ingress 由 nginx-ingress 管理。对于给定的一组 URL 路径,入口将请求转发到以部署 REST API 后端进程为目标的服务。部署也由 HPA 根据 CPU 负载进行管理。

我想做的是找到一种方法来对入口请求进行排队,这样在运行我们的 API 后端进程的任何 pod 中传输的请求永远不会超过 X 个。 (例如,每个 pod 一次只允许 50 个正在运行的请求)

有人知道如何设置这样的请求限制吗?

作为一个额外的问题,我需要做的下一件事是让 HPA 监控请求队列并自动扩大/缩小部署,以使 pod 的数量与当前正在处理/排队的请求数量相匹配。例如,如果每个 pod 可以同时处理 100 个运行中的请求,而我们目前有 1000 个请求的负载水平要处理,那么自动缩放到 10 个 pod。

如果有用,我还计划为这个集群安装 linkerd。也许它有一种可以提供帮助的能力。

【问题讨论】:

  • stackoverflow.com/a/48693860/9521610 由于 Kubernetes 中的上游服务器是一个服务,它不能给出所需的结果,但在特定的配置中你可能会发现它很有用。

标签: kubernetes kubernetes-ingress nginx-ingress hpa linkerd


【解决方案1】:

网络请求中的自动缩放需要自定义指标。鉴于您使用的是 NGINX 入口控制器,您可以先安装 prometheus 和 prometheus 适配器以从 NGINX 入口控制器导出指标。默认情况下,NGINX 入口控制器已经暴露了 prometheus 端点。

关系图会是这样的。

NGINX ingress <- Prometheus <- Prometheus Adaptor <- custom metrics api service <- HPA controller

箭头表示API中的调用。因此,总的来说,您的集群中将多出三个提取组件。

设置自定义指标服务器后,您可以根据来自 NGINX 入口的指标来扩展您的应用程序。 HPA 将如下所示。

apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: srv-deployment-custom-hpa
spec:
  scaleTargetRef:
    apiVersion: extensions/v1beta1
    kind: Deployment
    name: srv-deployment
  minReplicas: 1
  maxReplicas: 100
  metrics:
  - type: Pods
    pods:
      metricName: nginx_srv_server_requests_per_second
      targetAverageValue: 100

我不会在这里介绍实际的实现,因为它会包含很多环境特定的配置。

设置完成后,您可以看到 HPA 对象将显示从适配器中提取的指标。

对于Service 对象级别的速率限制,您需要一个强大的服务网格来执行此操作。 Linkerd2 设计为轻量级,因此它不附带速率限制功能。您可以在linkerd2 下参考此问题。维护者拒绝在服务级别实施速率限制。他们会建议您改为在Ingress 级别执行此操作。

AFAIK、Istio 和一些高级服务网格提供了速率限制功能。如果您尚未将链接器部署为您的服务网格选项,您可以尝试使用 Istio。

对于 Istio,您可以参考 this document 了解如何进行速率限制。但我需要告诉你,带有 NGINX 入口的 Istio 可能会给你带来麻烦。 Istio 附带了自己的入口控制器。你需要做额外的工作才能让它发挥作用。

总而言之,如果您可以将 HPA 与请求数量的自定义指标一起使用,它将是解决您在流量控制方面的问题的快速解决方案。除非您仍然很难控制流量,否则您将需要考虑Service 级别的速率限制。

【讨论】:

  • 感谢您的详细回复。
【解决方案2】:

Nginx 入口允许使用annotations 进行速率限制。你可能想看看limit-rps 一个:

  • nginx.ingress.kubernetes.io/limit-rps:每秒从给定 IP 接受的请求数。突发限制设置为此限制乘以突发乘数,默认乘数为 5。当客户端超过此限制时,limit-req-status-codedefault: 返回 503。

除此之外,NGINX 会将您的请求与leaky bucket algorithm 一起排队,因此传入的请求将使用 FIFO(先进先出)算法缓冲在队列中,然后以有限的速率消耗。在这种情况下,突发值定义了允许请求超出限制的队列大小。当此队列已满时,下一个请求将被拒绝。

有关限制流量和整形的更多详细信息:

【讨论】:

  • 这将允许每个 IP 的硬限制,或者如果使用全局设置,它将允许整个入口的硬速率限制,但这并不是我想要找到的。我需要一种方法来限制每个 pod 的请求数量。我认为这不会处理我的情况。
  • 那么我建议研究一些服务网格和envoy filter rate limiting,因为这可能更适合您的用例。 Envoy 过滤器会在您的部署中添加一些随机标头,然后您将根据该标头进行速率限制。
【解决方案3】:

或许你应该考虑实现Kubernetes Service APIs

【讨论】:

    【解决方案4】:

    基于最新的 kubernetes 文档。我们可以根据自定义指标做 hpa。 文档参考:https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/

    在下面添加代码:

    apiVersion:自动缩放/v2beta2 种类:Horizo​​ntalPodAutoscaler 元数据: 名称:php-apache 规格: 规模目标参考: api版本:应用程序/v1 种类:部署 名称:php-apache minReplicas: 1 最大副本数:10 指标:

    • 类型:对象 目的: 指标: 名称:每秒请求数 描述对象: api版本:networking.k8s.io/v1beta1 种类:入口 名称:主线 目标: 类型:值 价值:10k

    我的建议是专门为此服务提供入口资源(循环中的负载平衡),然后如果您可以根据请求数(您期望)* 最小副本节点数进行自动缩放。这应该做一个最佳的 hpa 。 PS 我会自己测试并发表评论。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-30
      • 1970-01-01
      • 2021-11-18
      • 1970-01-01
      相关资源
      最近更新 更多