如何優化生產環境下的Kubernetes資源分配
譯文【51CTO.com快譯】我在使用Kubernetes的頭一天將應用程序Docker容器化,并部署到生產集群。我將Buffer的其中一個***吞吐量(和低風險)端點從整體式應用程序遷移出來。這個端點造成了越來越大的麻煩,偶爾會影響優先級更高的其他流量。
我們用curl進行一番手動測試之后,決定開始將流量轉移到Kubernetes上的新服務。負載為1%時,一切看起來很棒;然后提高到10%,依然很棒;之后提高到50%,服務突然開始陷入崩潰循環。我的***反應是,將服務從4個副本增加到20個。這有點幫助,服務處理流量,但pod仍然陷入崩潰循環。
我使用kubectl describe進行一些調查后了解到,由于OOMKilled即內存不足,Kubelet在終止pod。我深入探究后意識到,我從另一個部署復制粘貼YAML時,設置了一些限制性過強的內存限制。這段經歷讓我開始思考如何有效地設置請求和限額。
一、請求vs限制
Kubernetes允許對CPU、內存和本地短暫存儲(v1.12中的測試版功能)之類的資源設置可配置的請求和限制。CPU等資源是可壓縮的,這意味著可以使用CPU管理策略來限制容器。內存等其他資源由Kubelet監控,如果超過限制就被終止。使用請求和限制的不同配置,就可以針對每個工作負載實現不同的服務質量。
1.限制
限制是允許工作負載消耗的上限。超過請求的限制閾值將觸發Kubelet終止pod。如果未設置限制,工作負載就會消耗某個節點上的所有資源。如果運行的多個工作負載沒有限制,將按照盡力原則分配資源。
2.請求
調度程序使用請求為工作負載分配資源。工作負載可以使用所有請求的資源,無需Kubernetes的干預。如果未設置限制且超過請求閾值,容器將受限制,只能使用請求的資源。如果設置了限制但未設置任何請求,請求的資源將與請求的限制相匹配。
3.服務質量
有三種基本的服務質量(QoS)可通過資源和限制來實現――***的QoS配置取決于工作負載的要求。
4.保證的QoS
保證的QoS可通過僅設置限制來實現。這意味著容器可以使用調度程序為其配置的所有資源。對于受CPU限制且相對可預測的工作負載來說,比如處理請求的Web服務器,這是很好的QoS。
5.可突發式QoS
可突發式QoS通過同時設置請求和限制(請求低于設置)來配置。這意味著可以保證容器使用最多是配置請求的資源,如果某個節點上有,可以使用資源的全部配置限額。這對于短暫使用資源或需要密集初始化過程的工作負載來說很有用。一個例子就是構建Docker容器的worker節點或運行未經過優化的JVM進程的容器。
6.盡力式QoS
盡力式QoS通過既不設置請求也不設置限制來配置。這意味著容器可以使用計算機上的任何可用資源。從調度程序的角度來看,這是優先級***的任務,會在突發式QoS和保證式QoS配置之前被終止。這對于可中斷、低優先級的工作負載(比如迭代運行的冪等優化過程)來說很有用。
二、設置請求和限制
要設置合理的請求和限制,關鍵是找到單個pod的斷點(breaking point)。若使用幾種不同的負載測試方法,可以在應用程序進入到生產環境之前了解其不同的故障模式。被推向極限時,幾乎每個應用程序都有各自的一組故障模式。
要準備測試,確保將副本計數設為1,并從一組保守的限制開始,比如:
- # limits might look something like
- replicas: 1
- ...
- cpu: 100m # ~1/10th of a core
- memory: 50Mi # 50 Mebibytes
注意,在此過程中使用限制很重要,以便清楚地看到結果(內存使用率高時遏制CPU和終止pod)。測試迭代完成后,一次更改一個資源限制(CPU或內存)。
1.Ramp-up測試
ramp-up測試逐漸增加負載,直到服務在不堪重負而失效或測試完成。
如果ramp-up測試突然失敗,這表明資源限制過于苛嚴。觀察到性能突然變化時,將資源限制增加一倍、重復測試,直到測試成功完成。
資源限制接近***時(至少對于Web風格的服務來說),性能會逐漸穩定地下降。
如果負載增加時性能沒有變化,可能為工作負載分配了太多的資源。
2.持續時間測試
運行ramp-up測試并調整限制后,可以進行持續時間測試了。持續時間測試是指在一段延長的時間內(至少10分鐘,但越長越好)添加一致的負載,但又恰好在斷點之下。
該測試的目的是識別在短暫的ramp-up測試中發現不了的內存泄漏和隱藏的隊列機制。如果在此階段進行調整,它們應該很小(變化>105)。好的結果將表明性能在測試持續期間保持穩定。
3.保留失效日志
進行測試階段時,記錄服務失敗時的執行情況至關重要。可以將故障模式添加到運行手冊(run book)和說明文檔,排查生產環境中的問題時很有用。我們在測試時發現了一些觀察到的故障模式:
- 內存慢慢增加
- CPU固定在100%
- 500s
- 響應時間長
- 請求丟棄
- 響應時間差異大
將日志保存起來,以備不時之需,因為有一天它們可以為你或同事在排查問題時幫大忙。
三、實用的工具
雖然可以使用Apache Bench之類的工具添加負載、使用cAdvisor之類的工具直觀地顯示資源利用率,但一些工具更適合設置資源限制。
1.Loader.IO
Loader.io是一種托管的負載測試服務。它讓你可以配置ramp-up測試和持續時間測試,測試運行時直觀地顯示應用程序的性能和負載,并迅速開始和停止測試。測試結果歷史記錄存儲起來,因此資源限制變化時很容易比較結果。
2.Kubescope CLI
Kubescope CLI這款工具在Kubernetes中(或本地)運行,可直接從Docker收集和直觀顯示容器度量指標。它使用cAdvisor之類的工具或另一項集群指標收集服務,每秒(而不是每隔10秒至15秒)收集一次指標。由于間隔10秒至15秒,你在測試期間大有時間錯過瓶頸。若使用cAdvisor,你得為每次測試尋找新的pod,因為Kubernetes在超過資源限制時終止pod。Kubescope CLI直接從Docker收集指標(可以設置自己的間隔),并使用正則表達式來選擇和過濾想要直觀顯示的容器,從而解決了這個問題。
結論
只有在你知道一項服務何時壞掉、如何壞掉,它才準備好用于生產環境,對此我深有體會。希望你能從我的錯誤中吸取教訓,利用其中一些方法對部署的環境設置資源限制和請求。這將為你的系統增添彈性和可預測性,從而使客戶滿意,但愿幫助你高枕無憂。
原文標題:Optimizing Kubernetes resource allocation in production,作者:Harrison Harnisch
【51CTO譯稿,合作站點轉載請注明原文譯者和出處為51CTO.com】