Kubernetes計算資源管理

聞數起舞 發佈 2020-05-14T14:22:45+00:00

在Almatar,與Kubernetes(k8s)進行了大規模合作,在極少數情況下,我們的某些服務遇到意外行為,導致我們提出了很少的問題,以使事情變得更加穩定和可靠。

在Almatar,與Kubernetes(k8s)進行了大規模合作,在極少數情況下,我們的某些服務遇到意外行為,導致我們提出了很少的問題,以使事情變得更加穩定和可靠。 其中之一是當一個Pod停止運行時該怎麼辦,因為k8無法滿足特定節點上該Pod所需的資源(就內存和CPU而言),我們是否應該在這種情況下重新啟動Pod? 有沒有更聰明的方法來管理資源分配? 讓我們看看我們如何遇到這種情況以及如何更好地控制它。

Kubernetes,大圖景

在容器化的世界中,Kubernetes在其控制平面中又有多個組件,即一個主節點,其中之一就是kube-scheduler。 是組件/流程,負責監視集群中的Pod,將工作負載分配給相應的節點,以及跟蹤每台正在運行的主機上的資源利用率,以使工作負載與可用資源匹配。

資源限制是Kubernetes用於獲取信息的信息的參數,該信息是Pod正常運行所需的資源是什麼以及Pod可以利用的最大允許資源是多少。

調度程序還負責根據計算資源利用率(內存/ CPU)與可用節點匹配容器需求,即:對於需要X內存和Y CPU的新創建的Pod,調度程序將確保分配容器。 裝到可以處理分配給它的工作負載的節點上,否則會發生什麼? 默認的k8s分配沒有針對內存/ CPU的強制資源限制,因此,容器可以與同一個節點中的其他Pod一起使用儘可能多的資源,從而相互影響,可能會出現擁塞狀態。

負載測試背景

在發布我們的航班產品之前,我們開始使用Apache JMeter進行一些負載測試,並通過Grafana收集少量指標,以確保在高流量期間一切穩定。

如果容器超出了其允許的內存限制(在我們的情況下為無限制),則kubelet(在每個節點上運行的守護程序)將開始採取措施以重啟有問題的Pod(如果可能的話),否則,如果其超出了請求的內存(在我們的情況下) 它也處於打開狀態),如果Pod導致節點內存不足(或基於內核發出信號的方式殺死了oom),則該Pod將被驅除,或者同一節點中的其他Pod也可能被驅逐,從而導致更多混亂和 這些服務不穩定,會間歇性停止運行。

在此階段,一切可能仍然很好,Kubernetes將重新啟動Pod,Linux內核將回收一些空間,然後調度程序將Pod重新調整到其他節點(請記住,尚無分配策略),但是我們仍然有風險 在其他節點上再次發生相同的行為。 我們需要根據每個服務的當前消耗率對Kubernetes進行檢測,以便在當前基礎架構下可以做出更好的分配決策。

K8中的這些請求/限制是什麼?

在kube-scheduler決定在哪個節點上放置容器/容器之後,重要的是容器具有可在該節點上運行的足夠資源,這是kubelet守護程序在每個負責節點運行狀況的節點上運行的角色。 豆莢。 例如,如果您的應用程式需要8 GB的內存(RAM),而主機上允許的最大容量為<8 GB,則將導致該節點內存不足,並且一切將停止工作。 設置這些需求很重要,這樣調度程序才能在放置步驟中做出更好的決策。 但是這些指標如何設置以及設置什麼?

請求(例如:8 GB內存,0.1 CPU):告訴Kubernetes僅在具有這些資源可用的節點上分配容器。

限制(例如:10 GB內存,0.2 CPU):告訴Kubernetes調度程序在消耗資源時不要讓Pod超過這些閾值(達到這些限制然後限制它)。

spec: 
  containers: 
  - image: php 
  imagePullPolicy: IfNotPresent 
  name: flights-x-service   
  ports: 
  - containerPort: 80 
  protocol: TCP 
  resources: 
    limits: 
      cpu: 800m 
      memory: 2000Mi 
    requests: 
      cpu: 700m 
      memory: 1000Mi

簡而言之,上面的示例描述了一個Pod的部署,其中包含一個正在運行的PHP映像容器,並按以下方式指定了請求:

· 要求cpu:700m(以毫米為單位)

· 請求內存:1000Mi(以兆字節為單位)

· 限制cpu:800m(最高可達800毫米)

· 限制內存:2000Mi(最多可占用2000兆字節)

調度程序將首先嘗試找到一個可以處理請求閾值的節點(如果找到了該節點,則將其分配給它),但是如果找不到節點會發生什麼呢? 如果這些請求閾值太高或運行時超出了這些限制,該怎麼辦?

· 如果請求值設置得太高,則調度程序將無法在任何節點上調度Pod並掛起。 查看命名空間中引發的事件,我們將看到原因:

$ kubectl get events | grep flights-x-serviceWarning FailedScheduling0/x nodes are available:x Insufficient memory, y Insufficient cpu.

· 對於在運行時Pod超出其內存/ cpu限制的其他情況,kubernetes的行為會有所不同,具體取決於哪種資源類型。 CPU資源是可壓縮的,這意味著kubernetes將在CPU達到其極限時對其進行壓縮,但不會終止pod,從而導致應用程式性能下降。 另一方面,內存是不可壓縮的(無法像cpu一樣限制內存),如果內存超出了允許的配額,則pod將終止。

還有其他更深入的文章,討論kubelet如何處理資源不足的情況

如何定義請求限制閾值(上限)?

在開始時,我們主要採用一種實驗方法來在進行負載測試時跟蹤資源利用率,然後,我們可以使用分析/監控工具來跟蹤Pod的使用情況,並在需要時調整閾值以防止利用率過高或不足 在資源中,結果稱為"上限"或簡稱為" Ulimits":

· 如果我們能夠在短時間窗口內模擬成千上萬的用戶訪問平台的行為,那麼我們可以對集群中的資源分配進行一些粗略的估算;如果它是一個簡單的API,我們可以使用loader.io之類的東西或構建 使用Apache JMeter進行一些更複雜的流程,然後使用kubescope-cli或與Kubernetes集成的任何其他分析/監視工具(如Grafana)監視每個pod上的資源利用率。

2.一旦記錄了已使用的內存/ CPU,就可以開始按其類型對Pod利用率進行分類,還記得我們要回答的下一個問題是:如果我們有一個新的服務部署,那麼應該為其分配什麼資源閾值? ,貪婪的方法主要有以下三類:

· 高流量:在阿拉木圖,這些是沿用戶操作(例如搜索,產品選擇等)的關鍵路徑的請求的主要消費者。

· 中流量:可能是按機率命中的服務,即:由另一個緩存層支持的服務,該緩存層並未在每個繁忙流量的請求路徑上使用。

· 低流量:可能是受到攻擊的可能性很小,例如:擁有一些通過某些API為航班/酒店提供靜態數據的服務,這些服務可用於將信息植入其他層,例如Elastic Search, 這些甚至在其請求期間也不需要大量消耗。

3.除了上述存儲桶之外,其他Pod可以構成其他類別,例如資料庫存儲,例如,如果一個Pod用於mongodb,則Mongodb的u限制有一個額外的層,例如:https://docs.mongodb.com/ manual / reference / ulimit /引用了有關文件大小,內存分配,堆棧大小等的更詳細的限制級別。

4.對於請求的任何新服務,默認部署文件應考慮根據服務所屬的類別設置一些默認限制。 以後,可以根據需要調整這些限制,重新設計請求的關鍵路徑,等等。

最後的想法

· 可以在名稱空間級別上設置一些資源配額,它控制同一名稱空間中所有Pod的聚合資源消耗。 可以創建具有不同分類的ResourceQuota Kubernetes對象(將其視為標籤),為每個標籤設置一些內存/ cpu閾值,然後為每個創建的Pod指定一個標籤以引用ResourceQuota對象中定義的資源閾值, 例如:高流量客艙,低流量客艙,等等。

· 生產負載測試可能很棘手,我們需要在非尖峰時間在生產環境中連續運行這些定期測試,同時確保不會耗盡資源,從而導致其他服務的停機,設置u-limits非常重要 在進入這個階段之前。

· 本文介紹了對k8s Pod設置ulimit的重要性,請求和限制如何不同以及Kubernetes在這些閾值方面的行為的基本理解。 可以採用許多其他方法來完善這些閾值,更好地控制(不僅是容器)持久性卷,存儲請求等。

參考文獻:

· ResourceQuota對象類型:https://kubernetes.io/docs/concepts/policy/resource-quotas/

· 了解Kubernetes內存:https://medium.com/@betz.mark/understanding-resource-limits-in-kubernetes-memory-6b41e9a955f9

· Kubernetes最佳做法:https://cloud.google.com/blog/products/gcp/kubernetes-best-practices-resource-requests-and-limits

· 通過資源限制和負載測試充分利用kubernetes:https://www.youtube.com/watch?v=NuLFomXGUj4

我們的DevOps團隊的Tamer Elfeky和Mohamed Abdulmoghni表示敬意。

(本文翻譯自Islam Hamdi的文章《Kubernetes Compute Resource Management》,參考:https://medium.com/almatar-ota/kubernetes-compute-resource-management-and-upper-limits-910579d4fb06)

關鍵字: