V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
dunhanson
V2EX  ›  Kubernetes

Java k8s pod 经常重启问题

  •  
  •   dunhanson · 2023-09-17 22:33:49 +08:00 · 3373 次点击
    这是一个创建于 443 天前的主题,其中的信息可能已经有所发展或是发生改变。

    1 、程序没有发生堆内存异常

    2 、内存显示(Memory Usage (bytes)一直在增加( kubernetes dashboard )

    3 、jvm 参数设置 JAVA_TOOL_OPTIONS

    -XX:+UseContainerSupport -XX:InitialRAMPercentage=80.0
    -XX:MaxRAMPercentage=80.0 -XX:+PrintGCDetails
    -XX:+PrintGCDateStamps -Xloggc:/data/logs/app/gc.log
    -XX:+HeapDumpOnOutOfMemoryError
    -XX:HeapDumpPath=/data/logs/app/dump.hprof
    
    第 1 条附言  ·  2023-09-18 11:38:14 +08:00

    pod

          resources:
            limits:
              cpu: '4'
              memory: 8G
            requests:
              cpu: 50m
              memory: 500m
    
    第 2 条附言  ·  2023-09-18 22:12:36 +08:00

    JDK8版本:1.8.0_345

    Reason: OOMKilled

    Exit Code: 137

    第 3 条附言  ·  2023-09-18 22:24:19 +08:00

    arthas

    45 条回复    2023-12-15 13:24:02 +08:00
    kevinlia0
        1
    kevinlia0  
       2023-09-18 00:15:26 +08:00 via Android
    会不会是你分配给 pod 内存不够呢。
    Frankcox
        2
    Frankcox  
       2023-09-18 08:47:37 +08:00
    重启的时候看下事件或者 Pod 的 status ,或者你看 dashboard 看下内存是不是超了
    ixx
        3
    ixx  
       2023-09-18 08:51:30 +08:00
    看一下重启的时候 k8s 记录的 pod 日志 有没有 oomkilled
    一般情况如果不是程序本身结束进程重启就是触发了 k8s 的 oomkilled 机制
    beiluo
        4
    beiluo  
       2023-09-18 09:25:15 +08:00
    大概率是 OOMKilled ,查看 pod status 可以看到 exit code 和 reason, exit code 可以参考 https://komodor.com/learn/exit-codes-in-containers-and-kubernetes-the-complete-guide/
    如果不是,可以查看 previous pod log 看下是不是 jvm crash 出 core dump 了。
    imyasON
        5
    imyasON  
       2023-09-18 09:32:16 +08:00
    我遇到过,也是不知道什么原因。我容器内存是 1 - 2G ,Java -Xms xmx 设置的都是 2g, 然后 OPTIONS 加了一个 gc 类型 UseG1GC 。上线后出现和你一样的情况,莫名其妙的重启,后来我把-Xms1500m -Xmx1500m 和 gc 删掉让它用默认的,目前算是恢复正常,没有重启了。
    fisherwei
        6
    fisherwei  
       2023-09-18 09:39:42 +08:00
    java 版本是 1.8.191 以上吗?
    jerry2233
        7
    jerry2233  
       2023-09-18 11:22:58 +08:00
    `kubectl logs --previous POD_NAME`
    dunhanson
        8
    dunhanson  
    OP
       2023-09-18 11:30:23 +08:00
    @kevinlia0 再怎么调大都会被重启
    dunhanson
        9
    dunhanson  
    OP
       2023-09-18 11:36:21 +08:00
    @Frankcox
    @ixx
    @imyasON
    我还得后续看下,目前没有发生重启,看下 pod 的推出状体码
    dunhanson
        10
    dunhanson  
    OP
       2023-09-18 11:36:43 +08:00
    @fisherwei 最新版本的 jdk8
    dunhanson
        11
    dunhanson  
    OP
       2023-09-18 11:41:18 +08:00
    @beiluo
    @imyasON
    OOMKilled 有什么有效的解决办法?(原因:由于容器 限制,该 pod 已终止。)
    lasuar
        12
    lasuar  
       2023-09-18 11:51:41 +08:00
    OOM 是代码问题,不是 k8s 问题( k8s 也解决不了)。检查程序哪里发生内存泄露,这个在 java 生态里面不是有很多工具能用吗
    Dream95
        13
    Dream95  
       2023-09-18 12:05:09 +08:00
    pod 内除了 Java 有没有其它进程占用了内存
    lidashuang
        14
    lidashuang  
       2023-09-18 12:31:36 +08:00
    @dunhanson 加内存呗
    matepi
        15
    matepi  
       2023-09-18 12:42:45 +08:00
    jvm 总体不要设过容器一半。各种 gc 相关参数打开、oom 时就能产生 heapdump ,拿出来分析内存溢出/泄露对象

    还有:@imyasON

    不要 不要 不要 随便随便就设置等同的 xms 和 xmx 。当堆内用量情况很平稳没有升代、长时间不需要 fullgc ,没有 fullgc 就有不能触发挂载在 finalizer 上的资源回收,可能导致包括堆外溢出等各种各样的资源耗尽问题。在确认没有堆外资源、没有 finalizer 依赖等等情况下,已经做过深度优化的基础上再考虑 xms=xmx 的设定。
    chendy
        16
    chendy  
       2023-09-18 13:17:20 +08:00
    容器内存限制 500m 的话,堆最大给 250m ,也就是堆内堆外 1:1 比较稳妥,然后上监控看看实际使用情况再酌情往大了给
    Georgedoe
        17
    Georgedoe  
       2023-09-18 13:45:39 +08:00
    java8 读的不是容器内存 , 是宿主机内存 , 容易堆溢出 , 得设置 Xms 和 Xmx
    imyasON
        18
    imyasON  
       2023-09-18 13:47:03 +08:00
    @matepi 多谢指教
    julyclyde
        19
    julyclyde  
       2023-09-18 15:15:11 +08:00
    @dunhanson 都 jdk8 了还能有多新啊

    前几天有另一个帖子说过了,jdk8 不认识 cgroup 的限制,但是看/proc/meminfo 看到的又不是“给自己的”而是“整机的”资源,导致一些自动设定的容量大小参数计算错误
    cdlnls
        20
    cdlnls  
       2023-09-18 15:21:20 +08:00
    使用了 MaxRAMPercentage=80.0 后,容器里面的 jvm 最大堆内存是多少呢?
    jdk8 现在应该还不认识 cgroup2 的资源限制的,目前应该是只能支持 v1 。如果节点上使用的是 cgroup2 的话,在使用 MaxRAMPercentage 的时候,会按照节点的内存大小来计算百分比,而不是 pod 资源限制的内存大小来计算。
    notwaste
        22
    notwaste  
       2023-09-18 15:25:43 +08:00
    看描述是 OOM Killer 的问题,容器是否有其他程序占用内存,站内搜下 OOM Killer 可能会有些收获
    anubu
        23
    anubu  
       2023-09-18 15:42:48 +08:00
    可以看看 #20 的回复。我们在 k8s 环境碰到过这个问题,JDK8 和 cgroup2 有兼容性问题,无法识别容器的 limit 导致 OOM 。可以考虑升级 JDK ,降级 cgroup ,手动指定 xmx 等方法。
    julyclyde
        24
    julyclyde  
       2023-09-18 18:20:41 +08:00
    @anubu 我觉得这个东西不能叫“有兼容性问题”;写成“未考虑与 cgroupv2 的兼容性”比较好吧
    julyclyde
        25
    julyclyde  
       2023-09-18 18:22:05 +08:00
    @anubu 我觉得这个东西不能叫“有兼容性问题”;写成“未考虑与 cgroupv2 的兼容性”比较好吧
    v2nika
        26
    v2nika  
       2023-09-18 18:52:33 +08:00
    kubectl describe pod YOUR_POD_NAME

    可以看到 restart 的原因.
    v2nika
        27
    v2nika  
       2023-09-18 19:02:40 +08:00
    有一种情况是 pod 被驱逐了, 会导致 pod 名字变了, 就找不到了, 可以通过 kubectl get events 查一下事件记录.

    另外还有可能是 node 内存不够导致 pod 被系统 oom 杀掉了 (我猜大概率是这个), 这个时候是找不到任何日志的, 因为 jvm/kubelet 都没有机会记录这个事件. 发生的原因是你的 memory 的 request 和 limit 写的不一样, memory 属于不可压缩资源, k8s 没有办法在已经申请后调度. 另外你的 cpu limit 配置的是 4, 这个时候的 gc 算法默认是 G1 (<= 1 的时候是 Serial GC), G1 会在达到你配置的最大堆内存的一个比例前持续增加 old gen 的内存占用 (即使这些对象已经没有引用), 直到发生 mixed gc 或者 full gc.
    v2nika
        28
    v2nika  
       2023-09-18 19:05:31 +08:00
    不过我看你的 InitialRAMPercentage 配置和 MaxRAMPercentage 配置一样, 不太可能是上面说的那个.
    julyclyde
        29
    julyclyde  
       2023-09-18 22:07:37 +08:00
    @v2nika oom 的时候,在那个 node 自己的 dmesg 里是有日志的
    dunhanson
        30
    dunhanson  
    OP
       2023-09-18 22:16:24 +08:00
    @matepi 我看的一篇阿里云官方的资料上面这么推荐配置的,就我这个程序有这个问题,我看其他同事一样的配置,没啥问题 哈哈
    dunhanson
        31
    dunhanson  
    OP
       2023-09-18 22:17:12 +08:00
    @Georgedoe 写了容器支持:UseContainerSupport
    dunhanson
        32
    dunhanson  
    OP
       2023-09-18 22:21:30 +08:00
    @v2nika
    Reason: OOMKilled
    Exit Code: 137
    dunhanson
        33
    dunhanson  
    OP
       2023-09-18 22:23:08 +08:00
    @cdlnls 我用 arthas 看了下,最大堆内存:5426M ,符合 75%设置,有生效
    dunhanson
        34
    dunhanson  
    OP
       2023-09-18 22:26:30 +08:00
    @notwaste 只有 java 一个进程
    Goooooos
        35
    Goooooos  
       2023-09-18 22:32:33 +08:00
    我的内存最大都只设置到 70%,你 80%的话,如果 POD 内存不大,那剩余的内存不多了,可能一些堆外内存就容易占满。建议根据实际情况调整。
    YzSama
        36
    YzSama  
       2023-09-18 22:50:39 +08:00 via iPhone
    1 建议升级 11 ,2 最好的方式是容器自适应。我之前也是,后面不设最大 max 和 min 了。基本不会重启了
    cheng6563
        37
    cheng6563  
       2023-09-18 22:59:50 +08:00
    你 Java 服务没用 jni 那些 native 内存管理的话,只靠-Xmx 限制就够用了,k8s 的 pod 限制可以去掉或者设置很大。
    beiluo
        38
    beiluo  
       2023-09-19 10:08:54 +08:00
    @dunhanson #33 看了下 arthas 的截图,可以考虑把 Xmx 的 75%降到 50%左右试试,可能会增加一些 GC 频率,但是服务更稳定。一个 docker 容器里面会有 Linux 系统本身的占用+JVM 堆占用+JVM 堆外占用(包括 metaspace ,code cache ,native 等)堆占用 75%之后,其实留给其他部分的并不多了。个人理解。
    cmai
        39
    cmai  
       2023-09-19 11:20:52 +08:00
    看不到阿尔萨斯的图了,从堆外内存泄漏着手吧
    notwaste
        40
    notwaste  
       2023-09-19 14:22:00 +08:00
    https://www.v2ex.com/t/740570

    “问题出发点不在修改方便上面,Xmx 跟容器平台 memory limit 不契合是关键。因为 JVM 进程内存不严格的说要等于 Xmx + 线程数 * Xss + native allocation 等等等,如果 Xmx 是设置好的,跟 limit 一样,实际上堆内存还远没用到 Xmx 就会到达 memory limit 被 kubernetes exit 137 这个值必须要动态”

    可以看下 7 楼里面引用的答案和评论
    dunhanson
        41
    dunhanson  
    OP
       2023-09-20 21:44:55 +08:00
    @beiluo 我设置 60%观察看看
    dunhanson
        42
    dunhanson  
    OP
       2023-09-20 21:53:41 +08:00
    @cdlnls 是 v1 版本
    dunhanson
        43
    dunhanson  
    OP
       2023-09-20 21:55:03 +08:00
    @v2nika pod 没有驱逐,只是重启了,Restarts=1
    freebird1994
        44
    freebird1994  
       2023-09-21 15:45:41 +08:00 via Android
    我也遇到了一样的问题😢
    Plutooo
        45
    Plutooo  
       354 天前
    @notwaste 挖一下,前面的回答有些错误,不知道是不是下面这个原因

    kubernetes 1.25 之后的 CRI 默认启用 cgroup v2 会导致旧版本 java 8 服务像当初 backport cgroup v1 之前的时代那样,识别不到正确的内存限制需要 Java 服务的 JDK 版本 >= 8u372 11.0.6 15+如果遇到疑似容器内存非预期暴涨,记得关注这一块,及时升级 JDK 版本
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1392 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 17:41 · PVG 01:41 · LAX 09:41 · JFK 12:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.