3 回答

TA貢獻1809條經驗 獲得超8個贊
我猜這是由Pod QoS類引起的
當系統過度使用時,QoS 類會確定哪個 pod 首先被殺死,以便將釋放的資源提供給優先級更高的 Pod。
在你的情況下,你的 Pod 的 QoS 是可爆發的
每個正在運行的進程都有一個超出內存 (OOM) 分數。系統通過比較所有正在運行的進程的OOM分數來選擇要終止的進程。當需要釋放內存時,得分最高的進程將被終止。有關如何計算的詳細信息,請參閱如何計算內核 oom 分數?。score
如果兩者都在可爆破類中,哪個 pod 會先被殺死?
簡而言之,系統將使用比另一個請求的內存更多的百分比來殺死一個。
Pod A
used: 90m
requests: 100m
limits: 200m
Pod B
used: 150m
requests: 200m
limits: 400m
Pod A之前會被殺死,因為它使用了 90% 的請求內存,而只使用了請求內存的 75%。Pod BPod B

TA貢獻1824條經驗 獲得超8個贊
確保 QoS 類為“有保證”在你的方案中無濟于事。其中一個進程導致父 cgroup 超過其內存限制(反過來由針對相應容器指定的內存限制值設置),OOM 殺手將其終止。這不是 Pod 逐出,因為您可以在日志中清楚地看到 OOM 殺手的商標信息。如果另一個 Pod 分配了如此多的內存,使節點處于內存壓力之下,那么“有保證的”QoS 類將會有所幫助 - 在這種情況下,您的“保證”Pod 將幸免于難。但在你的情況下,Kubelet從來沒有在所有這些事情中得到一個字 - 就像決定完全驅逐豆莢一樣 - 因為OOM殺手行動更快。
Burak Serdar在其評論中有一個很好的觀點 - 臨時分配大內存塊。情況很可能就是這樣,因為從您粘貼的消息中收集數據的分辨率為60s。那是很多時間。一個人可以在不到1秒的時間內輕松填充GB的RAM。我的假設是,內存“峰值”永遠不會被渲染,因為指標永遠不會被及時收集(即使你直接查詢cAdvisor,它也會很棘手,因為它的分辨率為10-15秒來收集其指標)。
如何了解更多有關正在發生的事情的信息?幾個想法:
有一些工具可以顯示應用程序實際分配了多少,一直到框架級別。在.NET中,dotMemory是一種常用的工具,可以在容器內運行并捕獲正在發生的事情。Go 可能有一個等價物。這種方法的問題在于,當容器被OOM殺死時,該工具也會隨之被刪除。
在這里,您將找到一個影片,該影片捕獲了一個進程分配內存,直到其父容器被 OOM 殺死。相應的 .NET 應用程序會不時地將它使用的內存量寫入控制臺,即使在容器不再存在后,Kubernetes 日志也會顯示這些內存量,從而允許查看發生了什么
限制應用,使其處理少量數據(例如,如果您每分鐘只處理 1 張圖片,則從內存角度臨時查看會發生什么)
查看詳細的 OOM 殺手內核日志,了解 cgroup 中的所有進程。在一個容器內有多個進程是完全有效的(就像在其他進程中一樣,除了該容器中帶有PID 1的進程),OOM殺手很可能殺死其中任何一個。在這種情況下,您可能會偶然發現意想不到的轉折。然而,在你的場景中,它似乎被終止了,否則容器就不會被OOM殺死,所以這種情況不太可能發生。
只是為了完整性:底層框架可以對容器強制實施低于內存限制的限制。例如,在.NET中,當在具有內存限制的容器中運行時,此值為75%。換句話說,在限制為 2,000 MiB 的容器內分配內存的 .NET 應用將在 1,500 MiB 時出錯。然而,在這種情況下,你得到的退出代碼為139(SIGSEGV)。這似乎不適用于這里,因為OOM殺手終止了該過程,并且從內核日志中可以清楚地看到所有1 GiB實際上都被使用了()。據我所知,Go還沒有類似的設置,盡管社區一再要求它。anon-rss:1043688kB

TA貢獻1862條經驗 獲得超6個贊
此處的資源規范是 OOM 的根本原因。
在 Kubernetes 中,所需內存和有限內存的定義不同。所需的內存是 內存 。有限內存是容器可以突增到的內存。但有限的內存并不能保證容器可以擁有該資源。must-have
在大多數生產系統中,不建議有限和所需的資源差異太大。例如,在您的情況下,
requests:
cpu: "150m"
memory: "80Mi"
limits:
cpu: "1"
memory: "1024Mi"
容器只能有80Mi保證內存,但它可以以某種方式爆發為1024Mi。節點可能沒有足夠的內存用于容器,容器本身將進入 OOM。
因此,如果要改善這種情況,則需要將資源配置為類似此類的資源。
requests:
cpu: "150m"
memory: "1024Mi"
limits:
cpu: "1"
memory: "1024Mi"
請注意,CPU很好,因為您不會在低CPU時間下殺死進程。但是OOM將導致該過程被殺死。
正如上面提到的答案,這與 pod 中的服務質量有關。通常,對于大多數最終用戶,應始終將容器配置為保證類,即請求 == 受限。在將其配置為突發類之前,您可能需要有一些理由。
- 3 回答
- 0 關注
- 177 瀏覽
添加回答
舉報