背景
在 K8s 1.18 之前,HPA 擴容是無法調整靈敏度的:
- 對于縮容,由
kube-controller-manager的--horizontal-pod-autoscaler-downscale-stabilization-window引數控制縮容時間視窗,默認 5 分鐘,即負載減小后至少需要等 5 分鐘才會縮容, - 對于擴容,由 hpa controller 固定的演算法、硬編碼的常量因子來控制擴容速度,無法自定義,
這樣的設計邏輯導致用戶無法自定義 HPA 的擴縮容靈敏度,而不同的業務場景對于擴容容靈敏度要求可能是不一樣的,比如:
- 對于有流量突發的關鍵業務,在需要的時候應該快速擴容 (即便可能不需要,以防萬一),但縮容要慢 (防止另一個流量高峰),
- 對于一些需要處理大量資料的離線業務,在需要的時候應該盡快擴容以減少處理時間,不需要那么多資源的時候應該盡快縮容以節約成本,
- 處理常規資料/網路流量的業務,它們可能會以一般的方式擴大和縮小規模,以減少抖動,
HPA 在 K8s 1.18 迎來了一次更新,在之前 v2beta2 版本上新增了擴縮容靈敏度的控制,不過版本號依然保持 v2beta2 不變,
如何使用
這次更新實際就是在 HPA Spec 下新增了一個 behavior 欄位,下面有 scaleUp 和 scaleDown 兩個欄位分別控制擴容和縮容的行為,具體可參考官方 API 檔案: https://v1-18.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#horizontalpodautoscalerbehavior-v2beta2-autoscaling
下面給出一些使用場景的示例,
快速擴容
當你的應用需要快速擴容時,可以使用類似如下的 HPA 配置:
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: web
spec:
minReplicas: 1
maxReplicas: 1000
metrics:
- pods:
metric:
name: k8s_pod_rate_cpu_core_used_limit
target:
averageValue: "80"
type: AverageValue
type: Pods
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web
behavior: # 這里是重點
scaleUp:
policies:
- type: percent
value: 900%
上面的配置表示擴容時立即新增當前 9 倍數量的副本數,即立即擴容到當前 10 倍的 Pod 數量,當然也不能超過 maxReplicas 的限制,
假如一開始只有 1 個 Pod,如果遭遇流量突發,它將以飛快的速度進行擴容,擴容時 Pod 數量變化趨勢如下:
1 -> 10 -> 100 -> 1000
沒有配置縮容策略,將等待全域默認的縮容時間視窗 (--horizontal-pod-autoscaler-downscale-stabilization-window,默認5分鐘) 后開始縮容,
快速擴容,緩慢縮容
如果流量高峰過了,并發量驟降,如果用默認的縮容策略,等幾分鐘后 Pod 數量也會隨之驟降,如果 Pod 縮容后突然又來一個流量高峰,雖然可以快速擴容,但擴容的程序畢竟還是需要一定時間的,如果流量高峰足夠高,在這段時間內還是可能造成后端處理能力跟不上,導致部分請求失敗,這時候我們可以為 HPA 加上縮容策略,HPA behavior 配置示例如下:
behavior:
scaleUp:
policies:
- type: percent
value: 900%
scaleDown:
policies:
- type: pods
value: 1
periodSeconds: 600 # 每 10 分鐘只縮掉 1 個 Pod
上面示例中增加了 scaleDown 的配置,指定縮容時每 10 分鐘才縮掉 1 個 Pod,大大降低了縮容速度,縮容時的 Pod 數量變化趨勢如下:
1000 -> … (10 min later) -> 999
這個可以讓關鍵業務在可能有流量突發的情況下保持處理能力,避免流量高峰導致部分請求失敗,
緩慢擴容
如果想要你的應用不太關鍵,希望擴容時不要太敏感,可以讓它擴容平穩緩慢一點,為 HPA 加入下面的 behavior:
behavior:
scaleUp:
policies:
- type: pods
value: 1 # 每次擴容只新增 1 個 Pod
假如一開始只有 1 個 Pod,擴容時它的 Pod 數量變化趨勢如下:
1 -> 2 -> 3 -> 4
禁止自動縮容
如果應用非常關鍵,希望擴容后不自動縮容,需要人工干預或其它自己開發的 controller 來判斷縮容條件,可以使用型別如下的 behavior 配置來禁止自動縮容:
behavior:
scaleDown:
policies:
- type: pods
value: 0
延長縮容時間視窗
縮容默認時間視窗是 5 min (--horizontal-pod-autoscaler-downscale-stabilization-window),如果我們需要延長時間視窗以避免一些流量毛刺造成的例外,可以指定下縮容的時間視窗,behavior 配置示例如下:
behavior:
scaleDown:
stabilizationWindowSeconds: 600 # 等待 10 分鐘再開始縮容
policies:
- type: pods
value: 5 # 每次只縮掉 5 個 Pod
上面的示例表示當負載降下來時,會等待 600s (10 分鐘) 再縮容,每次只縮容 5 個 Pod,
延長擴容時間視窗
有些應用經常會有資料毛刺導致頻繁擴容,而擴容出來的 Pod 其實沒太大必要,反而浪費資源,比如資料處理管道的場景,擴容指標是佇列中的事件數量, 當佇列中堆積了大量事件時,我們希望可以快速擴容,但又不希望太靈敏,因為可能只是短時間內的事件堆積,即使不擴容也可以很快處理掉,
默認的擴容演算法會在較短的時間內擴容,針對這種場景我們可以給擴容增加一個時間視窗以避免毛刺導致擴容帶來的資源浪費,behavior 配置示例如下:
behavior:
scaleUp:
stabilizationWindowSeconds: 300 # 擴容前等待 5 分鐘的時間視窗
policies:
- type: pods
value: 20 # 每次擴容新增 20 個 Pod
上面的示例表示擴容時,需要先等待 5 分鐘的時間視窗,如果在這段時間內負載降下來了就不再擴容,如果負載持續超過擴容閥值才擴容,每次擴容新增 20 個 Pod,
小結
本文介紹了如何利用 K8s 1.18 的 HPA 新特性來控制擴縮容的靈敏度,以更好的滿足各種不同場景對擴容速度的需求,
參考資料
- HPA 介紹: https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/
【騰訊云原生】云說新品、云研新術、云游新活、云賞資訊,掃碼關注同名公眾號,及時獲取更多干貨!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/246011.html
標籤:其他

