K8S Ingress:如何限制每个 pod 的飞行请求

K8S Ingress: How to limit requests in flight per pod

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

查看下图显示的体系结构。

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

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

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

作为奖励问题,我接下来需要做的是让 HPA 监控请求排队并自动扩展 up/down 部署以匹配 pods 的数量当前正在处理/排队的请求。例如,如果每个 pod 可以同时处理 100 个请求,而我们当前有 1000 个请求的负载级别要处理,那么自动缩放到 10 pods.

如果有用的话,我也打算在这个集群上安装linkerd。也许它具有可以提供帮助的功能。

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

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

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

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

也许您应该考虑实施 Kubernetes Service APIs

网络请求中的自动缩放需要自定义指标。鉴于您使用的是 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 和一些高级服务网格提供了速率限制功能。如果您还没有部署 linkerd 作为您的服务网格选项,您可以尝试使用 Istio。

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

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

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

在下面添加代码:

api版本:autoscaling/v2beta2 种类:Horizo​​ntalPodAutoscaler 元数据: 名称:php-apache 规格: scaleTargetRef: api版本:apps/v1 种类:部署 名称:php-apache 最小副本:1 最大副本数:10 指标:

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

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