Cerebral vs Kubernetes Cluster Autoscaler: 搶佔式自動縮放演示

cerebral_kubernetes.png

Cerebral是一個開源的工具,用於響應用戶定義的策略生成的警報來增長或減少Kubernetes集羣中節點池的大小。這些策略引用可插拔和可配置的度量標準後端,以收集度量標準以進行自動縮放決策。node

本文,在易於搭建的 Kops環境中將Cerebral與Kubernetes Cluster Autoscaler進行了公平地比較和對比。git

Kubernetes 伸縮基礎

要了解生產中的自動縮放,咱們首先必須退後一步,從通常意義上理解Kubernetes的自動縮放。與Kubernetes相關的自動縮放器有幾類:github

在本文中,咱們將重點介紹水平Pod自動縮放和羣集自動縮放。它們一般相互串聯使用,所以,咱們將研究HPA與集羣自動縮放器之間的交互以及不一樣集羣自動縮放器實現之間的權衡。特別是,咱們將介紹Cerebral和Kubernetes Cluster Autoscaler(CA)項目之間的區別。json

Kubernetes Cluster Autoscaler 總覽

Kubernetes Cluster Autoscaler採用一種簡單的方法(至少在較高級別上)來決定什麼時候將節點添加到集羣中:當發現沒法調度Pod並肯定添加新節點後將可以調度成功該Pod時,它將進行擴展。這種方法有不少好處,例如,它僅依賴於Kubernetes核心概念。它還保證僅在絕對須要時才添加節點,由於它知道因爲資源不足而致使Pod處於pending狀態。後端

這種方法的主要缺點是,它太慢了,沒法知足實際的業務需求。在許多狀況下,等到沒法調度Pod的時間爲時已晚。app

使用CA進行縮小也很簡單:若是某個節點在必定時間內未獲得充分利用,而且當前能夠在該節點上運行的Pod能夠從新安排到另外一個節點上,則它將刪除該節點。負載均衡

對於CA如何工做的細節,FAQ是一個很好的資源。curl

Cerebral 總覽

Cerebral的構建考慮了靈活性。它使operators能夠輕鬆地對從各類來源收集的指標進行自動縮放配置,並能夠經過使用自定義資源定義(CRD)在雲環境之間輕鬆移植的方式進行配置。ide

Cerebral採用的搶佔式自動縮放方法與標準的Kubernetes Cluster Autoscaler根本不一樣。 Cerebral無需等待直到沒法安排Pod,而是決定根據來自可配置指標後端的用戶指定指標進行擴展。在撰寫本文時,主要的Cerebral存儲庫中支持如下後端:Prometheus,InfluxDB和Kubernetes自己。工具

經過實現簡單的接口並在新的MetricsBackend CRD中定義後端的配置,也能夠輕鬆構建自定義後端。自定義後端的可能性是無限的。例如,可使用Cerebral基於特定於應用程序的隊列的深度來自動縮放羣集。

在本文中,咱們將堅持使用Kubernetes後端與Kubernetes CA進行公平比較。

有關Cerebral的工做方式的更多詳細信息,以及其餘指標後端和雲提供商的入門信息,請參閱GitHub上的項目。

自動縮放實驗

讓咱們看一個簡單的示例,將HPA與Kubernetes Cluster Autoscaler和Cerebral結合使用。這將使咱們可以在模擬的真實場景中對比Kubernetes CA和Cerebral。

若是您對實驗自己不感興趣,請隨時跳至「關鍵」部分。

在AWS準備一個測試集羣

雖然Cerebral已徹底集成到支持AWS的Containership Kubernetes Engine(CKE)中,但讓咱們改用kops以便從基礎上進行構建。

咱們建立了一個具備很是基本的kops集羣配置的公共要點,任何人均可以複製它以進行後續操做。集羣具備一個主節點和一個節點池(等於一個AWS Auto Scaling組),其最小大小爲1個節點,最大大小爲5個節點。只需在S3中建立一個新的存儲桶以用做集羣狀態存儲,而後按如下步驟建立集羣便可。首先以kops建立集羣配置:

kops --state=s3://bucket-name create -f https://gist.githubusercontent.com/mattkelly/692af294868ff50a6c5664ea63b7e9c4/raw/48b00e3dc3d7de18c040522a6392a92beb9dc7e1/kops\-autoscaling-demo-cluster-config.yaml

你應該能看到以下的輸出:

image.png

如今apply更改以實際建立集羣:

kops --state=s3://bucket-name update cluster autoscaling-experiment.k8s.local --yes

它可能會提示您首先指定一個公用SSH密鑰。若是是這樣,只需按照說明建立密鑰,而後從新運行更新命令。

您應該看到一堆輸出,而後最終是:

image-1.png

幾分鐘後,您應該可以與羣集進行交互。嘗試kubectl get nodes,直到它起做用爲止(請注意,若是一切順利,kops將適當地設置您的kubectl上下文)。

有關kops的更多信息,請參考存儲庫

部署 Kubernetes Metrics Server

水平Pod自動縮放器須要知道Pod正在消耗多少資源。
爲此,咱們須要部署metrics-server。請注意,僅HPA才須要,而不是Cerebral或Kubernetes CA都須要。

啓動並運行metrics-server的最簡單方法是簡單地克隆存儲庫並部署全部Kubernetes v1.8 +清單。不幸的是,咱們發現須要一些變通辦法來使清單在此kops羣集上正常工做。一旦再也不須要此解決方法,咱們將更新本文。

同時,您能夠在個人fork上使用分支:

git clone git@github.com:mattkelly/metrics-server.git 
cd metrics-server 
git checkout bugfix/deploy-1.8+

應用如下相關清單:

kubectl apply -f deploy/1.8+/

檢查metrics-server pod日誌,以確保一切正常:

kubectl -n kube-system logs -lk8s-app=metrics-server

建立用於自動擴展的資源使用者部署

如今,咱們已經創建了一個羣集,而且可使用運行情況良好的metrics server,讓咱們繼續建立一個部署,能夠將其包裝在HPA中以運行實驗。若是咱們可以經過強制它消耗某些請求的結果而消耗指定數量的CPU或內存來使它按需擴展,那就太好了。幸運的是,生活在Kubernetes存儲庫深處的resource-consumer確實作到了這一點。

讓咱們根據CPU利用率自動調整resource-consumer部署。咱們的工做節點池正在使用t2.small實例,這些實例具備1個CPU(1000 millicores)和2 GB的內存。因爲工做池的最小節點數爲1,而且還沒有擴展,所以該池中只有一個節點。使用kubectl describe節點,咱們看到該節點已經在使用640 millicores的CPU:

image-2.png

讓咱們在默認命名空間中運行resource-consumer,請求爲100 millicores,並使用負載均衡器公開它,以便咱們向其發送請求:

kubectl run resource-consumer --image=gcr.io/kubernetes-e2e-test-images/resource-consumer:1.4 --expose --service-overrides='{ "spec": { "type": "LoadBalancer" } }' --port 8080 --requests='cpu=100m'

馬上,咱們看到初始的單個副本正按預期從節點請求另外一個100m:

image-3.png

因爲使用負載均衡器公開了resource-consumer的部署,所以咱們還應該可以使用kubectl get服務來查看它是否已正確分配了外部地址:

image-5.png

讓咱們導出完整的地址以供之後發送請求:

export RESOURCE_CONSUMER_ADDRESS="http://$(kubectl get service resource-consumer -ojsonpath='{.status.loadBalancer.ingress[0].hostname}'):8080"

建立水平Pod自動縮放器(HPA)

如今,咱們將HPA添加到resource-consumer部署中。若是觀察到的Pod CPU利用率超過Pod CPU請求的50%,則此HPA將添加一個新Pod(最多10個Pod)。若是部署中的Pod沒有顯示出很高的CPU利用率,它還將縮小到最少1個Pod。

kubectl autoscale deployment resource-consumer --cpu-percent=50 --min=1 --max=10

您應該可以使用kubectl get hpa看到新建立的HPA,由於它只是另外一個Kubernetes資源:

image-8.png

注意:HPA就像其餘任何Kubernetes控制器同樣都是循環檢查。默認狀況下,它們每15秒收集一次指標。所以,利用率百分比可能會短暫顯示爲<未知>,直到收集度量爲止。

正如預期的那樣,資源消耗者實際上並無消耗任何CPU,由於咱們還沒有要求這樣作。

如今咱們已經設置了HPA,讓咱們經過消耗CPU並查看Kubernetes Cluster Autoscaler和Cerebral的反應來強制其擴展!

設置Kubernetes Cluster Autoscaler

咱們建立了一個公共gist,能夠很容易地在此kops集羣上啓動和運行Kubernetes集羣自動縮放器(CA)。它對AWS清單所示的CA示例進行了以下調整:

  • 添加已將主部署更新爲參考的secret
  • 設置部署命令以正確地引用帶有預期最小/最大界限的kops輔助節點池。
  • 添加容忍和節點選擇器以使其僅在主節點上運行

只需下載文件,填寫AWS_ACCESS_KEY_ID和AWS_SECRET_ACCESS_KEY的有效值,而後kubectl便可應用它。

您能夠經過檢查日誌來檢查集羣自動伸縮器部署是否正常:

kubectl -n kube-system logs -lapp=cluster-autoscaler

此處應用的「cerebral-aws-engine」secret也能夠與Cerebral自動縮放器一塊兒使用。)

注意:這只是出於演示目的運行CA的一種簡單方法。若是您對在生產環境中運行CA感興趣,請閱讀文檔以肯定最適合您的環境(包括身份驗證方法等)的文檔。

使用Kubernetes集羣自動縮放器進行集羣自動縮放演示

僅當沒法調度Pod時,Kubernetes Cluster Autoscaler纔會縮放。這種縮放方法學是CA與Cerebral之間的主要區別之一。讓咱們確切地瞭解這在實踐中意味着什麼。

爲了模擬需求激增的開始,讓咱們經過將請求發佈到其ConsumeCPU端點來告訴resource-consumer消耗CPU:

curl --data "millicores=60&durationSec=600"  $RESOURCE_CONSUMER_ADDRESS/ConsumeCPU

若是願意,您能夠經過在第二個終端上運行watch來實時觀看動做:

watch --differences kubectl get deployments,replicasets,pods,hpa

片刻以後,您應該看到此峯值致使HPA向部署中添加了另外一個Pod,以知足需求並保持部署中Pod的CPU利用率低於50%的目標:

image-9.png

再過一下子,您應該會看到狀況穩定下來,而且HPA報告了新的CPU利用率:

image-10.png

而且kubectl describe nodes顯示新副本向該節點添加了另外100m的CPU請求:

image-11.png

咱們有一個簡單,可重複的環境,Horizo​​ntal Pod Autoscaler能夠按預期工做。

如今,咱們假設在很短的時間內,需求會增長更多:

curl --data "millicores=120&durationSec=600"  $RESOURCE_CONSUMER_ADDRESS/ConsumeCPU

片刻以後,咱們看到HPA能夠擴展以知足新的需求:

image-12.png

看起來咱們有一個處於待定狀態的Pod,所以咱們尚未成功地進行擴展以知足新的需求。這裏發生了什麼?使用該Pod上的kubectl describe,咱們能夠看到該Pod沒法調度,由於工做節點沒有足夠的CPU來知足全部CPU請求。因爲咱們如今有4個副本,這比640m / 1000m的基本狀態多了400m的CPU請求,所以只能在該節點上安排3/4個副本。

kubectl describe pod/resource-consumer-55c57bc84c-986lk

image-13.png

咱們還能夠看到因爲掛起的pod觸發了放大。在等待新節點出現以後,另外一個kubectl describe顯示pod最終被調度在新節點上。

image-14.png

kubectl get events --field-selector=involvedObject.name=resource-consumer-55c57bc84c-986lk -o=custom-columns=FIRST_TIMESTAMP:.firstTimestamp,TYPE:.type,REASON:.reason,MESSAGE:.message

image-15.png

從以上內容能夠看出,CA迅速作出反應,要求AWS擴展實例組-但僅在pod未能首先調度好以後。

Cooling Down

若是咱們等待對resource-consumer的請求中的durationSec指定的持續時間,咱們將看到resource-consumer回落到其原始資源使用狀況。 CA會注意到這一點,並在默認的冷卻時間10分鐘後請求縮減規模。這對於節省成本相當重要。能夠經過CA配置來調整冷卻時間。

使用Cerebral搶佔式自動縮放

清理並從新開始

確保咱們從頭開始的最簡單方法是簡單地刪除kops集羣並從新建立它。要刪除它,請運行如下命令:

kops --state=s3://bucket-name delete cluster autoscaling-experiment.k8s.local --yes

如今,只需從新建立測試設置,從建立kops集羣開始,到配置HPA後結束。

部署Cerebral

在腦存儲庫中能夠找到許多示例清單。首先,咱們須要應用一些必備清單,這些清單定義一些自定義資源定義,一個Cerebral的服務賬戶以及一些RBAC規則:

kubectl apply -f https://raw.githubusercontent.com/containership/cerebral/v0.4.0-alpha/examples/common/00-prereqs.yaml

咱們還必須像之前同樣使用AWS憑證應用相同的secret。咱們能夠下載示例secret清單並進行適當的編輯:

curl -O  https://raw.githubusercontent.com/containership/cerebral/master/examples/engines/aws/00-secret-cerebral-aws.yaml

# Edit OO-secret-cerebral-aws.yaml to fill in valid values 

kubectl apply -f OO-secret-cerebral-aws.yaml

接下來,讓咱們部署Cerebral operator,它做爲Kubernetes部署運行:

kubectl apply -f https://raw.githubusercontent.com/containership/cerebral/v0.4.0-alpha/examples/engines/aws/10-deployment-cerebral-aws.yaml

要向Cerebral註冊AWS自動縮放引擎,須要一個AutoscalingEngine資源:

kubectl apply -f https://raw.githubusercontent.com/containership/cerebral/master/examples/engines/aws/20-autoscaling-engine-aws.yaml

最後,讓咱們向Cerebral註冊Kubernetes MetricsBackend:

kubectl apply -f https://raw.githubusercontent.com/containership/cerebral/v0.4.0-alpha/examples/metrics_backends/kubernetes/00-metrics-backend-kubernetes.yaml

若是一切順利,日誌應該看起來很健康,咱們應該看到有關引擎和後端成功註冊的消息:

kubectl -n kube-system logs -lapp.kubernetes.io/name=cerebral

image-16.png

配置 Autoscaling Groups and Policies

既然Cerebral已啓動並在Kubernetes指標後端已註冊並運行AWS引擎的狀況下運行,咱們能夠將重點轉移到定義一個自動擴展組和擴展該組的策略。

Cerebral存儲庫中提供了示例AutoscalingGroups以及示例AutoscalingPolicies。可是,讓咱們在此處建立更特定於咱們的測試設置的組和策略。

首先,讓咱們定義一個AutoscalingPolicy,該策略使用在上一步中定義的kubernetes指標後端收集CPU分配指標以進行自動縮放決策。咱們將每15秒輪詢一次指標後端,並在30秒內進行抽樣。若是CPU分配大於或等於80%的時間超過該採樣週期,則Cerebral將按一個節點擴展:

image-30.jpg

如今應用它:

kubectl apply -f cpu-example-policy.yaml

接下來,讓咱們定義AutoscalingGroup,以使minNodes和maxNodes與kops定義的AWS AutoscalingGroup相匹配。這對於避免意外行爲很重要。選擇用於選擇屬於該組的節點的標籤選擇器,以匹配咱們在kops配置中分配給工做組的標籤,而咱們剛剛定義的策略將附加到該組:

image-31.jpg

如今應用它:

kubectl apply -f kops-group.yaml

有了這些簡單的清單,一旦CPU分配超出閾值,Cerebral如今就能夠自動縮放Kubernetes集羣。

使用Cerebral 進行集羣擴縮演示

徹底按照咱們在Kubernetes Cluster Autoscaler演示中所作的同樣,讓咱們​​向resource-consumer發出請求以使其消耗更多的CPU以模擬需求高峯的開始:

curl --data "millicores=60&durationSec=600"  $RESOURCE_CONSUMER_ADDRESS/ConsumeCPU

如預期的那樣,第二個副本將出現並在幾分鐘後開始運行:

image-17.png

和之前同樣,這會將工做節點池上的CPU請求總數提升到80%以上。Cerebral注意到了這一點,在咱們在AutoscalingPolicy中配置的短暫採樣週期以後,觸發了放大事件。咱們能夠在Cerebral日誌中看到這一點:

image-18.png

您還會在日誌中注意到,引擎會忽略全部後續縮放請求,由於自動縮放組已進入了咱們定義的冷卻期。這爲新節點的創建提供了時間,並有助於避免對雲提供商的伸縮請求進行大幅調整。

在短期內,AWS會啓動新節點,並能夠用於調度:

kubectl get events --field-selector=involvedObject.name=ip-172-20-37-156.ec2.internal -o=custom-columns=FIRST_TIMESTAMP:.firstTimestamp,REASON:.reason,MESSAGE:.message![image-19.png](/img/bVbCXem)

image-19.png

如您所見,在觸發放大以前,咱們沒必要等待任何pod處於「待處理」狀態。違反定義的CPU資源請求閾值後,就會觸發放大事件。換句話說,Cerebral搶先調度另外一個節點,以知足Pod調度需求。

Cooling Down

在增長的需求減小以後縮減規模以節省成本一樣容易。
只需編輯AutoscalingPolicy便可添加一個縮減策略,一旦資源請求低於定義的閾值,該策略就會觸發。

重點

當在咱們的測試場景中增長負載時,Kubernetes Cluster Autoscaler(CA)和Cerebral都可以成功地擴展集羣(向該集羣添加節點)。當發現負載正在增長時,Cerebral可以使用用戶定義的CPU閾值搶先擴大規模。可是,Kubernetes CA必須等待,直到沒法調度Pod。

這只是使用Cerebral優於Kubernetes CA的一個很是具體的例子。Cerebral的真正力量在於其靈活性和可擴展性。例如,在先前的實驗中,若是負載瞬間增長到最高點,則Cerebral將沒法搶先縮放,而且兩個自動縮放器之間的結果將很是類似。可是,與Kubernetes CA不一樣,Cerebral能夠配置爲使用自定義指標/事件後端來觸發不一樣指標的縮放(例如,push ,應用程序隊列深度達到某個閾值等)。

藉助Cerebral,操做員能夠以對其系統有意義的方式配置自動縮放。因爲基於CRD的方法,他們還能夠輕鬆地將此功能轉移到其餘雲提供商。

相關文章
相關標籤/搜索