本文翻譯自 learnk8s 的 Architecting Kubernetes clusters — choosing the best autoscaling strategy柬讨,<u>有增刪部分內(nèi)容</u>乍赫。
TL;DR: 在默認設(shè)置下,擴展 Kubernetes 集群中的 pod 和節(jié)點可能需要幾分鐘時間竣付。了解如何調(diào)整集群節(jié)點的大小火架、配置水平和集群自動縮放器以及過度配置集群以加快擴展速度鉴象。
自動擴展器
在 Kubernetes 中,常說的“自用擴展”有:
不同類型的自動縮放器何鸡,使用的場景不一樣纺弊。
HPA
HPA 定期檢查內(nèi)存和 CPU 等指標,自動調(diào)整 Deployment 中的副本數(shù)骡男,比如流量變化:
VPA
有些時候無法通過增加 Pod 數(shù)來擴容淆游,比如數(shù)據(jù)庫。這時候可以通過 VPA 增加 Pod 的大小隔盛,比如調(diào)整 Pod 的 CPU 和內(nèi)存:
CA
當(dāng)集群資源不足時犹菱,CA 會自動配置新的計算資源并添加到集群中:
自動縮放 Pod 出錯時
比如一個應(yīng)用需要 1.5 GB 內(nèi)存和 0.25 個 vCPU。一個 8GB 和 2 個 vCPU 的節(jié)點吮炕,可以容納 4 個這樣的 Pod腊脱,完美!
做如下配置:
- HPA:每增加 10 個并發(fā)龙亲,增加一個副本陕凹。即 40 個并發(fā)的時候,自動擴展到 4 個副本鳄炉。(這里使用自定義指標杜耙,比如來自 Ingress Controller 的 QPS)
- CA:在資源不足的時候,增加計算節(jié)點迎膜。
當(dāng)并發(fā)達到 30 的時候泥技,系統(tǒng)是下面這樣浆兰。完美磕仅!HPA 工作正常珊豹,CA 沒工作。
當(dāng)增加到 40 個并發(fā)的時候榕订,系統(tǒng)是下面的情況:
- HPA 增加了一個 Pod
- Pod 掛起
- CA 增加了一個節(jié)點
為什么 Pod 沒有部署成功店茶?
節(jié)點上的操作系統(tǒng)進程和 kubelet 也會消耗一部分資源,8G 和 2 vCPU 并不是全都可以提供給 Pod 用的劫恒。并且還有一個驅(qū)逐閾值:在節(jié)點系統(tǒng)剩余資源達到閾值時贩幻,會驅(qū)逐 Pod,避免 OOM 的發(fā)生两嘴。
當(dāng)然上面的這些都是可配置的丛楚。
那為什么在創(chuàng)建該 Pod 之前,CA 沒有增加新的節(jié)點呢憔辫?
CA 如何工作趣些?
CA 在觸發(fā)自動縮放時,不會查看可用的內(nèi)存或 CPU贰您。
CA 是面向事件工作的坏平,并每 10 秒檢查一次是否存在不可調(diào)度(Pending)的 Pod。
當(dāng)調(diào)度器無法找到可以容納 Pod 的節(jié)點時锦亦,這個 Pod 是不可調(diào)度的舶替。
此時,CA 開始創(chuàng)建新節(jié)點:CA 掃描集群并檢查是否有不可調(diào)度的 Pod杠园。
當(dāng)集群有多種節(jié)點池顾瞪,CA 會通過選擇下面的一種策略:
-
random
:默認的擴展器,隨機選擇一種節(jié)點池 -
most-pods
:能夠調(diào)度最多 Pod 的節(jié)點池 -
least-waste
:選擇擴展后抛蚁,資源空閑最少的節(jié)點池 -
price
:選擇成本最低的節(jié)點池 -
priority
:選擇用戶分配的具有最高優(yōu)先級的節(jié)點池
確定類型后玲昧,CA 會調(diào)用相關(guān) API 來創(chuàng)建資源。(云廠商會實現(xiàn) API篮绿,比如 AWS 添加 EC2孵延;Azure 添加 Virtual Machine;阿里云增加 ECS亲配;GCP 增加 Compute Engine)
計算資源就緒后尘应,就會進行節(jié)點的初始化。
注意吼虎,這里需要一定的耗時犬钢,通常比較慢。
探索 Pod 自動縮放的前置時間
四個因素:
- HPA 的響應(yīng)耗時
- CA 的響應(yīng)耗時
- 節(jié)點的初始化耗時
- Pod 的創(chuàng)建時間
默認情況下思灰,kubelet 每 10 秒抓取一次 Pod 的 CPU 和內(nèi)存占用情況玷犹。
每分鐘,Metrics Server 會將聚合的指標開放給 Kubernetes API 的其他組件使用洒疚。
- 少于 100 個節(jié)點坯屿,且每個節(jié)點最多 30 個 Pod,時間不超過 30s巍扛。平均延遲大約 5s领跛。
- 100 到 1000個節(jié)點,不超過 60s撤奸。平均延遲大約 15s吠昭。
節(jié)點的配置時間,取決于云服務(wù)商胧瓜。通常在 3~5 分鐘矢棚。
容器運行時創(chuàng)建 Pod:啟動容器的幾毫秒和下載鏡像的幾秒鐘。如果不做鏡像緩存府喳,幾秒到 1 分鐘不等幻妓,取決于層的大小和梳理。
對于小規(guī)模的集群劫拢,最壞的情況是 6 分 30 秒肉津。對于 100 個以上節(jié)點規(guī)模的集群,可能高達 7 分鐘舱沧。
HPA delay: 1m30s +
CA delay: 0m30s +
Cloud provider: 4m +
Container runtime: 0m30s +
=========================
Total 6m30s
突發(fā)情況妹沙,比如流量激增,你是否愿意等這 7 分鐘熟吏?
這 7 分鐘距糖,如何優(yōu)化壓縮?
- HPA 的刷新時間牵寺,默認 15 秒悍引,通過
--horizontal-pod-autoscaler-sync-period
標志控制。 - Metrics Server 的指標抓取時間帽氓,默認 60 秒趣斤,通過
metric-resolution
控制。 - CA 的掃描間隔黎休,默認 10 秒浓领,通過
scan-interval
控制。 - 節(jié)點上緩存鏡像势腮,比如 kube-fledged 等工具联贩。
即使調(diào)小了上述設(shè)置,依然會受云服務(wù)商的時間限制捎拯。
那么泪幌,如何解決?
兩種嘗試:
- 盡量避免被動創(chuàng)建新節(jié)點
- 主動創(chuàng)建新節(jié)點
為 Kubernetes 選擇最佳規(guī)格的節(jié)點
這會對擴展策略產(chǎn)生巨大影響。
這樣的場景
應(yīng)用程序需要 1GB 內(nèi)存和 0.1 vCPU祸泪;有一個 4GB 內(nèi)存和 1 個 vCPU 的節(jié)點吗浩。
排除操作系統(tǒng)、kubelet 和閾值保留空間后浴滴,有 2.5GB 內(nèi)存和 0.7 個 vCPU 可用拓萌。
最多只能容納 2 個 Pod岁钓,擴展副本時最長耗時 7 分鐘(HPA升略、CA、云服務(wù)商的資源配置耗時)
假如節(jié)點的規(guī)格是 64GB 內(nèi)存和 16 個 vCPU屡限,可用的資源為 58.32GB 和 15.8 個 vCPU品嚣。
這個節(jié)點可以托管 58 個 Pod。只有擴容第 59 個副本時钧大,才需要創(chuàng)建新的節(jié)點。
這樣觸發(fā) CA 的機會更少。
選擇大規(guī)格的節(jié)點边涕,還有另外一個好處:資源的利用率會更高但金。
節(jié)點上可以容納的 Pod 數(shù)量,決定了效率的峰值瓜饥。
物極必反逝撬!更大的實例,并不是一個好的選擇:
- 爆炸半徑(Blast radius):節(jié)點故障時乓土,少節(jié)點的集群和多節(jié)點的集群宪潮,前者影響更大。
- 自動縮放的成本效益低:增加一個大容量的節(jié)點趣苏,其利用率會比較低(調(diào)度過去的 Pod 數(shù)少)
即使選擇了正確規(guī)格的節(jié)點狡相,配置新的計算單元時,延遲仍然存在食磕。怎么解決尽棕?
能否提前創(chuàng)建節(jié)點?
為集群過度配置節(jié)點
即為集群增加備用節(jié)點彬伦,可以:
- 創(chuàng)建一個節(jié)點萄金,并留空 (比如 SchedulingDisabled)
- 一旦空節(jié)點中有了一個 Pod,馬上創(chuàng)建新的空節(jié)點
這種會產(chǎn)生額外的成本媚朦,但是效率會提升氧敢。
CA 并不支持此功能 -- 總是保留一個空節(jié)點。
但是询张,可以偽造孙乖。創(chuàng)建一個只占用資源,不使用資源的 Pod 占用整個 Node 節(jié)點。
一旦有了真正的 Pod唯袄,驅(qū)逐占位的 Pod弯屈。
待后臺完成新的節(jié)點配置后,將“占位” Pod 再次占用整個節(jié)點恋拷。
這個“占位”的 Pod 可以通過永久休眠來實現(xiàn)空間的保留资厉。
apiVersion: apps/v1
kind: Deployment
metadata:
name: overprovisioning
spec:
replicas: 1
selector:
matchLabels:
run: overprovisioning
template:
metadata:
labels:
run: overprovisioning
spec:
containers:
- name: pause
image: k8s.gcr.io/pause
resources:
requests:
cpu: '1739m'
memory: '5.9G'
使用優(yōu)先級和搶占,來實現(xiàn)創(chuàng)建真正的 Pod 后驅(qū)逐“占位”的 Pod蔬顾。
使用 PodPriorityClass
在配置 Pod 優(yōu)先級:
apiVersion: scheduling.k8s.io/v1beta1
kind: PriorityClass
metadata:
name: overprovisioning
value: -1 #默認的是 0宴偿,這個表示比默認的低
globalDefault: false
description: 'Priority class used by overprovisioning.'
為“占位” Pod 配置優(yōu)先級:
apiVersion: apps/v1
kind: Deployment
metadata:
name: overprovisioning
spec:
replicas: 1
selector:
matchLabels:
run: overprovisioning
template:
metadata:
labels:
run: overprovisioning
spec:
priorityClassName: overprovisioning #HERE
containers:
- name: reserve-resources
image: k8s.gcr.io/pause
resources:
requests:
cpu: '1739m'
memory: '5.9G'
已經(jīng)做完過度配置,應(yīng)用程序是否需要優(yōu)化诀豁?
為 Pod 選擇正確的內(nèi)存和 CPU 請求
Kubernetes 是根據(jù) Pod 的內(nèi)存和 CPU 請求窄刘,為其分配節(jié)點。
如果 Pod 的資源請求配置不正確舷胜,可能會過晚(或過早)觸發(fā)自動縮放器娩践。
這樣一個場景:
- 應(yīng)用程序平均負載下消耗 512MB 內(nèi)存和 0.25 個 vCPU。
- 高峰時烹骨,消耗 4GB 內(nèi)存 和 1 個 vCPU翻伺。(即資源限制,Limit)
有三種請求的配置選擇:
- 遠低于平均使用量
- 匹配平均使用量
- 盡量接近限制
第一種的問題在于超賣嚴重沮焕,過度使用節(jié)點吨岭。kubelet 負載高,穩(wěn)定性差遇汞。
第三種未妹,會造成資源的利用率低,浪費資源空入。這種通常被稱為 QoS:Quality of Service class 中的 Guaranteed
級別络它,Pod 不會被終止和驅(qū)逐。
如何在穩(wěn)定性和資源使用率間做權(quán)衡歪赢?
這就是 QoS:Quality of Service class 中的 Burstable
級別化戳,即 Pod 偶爾會使用更多的內(nèi)存和 CPU。
- 如果節(jié)點中有可用資源埋凯,應(yīng)用程序會在返回基線(baseline)前使用這些資源点楼。
- 如果資源不足,Pod 將競爭資源(CPU)白对,kubelet 也有可能嘗試驅(qū)逐 Pod(內(nèi)存)掠廓。
在 Guaranteed
和 Burstable
之前如何做選擇?取決于:
- 想盡量減少 Pod 的重新調(diào)度和驅(qū)逐甩恼,應(yīng)該是用
Guaranteed
蟀瞧。 - 如果想充分利用資源時沉颂,使用
Burstable
。比如彈性較大的服務(wù)悦污,Web 或者 REST 服務(wù)铸屉。
如何做出正確的配置?
應(yīng)該分析應(yīng)用程序切端,并測算空閑彻坛、負載和峰值時的內(nèi)存和 CPU 消耗。
甚至可以通過部署 VPA 來自動調(diào)整踏枣。
如何進行集群縮容昌屉?
每 10 秒,當(dāng)請求(request)利用率低于 50%時椰于,CA 才會決定刪除節(jié)點怠益。
CA 會匯總同一個節(jié)點上的所有 Pod 的 CPU 和內(nèi)存請求仪搔。小于節(jié)點容量的一半瘾婿,就會考慮對當(dāng)前節(jié)點進行縮減。
需要注意的是烤咧,CA 不考慮實際的 CPU 和內(nèi)存使用或者限制(limit)偏陪,只看請求(request)。
移除節(jié)點之前煮嫌,CA 會:
檢查都通過之后懦冰,才會刪除節(jié)點灶轰。
為什么不根據(jù)內(nèi)存或 CPU 進行自動縮放?
基于內(nèi)存和 CPU 的自動縮放器刷钢,不關(guān)心 pod笋颤。
比如配置縮放器在節(jié)點的 CPU 達到總量的 80%,就自動增加節(jié)點内地。
當(dāng)你創(chuàng)建 3 個副本的 Deployment伴澄,3 個節(jié)點的 CPU 達到了 85%。這時會創(chuàng)建一個節(jié)點阱缓,但你并不需要第 4 個副本非凌,新的節(jié)點就空閑了。
不建議使用這種類型的自動縮放器荆针。
總結(jié)
定義和實施成功的擴展策略敞嗡,需要掌握以下幾點:
- 節(jié)點的可分配資源并蝗。
- 微調(diào) Metrics Server、HPA 和 CA 的刷新間隔秸妥。
- 設(shè)計集群和節(jié)點的規(guī)格滚停。
- 緩存容器鏡像到節(jié)點。
- 應(yīng)用程序的基準測試和分析粥惧。
配合適當(dāng)?shù)谋O(jiān)控工具键畴,可以反復(fù)測試擴展策略并調(diào)整集群的縮放速度和成本。