【问题标题】:Kubernetes pod memory usage programatically以编程方式使用 Kubernetes pod 内存
【发布时间】:2021-12-11 04:40:48
【问题描述】:

我有一个用例,在我的 jax-rs rest api 中暴露将执行内存密集型操作,例如生成 pdf 并将其作为响应发送。我想在开始执行业务逻辑之前检查 pod 内存使用情况,如果当前内存使用率 > 50% ,我想向用户发送错误响应,要求他稍后再试。如何在我的 rest api 中检查 kubernetes pod 内存使用情况。有可能吗?

我当前的代码如下所示。

@Path("/doSomeMemoryStuff")
@Produces("text/plain")
public Response doStuff(){

     int memoryUsage = getPodCurrentMemoryUsage();  //Get pod current memory usage
     if( memoryUsage <= 50 ) {

          //do Some memory intensive operation
      }
      else{
           //memory usage is more than 50 % , return error
           return Response.ok("Try again later.").build();
          }
  }         

如何从我的 rest api 中找出 pod 的当前内存使用情况。提前致谢。

【问题讨论】:

    标签: java kubernetes


    【解决方案1】:

    严格来说,我们可以将您的陈述解释为 “Kubernetes pod 内存使用自动”,因为如果您的进程不时消耗大量需要释放的资源,您可以使用 Vertical Pod Autoscaler

    一些有趣的参考资料:

    1. https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler
    2. https://docs.aws.amazon.com/eks/latest/userguide/vertical-pod-autoscaler.html
    3. https://cloud.google.com/kubernetes-engine/docs/concepts/verticalpodautoscaler

    当一个或另一个进程的资源需求非常不同时,使用 VPA 是合适的。

    如果不是这种情况(或多或少所有请求都将使用已知数量的资源),或者即使您使用 VPA,建议您将服务限制为不接受请求(如果它们正在执行昂贵的操作) , Kubernetes 会根据负载自动增加或减少 Pod 的数量,您的用户会收到 503 错误,这正是表明他们现在无法提供服务,应该稍后再试。

    也就是说:

    1. 如果不是绝对必要,请勿使用 VPA。
    2. 为您的部署配置足够数量的 pod。
    3. 将 Pod 中的服务限制为单个并发请求(或与您的资源配置相适应的多个请求)。
    4. 不要做任何特别的事情,如果您的系统已达到您设置的限制,只需让用户收到 503(您的用户界面会将错误翻译为“稍后再试”) .

    部署的细节可能会有所不同,但基本上通过在三个级别上进行操作,您可以让您的基础架构对负载类型具有一定的适应性:

    1. 应用程序级别:您可以为每个应用程序实例定义(http 请求)速率限制。它必须与 Pod 的请求/限制保持一致。如果您无法修改您的应用程序(即使用bucket4j),您可以使用(例如)Nginx 将Adapter 添加到您的 Pod(具体配置请参见第 3 点)。
    2. 部署级别:一旦您的应用程序不会因请求过载而中断,您应该能够使用https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/(有有很多可用于自动缩放的指标)。
    3. 负载平衡器级别:对于简单的场景,您可以简单地配置一个入口控制器来限制速率(即使用Nginx controller),但是,如果您能够分段您的请求(例如...?queryType=hard&amp;...),您可以隔离您的配置(第 1 点和第 2 点),以维护多个基础架构(具有多个垂直扩展),每个基础架构都已准备好处理特定类型的请求,这可以通过 Nginx 轻松完成(Istio 可能有点矫枉过正)。李>

    使用此策略,假设您有两个区域:“LR:低资源”“HR:高资源”。如果您的系统上没有负载,则这两个区域都不会消耗资源(即minReplies: 1),如果有许多 "LR" 请求,则资源在该区域中使用,如果它们在"HR" 用在这个另一个中,如果两个都用,就分布在两者之间。从逻辑上讲,最大负载为 LR.maxReplies + HR.maxReplies(您可以制定更复杂的规则,例如使用 Istio,但始终使用您认为适合您的最简单的方案)。

    【讨论】:

    • 嘿@josejuan .. 感谢您指向资源。非常有用的信息.. 但是这个垂直的 Pod 自动缩放器会自动重启 Pod,这需要至少 1-2 分钟的停机时间。或者即使有多个 Pod 正在运行,正在重新启动的 Pod 的即时请求也会受到影响。我们如何处理这个.. 用户几乎不使用我的 api.. 所以我怀疑只为这个用例引入自动缩放功能......
    • 你是对的@Stunner 这就是为什么我说“不要使用 VPA” 并建议限制并发率和 infra 限制以简单地让 kubernetes 拒绝更多请求(#2到#4)。您可以根据需要调整参数。当然,您可以查看Runtime.getRuntime().freeMemory(),但更好的方法是将昂贵的请求多路复用到具有更多资源的 pod(这就是我已经说过的,但是是分层的)。但是要应用这些策略,需要了解有关您的请求和用户的更多详细信息(并且应用起来并非易事)。
    • 知道了。你能否告诉我我需要在资源配置中设置哪些参数来限制单个并发请求。谢谢。
    • “你能不能扔我...”当然,我已经更新了我的答案。
    猜你喜欢
    • 2021-06-01
    • 2020-02-01
    • 2021-09-01
    • 2021-02-14
    • 2018-01-18
    • 2021-06-22
    • 2019-07-26
    • 2020-11-27
    • 1970-01-01
    相关资源
    最近更新 更多