簡體   English   中英

Memory 在 Kubernetes 吊艙上建立超時導致 JVM 無法啟動

[英]Memory builds up overtime on Kubernetes pod causing JVM unable to start

我們正在運行 kubernetes 環境,並且我們的 pod 遇到了 memory 問題。 pod 只運行一個容器,這個容器負責全天運行各種實用程序作業。

問題是這個 pod 的 memory 使用量隨着時間的推移而緩慢增長。 此 pod 的 memory 限制為 6 GB,最終,memory 消耗增長到非常接近 6GB。

我們的許多實用程序作業都是用 Java 編寫的,當 JVM 為它們啟動時,它們需要-Xms256m才能啟動。 Yet, since the pod's memory is growing over time, eventually it gets to the point where there isn't 256MB free to start the JVM, and the Linux oom-killer kills the java process. 這是發生這種情況時我從dmesg看到的內容:

[Thu Feb 18 17:43:13 2021] Memory cgroup stats for /kubepods/burstable/pod4f5d9d31-71c5-11eb-a98c-023a5ae8b224/921550be41cd797d9a32ed7673fb29ea8c48dc002a4df63638520fd7df7cf3f9: cache:8KB rss:119180KB rss_huge:0KB mapped_file:0KB swap:0KB inactive_anon:0KB active_anon:119132KB inactive_file:8KB active_file:0KB unevictable:4KB
[Thu Feb 18 17:43:13 2021] [ pid ]   uid  tgid total_vm      rss nr_ptes swapents oom_score_adj name
[Thu Feb 18 17:43:13 2021] [ 5579]     0  5579      253        1       4        0          -998 pause
[Thu Feb 18 17:43:13 2021] [ 5737]     0  5737     3815      439      12        0           907 entrypoint.sh
[Thu Feb 18 17:43:13 2021] [13411]     0 13411     1952      155       9        0           907 tail
[Thu Feb 18 17:43:13 2021] [28363]     0 28363     3814      431      13        0           907 dataextract.sh
[Thu Feb 18 17:43:14 2021] [28401]     0 28401   768177    32228     152        0           907 java
[Thu Feb 18 17:43:14 2021] Memory cgroup out of memory: Kill process 28471 (Finalizer threa) score 928 or sacrifice child
[Thu Feb 18 17:43:14 2021] Killed process 28401 (java), UID 0, total-vm:3072708kB, anon-rss:116856kB, file-rss:12056kB, shmem-rss:0kB

例如,根據我一直在做的研究,隨着各種緩存的增長,Linux 的消耗隨着時間的推移而增長似乎是正常的。 據我了解,當新進程(例如我的 java 進程)開始運行時,緩存的 memory 也應該被釋放。

我的主要問題是:這個 pod 的 memory 是否應該被釋放以便這些 java 進程運行? 如果是這樣,我是否可以采取任何步驟來開始調試為什么這可能無法正確發生?

除了這個問題,我還一直試圖找出導致 memory 增長的原因。 我能夠將其縮小到每 15 分鍾運行一次的某個工作。 我注意到每次運行后,使用 memory 使 pod 增長了 ~.1 GB。

我能夠通過在每次執行作業之前和之后運行這個命令(在容器內)來解決這個問題:

cat /sys/fs/cgroup/memory/memory.usage_in_bytes | numfmt --to si

從那里我縮小了 bash 代碼的范圍,memory 似乎一直在增長。 該代碼如下所示:

while [ "z${_STATUS}" != "z0" ]
do
    RES=`$CURL -X GET "${TS_URL}/wcs/resources/admin/index/dataImport/status?jobStatusId=${JOB_ID}"`
    _STATUS=`echo $RES | jq -r '.status.status' || exit 1`
    PROGRES=`echo $RES | jq -r '.status.progress' || exit 1`
    [ "x$_STATUS" == "x1" ] && exit 1
    [ "x$_STATUS" == "x3" ] && exit 3
    [ $CNT -gt 10 ] && PrintLog "WC Job ($JOB_ID) Progress: $PROGRES Status: $_STATUS " && CNT=0

    sleep 10
    ((CNT++))
done
[ "z${_STATUS}" == "z0" ] && STATUS=Success || STATUS=Failed

這段代碼乍一看似乎對我無害,所以我不知道從這里到 go 的位置。

我真的很感激任何幫助,我幾天來一直在努力解決這個問題。

我最終確實做到了這一點,所以我想我會在這里發布我的解決方案。 我在原始帖子中提到,我將問題縮小到我在上面的問題中發布的 while 循環。 每次運行相關作業時,while 循環可能會迭代 10 次。 在 while 循環完成后,我注意到使用的 memory 每次都非常一致地增加 100MB。

我預感到循環中的CURL命令可能是罪魁禍首。 事實上,事實證明CURL正在吃掉我的 memory 並且出於某種原因沒有釋放它。 而不是循環並運行以下 CURL 命令:

RES=`$CURL -X GET "${TS_URL}/wcs/resources/admin/index/dataImport/status?jobStatusId=${JOB_ID}"`

我用一個簡單的 python 腳本替換了這個命令,該腳本使用requests模塊來檢查我們的作業狀態。

我仍然不確定為什么 CURL 是這種情況下的罪魁禍首。 運行CURL --version之后,使用的底層庫似乎是libcurl/7.29.0 也許該庫版本中存在一個錯誤,導致 memory 管理出現一些問題,但這只是猜測。

無論如何,從使用 python 的requests模塊而不是CURL已經解決了我的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM