解決k8s集羣環境內存不足致使容器被kill問題


背景

最近線上環境上出現了一個問題, k8s集羣環境Pod中的tomcat容器運行一段時間後直接被killd,但有時一切看起來正常,不能準確判斷在什麼時機出現被Killd問題。html

本文就此問題介紹了Linux內存不足緣由以及爲何特定進程會被殺死。並提供了Kubernetes集羣環境故障排除指南教程。java

tomcat進程被殺死緣由分析

當這個應用程序被kill問題進行故障排除時,很大程度上肯定是操做系統殺死的, 由於整個過程確認沒有進行kill操做。當我查看tomcat日誌時發現,tomcat只是簡單的提示了killd, 至於緣由, 日誌中沒有給出詳盡的提示。緊接着我查看了syslog日誌grep -i kill /var/log/messages*, syslog給出比較詳細的提示, 大概意思是該應用佔用內存超過cgroup限制, 直接被Kill。以下所示:web

Oct 1 20:37:21 k8swork kernel: Memory cgroup out of memory: Kill process 13547 (java) score 1273 or sacrifice child

若是當服務已經掛掉, 使用free查看內存佔用, 對咱們排除問題不會有太大幫助, 由於這個時候服務佔用內存已經隨着服務的掛掉而釋放。以下所示:docker

[root@k8swork log]# free -lm
             total       used       free     shared    buffers     cached
Mem:           498         93        405          0         15         32
Low:           498         93        405
High:            0          0          0
-/+ buffers/cache:         44        453
Swap:         1023          0       1023

可是Linux vmstat可使用如下命令將的輸出重定向到文件。咱們甚至能夠調整持續時間和次數以監控更長的時間。當命令運行時,咱們能夠隨時查看輸出文件以查看結果。咱們每120秒查看內存1000次。該&行末尾的容許咱們將其做爲一個進程運行並從新得到終端。tomcat

vmstat -SM 120 1000 > memoryuse.out &

經過如上信息能夠斷定罪魁禍首是這個Java進程佔用內存超過資源限制, 直接被系統殺死。爲何會出現這個問題呢?微信

首先第一點,已經在編排文件中限制資源最大使用量爲4G,理論上Pod中容器是不可能佔用這麼多資源, 默認狀況下Java佔用物理資源的1/4左右, 可是既然出現了這個問題,說明Java進程佔用資源超過了這個限制。架構

因而在網上找到了以下信息,大概意思是說,jdk從131版本以後開始經過選項支持對容器對內存和CPU 的限制,以下圖所示:oracle

https://blogs.oracle.com/java-platform-group/java-se-support-for-docker-cpu-and-memory-limits

當我打開131版本更新信息以後,沒有看到任何關於容器相關的更新, 因而開始查找以後的版本, 最後找到191版本, 能夠看到Java對容器作出了支持。app

https://www.oracle.com/java/technologies/javase/8u191-relnotes.html

覈對了目前出現問題的Java版本, 明顯是低於這個版本的, 肯定了問題所在。編輯器

Java虛擬機感知不到Pod中資源限制,因此直接佔用了宿主機1/4左右內存(宿主機是32G內存), cgroup檢測到Pod佔用內存超過限制(Pod限制爲4G),進行了Kill操做。

解決方式也很簡單,直接在tomcat服務中配置最大最小內存佔用, 在Java層面限制其內存佔用。可是具體Java進程爲何佔用這麼高的內存就須要業務開發人員排查解決了。

總結

經過本文能夠看出基於Java虛擬機構建項目, 在容器化過程當中要儘可能適配高版本或者對docker容器有親和性的Jdk版本, 若是沒有, 必定要在虛擬機層面限制Java服務佔用內存大小。另一定要在服務上添加存活探針,若是沒有添加存活探針,相似於tomcat這種容器類服務,即便內部服務掛了了, Kubernetes不會自動幫你拉起的,緣由很簡單,它沒法感知到你的服務是否存活。因此服務必定要添加Http存活探針(基於TCP層面的探針只是檢測端口是否存活,大多數狀況下,服務會出現假死問題,但端口依然能夠正常訪問)。

問題故障排查指南教程推薦

首先這本書是阿里雲同窗總結的<<深刻淺出Kubernetes>>, 裏面不只用通俗易懂語言介紹了Kubernetes核心概念, 並且介紹了Kubernetes集羣出現問題解決思路,值得借鑑。好比其中一個案例半夜兩點Ca證書過時問題 它不只詳細介紹了整個故障排除和解決方式, 另外給出了集羣環境證書認證體系流程介紹, 很是贊!

Citadel 證書體系

若是須要請在公衆號後臺回覆[k8s]獲取下載地址。

推薦


雲原生時代Java面臨的不適與挑戰

Kubernetes入門培訓(內含PPT)

從Ice到Kubernetes容器技術,微服務架構經歷了什麼?


原創不易,隨手關注或者」在看「,誠摯感謝!

本文分享自微信公衆號 - 雲原生技術愛好者社區(programmer_java)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索