wordpress+站群軟件東莞網(wǎng)絡(luò)推廣營(yíng)銷公司
什么是 OOMKilled Kubernetes 錯(cuò)誤(Exit Code 137)
當(dāng) Kubernetes 集群中的容器超過其內(nèi)存限制時(shí),Kubernetes 系統(tǒng)可能會(huì)終止該容器并顯示“OOMKilled”錯(cuò)誤,這表明該進(jìn)程由于內(nèi)存不足而被終止。此錯(cuò)誤的退出代碼是 137。
如果遇到錯(cuò)誤,Pod 的狀態(tài)將顯示“OOMKilled”,您可以使用以下命令查看該錯(cuò)誤:
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)存不足時(shí),內(nèi)核會(huì)調(diào)用 OOMKiller 選擇一個(gè)進(jìn)程來殺死,以釋放內(nèi)存并保持系統(tǒng)運(yùn)行。
OOMKiller 的工作方式是選擇消耗最多內(nèi)存且也被認(rèn)為對(duì)系統(tǒng)操作最不重要的進(jìn)程。此選擇過程基于多個(gè)因素,包括進(jìn)程的內(nèi)存使用情況、優(yōu)先級(jí)以及已運(yùn)行的時(shí)間量。
一旦 OOMKiller 選擇要終止的進(jìn)程,它就會(huì)向該進(jìn)程發(fā)送信號(hào),要求其正常終止。如果進(jìn)程沒有響應(yīng)該信號(hào),內(nèi)核將強(qiáng)制終止該進(jìn)程并釋放其內(nèi)存。請(qǐng)注意,如果節(jié)點(diǎn)上的重啟策略設(shè)置為“始終”,則由于內(nèi)存問題而被殺死的 Pod 不一定會(huì)從節(jié)點(diǎn)中逐出,而是會(huì)嘗試重新啟動(dòng) Pod。
OOMKiller 是最后手段,僅當(dāng)系統(tǒng)面臨內(nèi)存不足的危險(xiǎn)時(shí)才會(huì)調(diào)用。雖然它可以幫助防止系統(tǒng)因內(nèi)存耗盡而崩潰,但值得注意的是,終止進(jìn)程可能會(huì)導(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)行的每個(gè)進(jìn)程維護(hù)一個(gè) oom_score。該分?jǐn)?shù)越高,進(jìn)程被殺死的機(jī)會(huì)就越大。另一個(gè)值稱為 oom_score_adj,允許用戶自定義 OOM 進(jìn)程并定義何時(shí)應(yīng)終止進(jìn)程。
Kubernetes 在為 Pod 定義服務(wù)質(zhì)量 (QoS) 類時(shí)使用 oom_score_adj 值。可以將三個(gè) QoS 類別分配給 pod,每個(gè)類別都有一個(gè)匹配的 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 類別,請(qǐng)運(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 錯(cuò)誤的第一步是檢查 pod 日志,看看是否有任何指示內(nèi)存問題的錯(cuò)誤消息。描述命令的事件部分將給出進(jìn)一步的確認(rèn)以及錯(cuò)誤發(fā)生的時(shí)間/日期。?
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ī)后臺(tái)方式查詢 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)存使用情況。這可以幫助您識(shí)別哪些容器消耗過多內(nèi)存并觸發(fā) OOMKilled 錯(cuò)誤。
使用內(nèi)存分析器:使用內(nèi)存分析器(例如 pprof)來識(shí)別內(nèi)存泄漏或可能導(dǎo)致內(nèi)存使用過多的低效代碼。
??
Kubernetes OOMKilled 錯(cuò)誤的常見原因及解決方法?
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)樯蟼鞔笪募?huì)消耗大量?jī)?nèi)存資源,尤其是當(dāng)一個(gè) Pod 中運(yùn)行多個(gè)容器時(shí),以及流量突然增加導(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 移動(dòng)到具有更多可用內(nèi)存的節(jié)點(diǎn)。您還可以調(diào)整在過度使用的節(jié)點(diǎn)上運(yùn)行的 Pod 的內(nèi)存限制,使它們符合可用邊界,請(qǐng)注意,您還應(yīng)該注意內(nèi)存請(qǐng)求設(shè)置,該設(shè)置指定 Pod 應(yīng)使用的最小內(nèi)存量。如果設(shè)置得太高,可能無法有效利用可用內(nèi)存。在調(diào)整內(nèi)存請(qǐng)求和限制時(shí),請(qǐng)記住,當(dāng)節(jié)點(diǎn)過度使用時(shí),Kubernetes 將根據(jù)以下優(yōu)先級(jí)順序殺死 pod:
-
沒有請(qǐng)求或限制的 Pod
-
有請(qǐng)求但沒有限制的 Pod
-
使用超過其內(nèi)存請(qǐng)求值(指定的最小內(nèi)存)但低于其內(nèi)存限制的 Pod
-
使用超過內(nèi)存限制的 Pod