wordpress+站群軟件東莞網(wǎng)絡(luò)推廣營銷公司
什么是 OOMKilled Kubernetes 錯誤(Exit Code 137)
當(dāng) Kubernetes 集群中的容器超過其內(nèi)存限制時,Kubernetes 系統(tǒng)可能會終止該容器并顯示“OOMKilled”錯誤,這表明該進(jìn)程由于內(nèi)存不足而被終止。此錯誤的退出代碼是 137。
如果遇到錯誤,Pod 的狀態(tài)將顯示“OOMKilled”,您可以使用以下命令查看該錯誤:
kubectl get pods
OOMKiller 機(jī)制如何工作?
Out-Of-Memory Killer (OOMKiller) 是 Linux 內(nèi)核(不是本機(jī) Kubernetes)中的一種機(jī)制,負(fù)責(zé)通過殺死消耗過多內(nèi)存的進(jìn)程來防止系統(tǒng)內(nèi)存不足。當(dāng)系統(tǒng)內(nèi)存不足時,內(nèi)核會調(diào)用 OOMKiller 選擇一個進(jìn)程來殺死,以釋放內(nèi)存并保持系統(tǒng)運(yùn)行。
OOMKiller 的工作方式是選擇消耗最多內(nèi)存且也被認(rèn)為對系統(tǒng)操作最不重要的進(jìn)程。此選擇過程基于多個因素,包括進(jìn)程的內(nèi)存使用情況、優(yōu)先級以及已運(yùn)行的時間量。
一旦 OOMKiller 選擇要終止的進(jìn)程,它就會向該進(jìn)程發(fā)送信號,要求其正常終止。如果進(jìn)程沒有響應(yīng)該信號,內(nèi)核將強(qiáng)制終止該進(jìn)程并釋放其內(nèi)存。請注意,如果節(jié)點(diǎn)上的重啟策略設(shè)置為“始終”,則由于內(nèi)存問題而被殺死的 Pod 不一定會從節(jié)點(diǎn)中逐出,而是會嘗試重新啟動 Pod。
OOMKiller 是最后手段,僅當(dāng)系統(tǒng)面臨內(nèi)存不足的危險(xiǎn)時才會調(diào)用。雖然它可以幫助防止系統(tǒng)因內(nèi)存耗盡而崩潰,但值得注意的是,終止進(jìn)程可能會導(dǎo)致數(shù)據(jù)丟失和系統(tǒng)不穩(wěn)定。因此,建議配置您的系統(tǒng)以避免 OOM 情況,例如,通過監(jiān)視內(nèi)存使用情況、設(shè)置資源限制以及優(yōu)化應(yīng)用程序中的內(nèi)存使用情況。
在底層,Linux 內(nèi)核為主機(jī)上運(yùn)行的每個進(jìn)程維護(hù)一個 oom_score。該分?jǐn)?shù)越高,進(jìn)程被殺死的機(jī)會就越大。另一個值稱為 oom_score_adj,允許用戶自定義 OOM 進(jìn)程并定義何時應(yīng)終止進(jìn)程。
Kubernetes 在為 Pod 定義服務(wù)質(zhì)量 (QoS) 類時使用 oom_score_adj 值??梢詫⑷齻€ QoS 類別分配給 pod,每個類別都有一個匹配的 oom_score_adj 值:
-
Guaranteed: -997
-
BestEffort: 1000
-
Burstable:?min(max(2, 1000 — (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999)
由于 Qos 值為Guaranteed 的 Pod 的值較低,為 -997,因此它們是內(nèi)存不足的節(jié)點(diǎn)上最后被殺死的。BestEffort pod 是最先被殺死的,因?yàn)樗鼈兊闹底罡邽?1000。
要查看 Pod 的 QoS 類別,請運(yùn)行以下命令:
kubectl describe pod <POD_NAME> | grep "QoS Class"kubectl describe pod busybox-busybox-854bfd7f4d-cwr8s -n dep-xxx-uat | grep "QoS Class"
QoS Class: Burstable
查看Pod的oom_score:
kubectl exec -it <POD_NAME> /bin/bashkubectl exec -it dep-redis-deployment-587bdcbc99-4bhsz -n dep-xxx-uat /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
bash-5.0# cat /proc/1/oom_score
1312
OOMKilled診斷?
檢查 pod 日志:診斷 OOMKilled 錯誤的第一步是檢查 pod 日志,看看是否有任何指示內(nèi)存問題的錯誤消息。描述命令的事件部分將給出進(jìn)一步的確認(rèn)以及錯誤發(fā)生的時間/日期。?
kubectl describe pod <podname>
State: RunningStarted: Fri, 12 May 2023 11:14:13 +0200Last State: TerminatedReason: OOMKilledExit Code: 137...
您還可以通過進(jìn)入該pod運(yùn)行的主機(jī)后臺方式查詢 pod 日志:
cat /var/log/pods/<podname>cd /var/log/pods/dep-xxx-uat_dep-redis-deployment-587bdcbc99-b5pfc_e97776e7-7e4c-4632-b1e6-fc15dd88ed15ls
dep-redis-deploymentcd dep-redis-deployment/
ls
0.logls -l
lrwxrwxrwx 1 root root 176 Oct 9 23:41 0.log -> /var/lib/containers/docker/containers/aa87d2a7abcf92acbe4a9a47119d0d806236c78de65519969f64e1b93f90bf50/aa87d2a7abcf92acbe4a9a47119d0d806236c78de65519969f64e1b93f90bf50-json.log
監(jiān)控內(nèi)存使用情況:使用 Prometheus 或 Grafana 等 Kubernetes 監(jiān)控工具來監(jiān)控 Pod 和容器中的內(nèi)存使用情況。這可以幫助您識別哪些容器消耗過多內(nèi)存并觸發(fā) OOMKilled 錯誤。
使用內(nèi)存分析器:使用內(nèi)存分析器(例如 pprof)來識別內(nèi)存泄漏或可能導(dǎo)致內(nèi)存使用過多的低效代碼。
??
Kubernetes OOMKilled 錯誤的常見原因及解決方法?
1、已達(dá)到容器內(nèi)存限制。這可能是由于在容器清單中指定的內(nèi)存限制值上設(shè)置了不適當(dāng)?shù)闹?#xff0c;這是允許容器使用的最大內(nèi)存量。這也可能是由于應(yīng)用程序的負(fù)載高于正常負(fù)載。解決方案是增加內(nèi)存限制的值或調(diào)查負(fù)載增加的根本原因并進(jìn)行修復(fù)。造成這種情況的常見原因包括大文件上傳,因?yàn)樯蟼鞔笪募拇罅績?nèi)存資源,尤其是當(dāng)一個 Pod 中運(yùn)行多個容器時,以及流量突然增加導(dǎo)致的高流量。
2、由于應(yīng)用程序遇到內(nèi)存泄漏,因此已達(dá)到容器內(nèi)存限制。需要調(diào)試應(yīng)用程序以解決內(nèi)存泄漏的原因。
3、節(jié)點(diǎn)過度使用——這意味著 Pod 使用的總內(nèi)存大于可用的節(jié)點(diǎn)總內(nèi)存。通過擴(kuò)展來增加節(jié)點(diǎn)可用的內(nèi)存,或者將 Pod 移動到具有更多可用內(nèi)存的節(jié)點(diǎn)。您還可以調(diào)整在過度使用的節(jié)點(diǎn)上運(yùn)行的 Pod 的內(nèi)存限制,使它們符合可用邊界,請注意,您還應(yīng)該注意內(nèi)存請求設(shè)置,該設(shè)置指定 Pod 應(yīng)使用的最小內(nèi)存量。如果設(shè)置得太高,可能無法有效利用可用內(nèi)存。在調(diào)整內(nèi)存請求和限制時,請記住,當(dāng)節(jié)點(diǎn)過度使用時,Kubernetes 將根據(jù)以下優(yōu)先級順序殺死 pod:
-
沒有請求或限制的 Pod
-
有請求但沒有限制的 Pod
-
使用超過其內(nèi)存請求值(指定的最小內(nèi)存)但低于其內(nèi)存限制的 Pod
-
使用超過內(nèi)存限制的 Pod