也許,這樣理解K8s的Pod自動化擴縮容機制更容易
本文嘗試以通俗的方式向讀者介紹K8s的Pod的自動化橫向擴縮容的領域模型。其實是以領域驅動設計(DDD)的思考方式來學習一項技術。希望能對讀者幫助。
問題是什麼
當要理解一個解決方案時,我們從問題域開始理解,會更容易。
比如存在一個場景:基於Pod的CPU使用率進行自動化擴容。當一個Pod的CPU使用率大於60%,並持續15秒時,我們就希望Pod的數量從10個擴到13個。
要實現這個場景,我們推斷K8s應該存在一種機制方便我們實現這個場景。這種機制就是HPA(Horizontal Pod Autoscaler)。
換位思考一下,如果你是HPA機制的使用者,你會如何使用HPA呢?
你可能會配置如下:
apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: php-apache spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: php-apache minReplicas: 1 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 60
(如果看不懂,也沒有關係,你只需要知道,你可以通過程式碼來定義HPA的行為)
作為使用者,你只需要通過YAML檔案定義清楚你的期望就可以了。至於如何實現,是由HPA機制的實現者實現的。
就好比司機開車過程中是不需要考慮動力系統是由電機實現的,還是由柴油引擎實現的。這就是“介面是使用者的”的含義了。當然,作為汽車的設計者,你就必須考慮動力系統的設計與實現。
同樣的,作為K8s的設計者,就必須考慮HPA機制的設計與實現。
當用戶通過kubectl apply -f hpa.yaml命令部署HPA到K8s中時,我們的K8s該做什麼呢?它需要考慮以下問題:
-
1. 我該如何拿到使用者Pod的某一個指標的值呢?
-
2. 多久拿一次指標呢?
-
3. 當這個指標不是CPU,記憶體等資源指標,而是應用本身的自定義指標呢?如果指標資料甚至不在K8s內部呢?
-
4. Pod本來已經是由控制器控制的了,我們是該控制控制器去完成工作,還是直接控制Pod去完成?
-
5. 當用戶需要根據多個指標的值共同決定擴容時,我們該如何權衡其中的策略?
-
6. 如果Pod中有多個容器,如何根據其中一個容器的指標進行擴容?
-
7. 以上說的都是擴容,如何縮容呢?
-
8. 縮容太快了,怎麼辦?即如何保證縮容時的穩定性?
筆者對以上相對口語的表述進行抽象。當我們作為K8s的HPA的設計者與實現者時,我們需要考慮以下問題:
-
1. 指標來源問題;
-
2. 指標的數量問題:即不僅只支援針對一個指標的擴縮容;
-
3. 指標型別支援問題:資源指標、自定義指標、外部指標;
-
4. Pod擴縮的控制器實現;
-
5. 自定義Pod擴縮行為:擴容行為應該可以由使用者自定義。
接下來我們分別看下K8s是如何解決以上問題的。
指標來源與指標型別
HPA控制器會從Metrics API中獲取指標。而Metrics API根據不同的指標型別去不同的Metrics API的實現中去獲取指標。

-
• 資源指標:CPU和記憶體的使用率指標,由Metrics Server提供。Metrics Server需要單獨安裝;
-
• 自定義指標:比如應用的連線數大小。最終由你的Custom Metrics API的實現者提供;
-
• 外部自定義指標:與K8s 物件無關的自定義指標。
自定義指標與外部自定義指標的區別是該自定義指標是否來自於與應用同處於同一個K8s叢集。
雖然定義是這樣,這個界線也可以被打破,如下圖:

當HPA拿到指標後,在哪裡,又該如何實現對Pod的數量的控制呢?
既然Pod已經存在Deployment 及其 Replicate Controller了,沒有必要再重新設計一個新的控制器,在現有的控制器之上進行操作即可。
這部分邏輯是HPA的核心邏輯。具體實現在kube-controller-manager。網路上已經有很多原始碼分析。此處不再贅述。

小結
本文雖說的是K8s的HPA的機制的領域模型,但是,你發現這個領域模型也適用於非K8s的部署方式。
總的來說,關於HPA你只需要記住兩個問題:
-
1. 指標從何而來
-
2. 如何根據指標進行擴縮容
然後找到這兩個問題答案。當我們想通這兩個問題後,即使不在K8s中實現HPA,我們也會有思路實現。
- 一老司機在生產環境上翻車,是什麼心理
- 也許,這樣理解K8s的Pod自動化擴縮容機制更容易
- Helm3單元測試教程
- DevOps系統對軟體團隊管理模式的影響
- 個人開發習慣與團隊效率之間的關係
- 集中力量辦大事的軟體交付方式
- SRE問題排查四步法——以建立HTTPS連線失敗問題排查為例
- 團隊線上故障處理模板(SRE必收藏)
- 這十年,我所經歷的領域驅動設計(DDD)
- 使用Rancher部署k8s叢集
- K8s工程化:K8s中的Java應用出現OOM後怎麼辦?
- 為什麼我不允許開發人員修改測試環境的MySQL Schema
- 一步步帶你搭建監控系統
- 手把手教你搭建Kubeflow——基於K8s的機器學習平臺
- kubernetes叢集基於traefik對外提供服務
- 構建工具設定代理的方法集合(DevOps工程師必收藏)
- 可落地的雲原生應用規範
- 阿里巴巴DevOps實踐指南 | 以特性為核心的持續交付
- 我是如何做軟體工程化的
- 比構建速度,Bazel是Gradle的10倍,不服不行!!!