在Pod设置limit 的情况下,如何让JDK容器适配

这篇具有很好参考价值的文章主要介绍了在Pod设置limit 的情况下,如何让JDK容器适配。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1. 背景

2. 问题

3. 解决方案

3.1. 注意

4. 参考


1. 背景

        在使用Kubernetes部署业务应用的实际操作中,由于k8s集群的资源是有限的,为了防止部分应用无节制地使用资源,我们会在Deployment.yaml文件中设置request,limit的资源限制大小。

        在 Kubernetes 中,你可以通过设置 pod 的 spec.containers[].resources.requests 和 spec.containers[].resources.limits 来配置容器的资源需求和限制。以下是一个样例:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: my-springboot-jdk11-demo-image
    resources:
      requests:
        cpu: "0.5"
        memory: "250Mi"
      limits:
        cpu: "2"
        memory: "8192Mi"

在这个例子中:

  • requests:这部分设置了容器启动所需要的资源。在这个例子中,容器启动所需的 CPU 是 0.5 个核心,内存是 250 MiB。
  • limits:这部分设置了容器所能使用的资源的最大值。在这个例子中,容器所能使用的最多的 CPU 是 2 个核心,内存是 8192 MiB(8Gib)。

        如果容器使用的资源超过了所设置的 limits,那么这个容器可能会被 Kubernetes 杀掉并重启。

2. 问题

        在现实中,我们有很多应用使用java开发,那必然会使用JDK基础镜像,在这个实际操作中,我们可能会遇到明明设置了Limit,但是容器的最大Memory就是上不去,卡在2.1Gib左右,这个和使用的基础镜像有关系,部分JDK基础镜像有的存在默认的Xmx和Xms值。或者说,JDK运行在容器中,它无法确定Pod的limit是多少。

  • -Xmx<size>: 这个参数可以设置程序的最大内存分配。比如,如果你想要设置最大内存为1GB,你可以写成-Xmx1024m或者-Xmx1g。
  • -Xms<size>: 这个参数可以设置程序的初始化(最小)内存分配。比如,如果你想要设置最小内存为256MB,你可以写成-Xms256m。

3. 解决方案

        对于运行在容器中的Java应用,于JDK 10及以后的版本,JVM可以自动识别并根据容器的内存限制动态设置堆大小,无需再额外手动设置JVM的-Xmx和-Xms参数。

        JDK 10及以后的版本默认开启了-XX:+UseContainerSupport选项,默认使用容器的cgroup限制作为JVM的内存限制。如果你使用的是JDK 8,可以使用-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap选项来让JVM使用容器cgroup的内存限制。

        此外,你还可以通过使用比例设置JVM的内存分配,例如,你可以使用-XX:MaxRAMPercentage和-XX:MinRAMPercentage参数来限制JVM使用的最大和最小内存占比。这两个参数设置的是JVM可用内存占容器可用内存的最大和最小百分比。

-XX:MaxRAMPercentage=80.0 -XX:MinRAMPercentage=5.0

# 注意
# -XX:+UseContainerSupport参数在JDK 10及以后的版本是默认开启的
# 完整命令:-XX:+UseContainerSupport -XX:MaxRAMPercentage=80.0 -XX:MinRAMPercentage=5.0

# JDK8完整命令:-XX:+UnlockExperimentalVMOptions -XX:+UseContainerSupport -XX:MaxRAMPercentage=80.0 -XX:MinRAMPercentage=5.0

        上述命令就设置了JVM使用最大内存为容器内存的80%,最小内存为容器内存的20%。这样,无论你的pod限制如何变动,JVM都会按照这个比例动态调整。

        在上述例子中,因为设置的容器内存上限是8GB,所以JVM会设置最大堆大小(-Xmx)为8GB的80%,即6.4GB。最小堆大小(-Xms)为8GB的5%,即400MB

完整的Dockerfile如下:

FROM openjdk-11

ADD target/my-app-name.jar /app/app.jar

WORKDIR /app

ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=80.0 -XX:MinRAMPercentage=5.0"

ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Dspring.profiles.active=$PROJECT_ENV -jar app.jar"]

EXPOSE 8080

3.1. 注意

        在实际使用过程中,请注意,XX:MaxRAMPercentage=80.0是限制堆内存最大值。我遇到一个项目出现这个问题,当时就提出这个问题,此处也记录一下

:我的container limit 是3000M, 设置-XX:MaxRAMPercentage=80.0之后,在压力测试之后,从监控上看,内存还是能飚高到3000M,为何没有限制住?

        这主要是因为Java程序的内存使用不仅仅包括堆内存(Heap),还包括了非堆内存(Non-Heap),其中包括MetaSpace(元数据区),JVM堆栈,JVM本身代码等等。 MaxRAMPercentage 这个参数只是设置了堆内存(Heap)的大小,但并没有限制非堆内存(Non-Heap)。

        如果你看到的内存占用达到了3000M,可能的情况是,堆内存占用了你设置的比例(80%,即2400M),剩下的600M被非堆内存占用了。

另外一个需要注意的地方,3000M的limit是设置给了整个容器,容器里不仅仅有这一个Java进程。也可能是其他进程占用了一部分内存。

        所以这意味着,如果你希望Java进程的最大内存使用不超过一个确定的值,那么你需要将MaxRAMPercentage设置的更小一些,比如50%或60%等,以便为非堆内存和其他进程留出足够的空间。

        注意,一定要结合实际的应用情况去做这个调整和选择,避免设置过小影响了Java程序的运行性能。

4. 参考

ChatGPT文章来源地址https://www.toymoban.com/news/detail-851624.html

到了这里,关于在Pod设置limit 的情况下,如何让JDK容器适配的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Kubernetes在容器内获取Pod信息

    我们知道,每个 Pod 在被成功创建出来之后,都会被系统分配唯一的名字、IP 地址,并且处于某个 Namespace 中,那么我们如何在 Pod 的容器内获取 Pod 的这些重要信息呢?答案就是使用 Downward API。 Downward API 可以通过以下两种方式将 Pod 信息注入容器内部。 (1)环境变量:用于单

    2024年02月10日
    浏览(27)
  • 【云原生|Kubernetes】08-Pod中的Init容器

    Init 容器是一种特殊容器,在 Pod内的应用容器启动之前运行。Init 容器可以包括一些应用镜像中不存在的实用工具和安装脚本。 你可以在 Pod 的spec中与用来描述应用容器的 containers 数组平行的位置指定 Init 容器。 Init 容器的状态在 status.initContainerStatuses 字段中以容器状态数组

    2024年02月09日
    浏览(43)
  • Kubernetes(k8s)容器编排Pod介绍和使用

    Pod是kubernetes中你可以创建和部署的最小也是最简的单位,一个Pod代表着集群中运行的一个进程。 Pod有两个必须知道的特点 通过yaml文件或者json描述Pod和其内容器的运行环境和期望状态,例如一个最简单的运行nginx应用的pod,定义如下 3.1.1 参数描述 下面简要分析一下上面的

    2024年02月08日
    浏览(55)
  • 【云原生】kubernetes在Pod中init容器的作用和使用

    目录 Pod 中 init 容器 1 init 容器特点 2 使用 init 容器 Pod 中 init 容器 Init 容器是一种特殊容器,在Pod 内的应用容器启动之前运行。Init 容器可以包括一些应用镜像中不存在的实用工具和安装脚本。 1 init 容器特点 init 容器与普通的容器非常像,除了如下几点: 它们总是运行到完

    2024年02月14日
    浏览(30)
  • kubernetes(k8s)为容器和 Pod 分配内存资源

    展示如何将内存请求(request)和内存限制(limit)分配给一个容器。 我们保障容器拥有它请求数量的内存,但不允许使用超过限制数量的内存。 创建新的命名空间 编辑yaml文件 配置文件的 args 部分提供了容器启动时的参数。 “–vm-bytes”, “150M” 参数告知容器尝试分配 15

    2024年02月15日
    浏览(37)
  • 45了解容器编排工具 Kubernetes 的基本概念和应用,包括 Pod、Service

    Kubernetes 是一种用于自动部署、扩展和管理容器化应用程序的开源容器编排工具。它可以轻松地管理和编排应用程序容器,确保它们在大规模的云环境中高效、可靠地运行。本教程将介绍 Kubernetes 的基本概念和应用,包括 Pod 和 Service。 Pod 是 Kubernetes 中最小的可部署对象,是

    2024年02月08日
    浏览(28)
  • kubernetes|云原生| 如何优雅的重启和更新pod---pod生命周期管理实务

    kubernetes的管理维护的复杂性体现在了方方面面,例如,pod的管理,服务的管理,用户的管理(RBAC),网络的管理等等,因此,kubernetes安装部署完毕仅仅是万里长征的第一步,后面的运营和维护工作才是更为关键的东西。 那么,pod的生命周期是什么概念呢?这

    2024年02月04日
    浏览(42)
  • k8s(Kubernetes)设置 pod,Deployment 域名自定义映射ip,hosts 解析 HostAliases

    直接 编辑修改 Deployment 最后内容如下,如需保存 按 esc 键,最后输入 :wq 保存退出,容器会自动重新生成新的

    2024年02月12日
    浏览(38)
  • 十一. Kubernetes 容器 container 设置详解

    pod是k8s的基本单位,用k8s部署的应用运行在container容器中, 容器运行在pod中,pod又运行在k8s的节点上,一个pod内部可以启动多个container容器,所以pod又称为容器组(pod内部运行的docker容器,使用docker容器启动服务时一个容器只能启动一个服务,使用k8s后,pod是k8s的基本单位一个pod中可以运

    2024年02月08日
    浏览(35)
  • 云原生之深入解析Kubernetes Pod如何获取IP地址

    一、背景 Kubernetes 网络模型的核心要求之一是每个 Pod 都拥有自己的 IP 地址并可以使用该 IP 地址进行通信。很多人刚开始使用 Kubernetes 时,还不清楚如何为每个 Pod 分配 IP 地址。它们了解各种组件如何独立工作,但不清楚这些组件如何组合在一起使用。例如,它们了解什么是

    2024年02月02日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包