自動擴容之Horizontal Pod Autoscaling(HPA)
我們通過手動執行kubectl scale命令,可以實現Pod擴容。但是,分散式系統要能夠根據當前負載的變化情況自動觸發水平擴充套件或縮容的行為,因為這一過程可能是頻繁發生的、不可預料的,所以手動控制的方式是不現實的。
-
因此,在Kubernetes1.1版本中首次釋出了這一重量級新特性-----Horizontal Pod Autoscaler。
-
Horizontal Pod Autoscaler簡稱HAP,意思是Pod橫向自動擴容,與之前的RC、Deployment一樣,也屬於一種Kubernetes資源物件。通過追蹤分析RC控制的所有目標Pod的負載來自動水平擴容,如果系統負載超過預定值,就開始增加Pod的個數,如果低於某個值,就自動減少Pod的個數。
目前,可以有以下兩種方式作為Pod負載的度量指標:
1、CPU utilization percentageb,
2、應用程式自定義的度量指標,比如服務在每秒內的相應的請求數(TPS或QPS)。
-
CPU utilization percentage是一個算術平均值,即目標pod所有副本自身的CPU利用率的平均值。一個Pod自身的CPU利用率是該Pod當前CPU使用量除以它的Pod request的值。比如當我們定義一個Pod的pod request為0.4,而當前pod的cpu使用量為0.2,則使用率為50%。如此可以得出一個平均值,如果某一個時刻CPU utilization percentage超過80%,則意味著當前Pod副本不足以支撐接下來更多的請求,需要進行動態擴容。而當請求高峰時段過去後,Pod CPU利用率又會降下來,此時對應的Pod副本數應該自動減少到一個合理的水平。
-
CPU utilization percentage計算過程使用到的Pod的CPU使用量通常是1分鐘的平均值。
條件
HPA通過定期(定期輪詢的時間通過–horizontal-pod-autoscaler-sync-period選項來設定,預設的時間為30秒)通過Status.PodSelector來查詢pods的狀態,獲得pod的CPU使用率。然後,通過現有pods的CPU使用率的平均值(計算方式是最近的pod使用量(最近一分鐘的平均值,從heapster中獲得)除以設定的每個Pod的CPU使用率限額)跟目標使用率進行比較,並且在擴容時,還要遵循預先設定的副本數限制:MinReplicas <= Replicas <= MaxReplicas。
-
計算擴容後Pod的個數:sum(最近一分鐘內某個Pod的CPU使用率的平均值)/CPU使用上限的整數+1
流程
1、建立HPA資源,設定目標CPU使用率限額,以及最大、最小例項數
2、收集一組中(PodSelector)每個Pod最近一分鐘內的CPU使用率,並計算平均值
3、讀取HPA中設定的CPU使用限額
4、計算:平均值之和/限額,求出目標調整的例項個數
5、目標調整的例項數不能超過1中設定的最大、最小例項數,如果沒有超過,則擴容;超過,則擴容至最大的例項個數
例外
考慮到自動擴充套件的決策可能需要一段時間才會生效,甚至在短時間內會引入一些噪聲。例如當pod所需要的CPU負荷過大,從而執行一個新的pod進行分流,在建立過程中,系統的CPU使用量可能會有一個攀升的過程。所以,在每一次作出決策後的一段時間內,將不再進行擴充套件決策。對於ScaleUp而言,這個時間段為3分鐘,Scaledown為5分鐘。
-
HPA允許一定範圍內的CPU使用量的不穩定,只有avg(CurrentPodsConsumption) / Target小於90%或者大於110%時才會觸發擴容或縮容,避免頻繁擴容、縮容造成顛簸。
為什麼選擇相對比率
為了簡便,選用了相對比率(90%的CPU資源)而不是0.6個CPU core來描述擴容、縮容條件。如果選擇使用絕對度量,使用者需要保證目標(限額)要比請求使用的低,否則,過載的Pod未必能夠消耗那麼多,從而自動擴容永遠不會被觸發:假設設定CPU為1個核,那麼這個pod只能使用1個核,可能Pod在過載的情況下也不能完全利用這個核,所以擴容不會發生。在修改申請資源時,還有同時調整擴容的條件,比如將1個core變為1.2core,那麼擴容條件應該同步改為1.2core,真是太麻煩了,與自動擴容的目標相悖。
下面是HPA定義的一個具體例子:
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: java-apache
namespace: default
spec:
minReplicas: 1
maxReplicas: 10
scaleTargetRef:
kind: Deployment
name: java-apache
targetCPUUtilizationPercentage: 90
根據上面的定義,我們可以知道,這個HPA控制的目標物件為一個名叫java-apache的Deployment裡的Pod副本,當這些Pod副本的CPUUtilizationPercentage的值超過90%時會觸發自動動態擴容行為,擴容或縮容時必須滿足的一個約束條件是Pod的副本數要介於1與10之間。
kubectl autoscale deployment java-apache --cpu-percent=90 --min=1 --max=10