6

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

请参阅下图显示架构。

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

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

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

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

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

在此处输入图像描述

4

4 回答 4

3

网络请求中的自动缩放需要自定义指标。鉴于您使用的是 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,您可以参考此文档以了解如何进行速率限制。但我需要告诉你,带有 NGINX 入口的 Istio 可能会给你带来麻烦。Istio 附带了自己的入口控制器。你需要做额外的工作才能让它发挥作用。

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

于 2021-01-12T03:07:45.947 回答
2

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

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

最重要的是,NGINX 将使用漏桶算法对您的请求进行排队,因此传入的请求将使用 FIFO(先进先出)算法在队列中缓冲,然后以有限的速率消耗。在这种情况下,突发值定义了允许请求超出限制的队列大小。当此队列已满时,下一个请求将被拒绝。

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

于 2021-01-07T09:25:15.787 回答
0

也许你应该考虑实现Kubernetes 服务 API

于 2021-01-09T10:48:36.983 回答
0

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

在下面添加代码:

apiVersion:autoscaling/v2beta2 种类:Horizo​​ntalPodAutoscaler 元数据:名称:php-apache 规格:scaleTargetRef:apiVersion:apps/v1 种类:部署名称:php-apache minReplicas:1 maxReplicas:10 指标:

  • 类型:对象对象:度量:名称:每秒请求次数描述对象:apiVersion:networking.k8s.io/v1beta1 种类:入口名称:主路由目标:类型:值值:10k

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

于 2021-01-12T05:40:22.523 回答