大規(guī)模集群使用建議
ACK集群的性能和可用性與集群資源數(shù)量、資源訪問(wèn)頻率、訪問(wèn)模式等緊密相關(guān)。不同變量組合下,API Server承載的壓力和性能差異不同。在大規(guī)模的ACK集群Pro版(通常為超過(guò)500個(gè)節(jié)點(diǎn)或者10,000個(gè)Pod的集群)中,集群管理者需要根據(jù)業(yè)務(wù)實(shí)際狀況合理規(guī)劃和使用規(guī)模化集群,密切關(guān)注監(jiān)控指標(biāo),確保集群的穩(wěn)定性和可用性。
大規(guī)模集群使用須知
相較于使用多個(gè)集群,構(gòu)建一個(gè)大規(guī)模集群可以有效減少集群管理運(yùn)維負(fù)擔(dān),提高資源利用率。但在某些復(fù)雜的業(yè)務(wù)場(chǎng)景中,建議您根據(jù)業(yè)務(wù)邏輯或需求將服務(wù)拆分到多個(gè)集群中,例如非生產(chǎn)(測(cè)試)服務(wù)與生產(chǎn)(開(kāi)發(fā))服務(wù)拆分、數(shù)據(jù)庫(kù)服務(wù)與前端應(yīng)用拆分等。
如您有以下維度的考量,我們更建議您使用多個(gè)集群,而非單一的大規(guī)模集群。
分類(lèi) | 說(shuō)明 |
隔離性 | 使用多個(gè)集群可以確保不同集群(例如生產(chǎn)集群和測(cè)試集群)的隔離性,避免某個(gè)集群的問(wèn)題影響全部業(yè)務(wù),降低故障爆炸半徑。 |
位置 | 某些服務(wù)需要部署在離終端用戶更近的特定地理位置,以滿足可用性、低延時(shí)的需求。在此場(chǎng)景下,推薦您在多個(gè)地區(qū)部署多個(gè)集群。 |
單集群規(guī)模上限 | ACK托管控制面通過(guò)彈性伸縮和集群組件的性能優(yōu)化來(lái)自適應(yīng)集群規(guī)模。但Kubernetes架構(gòu)存在性能瓶頸,超大的集群規(guī)模可能會(huì)影響集群的可用性和性能。在使用大規(guī)模集群前,您應(yīng)該了解Kubernetes社區(qū)定義的容量限制與SLO,并前往配額平臺(tái)查看并申請(qǐng)?zhí)岣?span id="3380d3b80e1yx" outputclass="productName" data-tag="ph" data-ref-searchable="yes" data-reuse-tag="productName" data-type="productName" data-product-code="csk" docid="4265392" class="ph productName">容器服務(wù) Kubernetes 版的配額上限。如果超出社區(qū)和ACK的限制,請(qǐng)拆分業(yè)務(wù),使用多個(gè)集群。 |
如您需要多集群管理,例如應(yīng)用部署、流量管理、作業(yè)分發(fā)、全局監(jiān)控等,建議您啟用多集群艦隊(duì)。
本文使用指引
本文主要面向ACK集群Pro版的集群開(kāi)發(fā)和管理人員,提供規(guī)劃和使用大規(guī)模集群的通用性建議,實(shí)際情況仍以您的集群環(huán)境和業(yè)務(wù)需求為準(zhǔn)。
根據(jù)安全責(zé)任共擔(dān)模型,ACK集群負(fù)責(zé)集群管控面組件(包括Kubernetes控制面組件和etcd)以及集群服務(wù)相關(guān)阿里云基礎(chǔ)設(shè)施的默認(rèn)安全性;您需要負(fù)責(zé)部署在云上的業(yè)務(wù)應(yīng)用安全防護(hù)以及對(duì)云上資源的安全配置和更新。更多信息,請(qǐng)參見(jiàn)安全責(zé)任共擔(dān)模型。
使用新版本集群
隨著Kubernetes版本不斷升級(jí),容器服務(wù)ACK會(huì)定期發(fā)布支持的Kubernetes版本,并逐步停止對(duì)過(guò)期版本的技術(shù)支持。對(duì)于過(guò)期版本,ACK將逐步停止發(fā)布新功能特性,停止修復(fù)功能缺陷、安全缺陷,且僅提供有限的技術(shù)支持。
請(qǐng)您通過(guò)幫助文檔、控制臺(tái)信息、站內(nèi)信等渠道關(guān)注版本發(fā)布情況,并在集群升級(jí)前了解相應(yīng)版本的升級(jí)注意事項(xiàng),及時(shí)完成版本升級(jí),避免潛在的集群安全和穩(wěn)定性問(wèn)題。關(guān)于集群升級(jí)的更多信息,請(qǐng)參見(jiàn)手動(dòng)升級(jí)集群、自動(dòng)升級(jí)集群;關(guān)于Kubernetes版本支持信息,請(qǐng)參見(jiàn)Kubernetes版本概覽及機(jī)制。
關(guān)注集群資源限制
為保證大規(guī)模集群的可用性、穩(wěn)定性和各項(xiàng)性能,請(qǐng)關(guān)注下表列出的限制及對(duì)應(yīng)的推薦解決方案。
限制項(xiàng) | 說(shuō)明 | 推薦解決方案 |
etcd數(shù)據(jù)庫(kù)大小(DB Size) | etcd數(shù)據(jù)庫(kù)大小上限為8 GB。當(dāng)etcd數(shù)據(jù)庫(kù)過(guò)大時(shí),會(huì)影響其性能,包括數(shù)據(jù)讀取和寫(xiě)入延遲、系統(tǒng)資源占用、選舉延時(shí)等,也會(huì)導(dǎo)致服務(wù)和數(shù)據(jù)恢復(fù)過(guò)程更加困難和耗時(shí)。 | 控制etcd DB Size的總大小在8 GB以下。
|
etcd中每種類(lèi)型資源的數(shù)據(jù)總大小 | 如果資源對(duì)象總量過(guò)大,客戶端全量訪問(wèn)該資源時(shí)會(huì)導(dǎo)致大量的系統(tǒng)資源消耗,嚴(yán)重時(shí)可能會(huì)導(dǎo)致API Server或自定義控制器(Controller)無(wú)法初始化。 | 控制每種資源類(lèi)型的對(duì)象總大小在800 MB以下。
|
API Server CLB的連接數(shù)和帶寬 | 目前,ACK集群API Server使用的負(fù)載均衡類(lèi)型為CLB,其連接數(shù)與帶寬有最大容量限制。CLB最大連接數(shù)可參見(jiàn)CLB實(shí)例概述,最大帶寬為5120Mbps。 超出CLB連接數(shù)或者帶寬限制可能會(huì)造成節(jié)點(diǎn)Not Ready。 | 對(duì)于1,000節(jié)點(diǎn)以上的集群,建議選擇按使用量計(jì)費(fèi)的CLB實(shí)例。 說(shuō)明 為提升網(wǎng)絡(luò)連接速度和帶寬,大規(guī)模集群訪問(wèn)Default命名空間中的Kubernetes服務(wù)時(shí),應(yīng)使用ENI直連模式。在2023年02月以后新建的,v1.20以上的集群中,新建集群已默認(rèn)使用ENI直連;存量集群的切換請(qǐng)提交工單。更多信息,請(qǐng)參見(jiàn)Kube API Server。 |
每個(gè)命名空間的Service數(shù)量 | kubelet會(huì)把集群中定義的Service的相關(guān)信息以環(huán)境變量的形式注入到運(yùn)行在該節(jié)點(diǎn)上的Pod中,讓Pod能夠通過(guò)環(huán)境變量來(lái)發(fā)現(xiàn)Service,并與之通信。 每個(gè)命名空間中的服務(wù)數(shù)量過(guò)多會(huì)導(dǎo)致為Pod注入的環(huán)境變量過(guò)多,繼而可能導(dǎo)致Pod啟動(dòng)緩慢甚至失敗 | 將每個(gè)命名空間的Service數(shù)量控制在5,000以下。 您可以選擇不填充這些環(huán)境變量,將 |
集群的總Service數(shù)量 | Service數(shù)量過(guò)多會(huì)導(dǎo)致kube-proxy需要處理的網(wǎng)絡(luò)規(guī)則增多,繼而影響kube-proxy的性能。 對(duì)于LoadBalancer類(lèi)型的Service,Service數(shù)量過(guò)多會(huì)導(dǎo)致Service同步到SLB的時(shí)延增加,延遲可能達(dá)到分鐘級(jí)別。 | 將所有Service的總數(shù)量控制在10,000以下。 對(duì)LoadBalancer類(lèi)型的Service,建議將Service總數(shù)控制在500以下。 |
單個(gè)Service的Endpoint最大數(shù)量 | 每個(gè)節(jié)點(diǎn)上運(yùn)行著kube-proxy組件,用于監(jiān)視(Watch)Service的相關(guān)更新,以便及時(shí)更新節(jié)點(diǎn)上的網(wǎng)絡(luò)規(guī)則。當(dāng)某個(gè)Service存在很多Endpoint時(shí),Service相應(yīng)的Endpoints資源也會(huì)很大,每次對(duì)Endpoints對(duì)象的更新都會(huì)導(dǎo)致控制面kube-apiserver和節(jié)點(diǎn)kube-proxy之間傳遞大量流量。集群規(guī)模越大,需要更新的相關(guān)數(shù)據(jù)越多,風(fēng)暴效應(yīng)越明顯。 說(shuō)明 為了解決此問(wèn)題,kube-proxy在v1.19以上的集群中默認(rèn)使用EndpointSlices來(lái)提高性能。 | 將單個(gè)Service的Endpoints的后端Pod數(shù)量控制在3,000以下。
|
所有Service Endpoint的總數(shù)量 | 集群中Endpoint數(shù)量過(guò)多可能會(huì)造成API Server負(fù)載壓力過(guò)大,并導(dǎo)致網(wǎng)絡(luò)性能降低。 | 將所有Service關(guān)聯(lián)的Endpoint的總數(shù)量控制在64,000以下。 |
Pending Pod的數(shù)量 | Pending Pod數(shù)量過(guò)多時(shí),新提交的Pod可能會(huì)長(zhǎng)時(shí)間處于等待狀態(tài),無(wú)法被調(diào)度到合適的節(jié)點(diǎn)上。在此過(guò)程中,如果Pod無(wú)法被調(diào)度,調(diào)度器會(huì)周期性地產(chǎn)生事件(event),繼而可能導(dǎo)致事件泛濫(event storm)。 | 將Pending Pod的總數(shù)量控制在10,000以下。 |
啟用了使用阿里云KMS進(jìn)行Secret的落盤(pán)加密的集群中的Secret數(shù)量 | 使用KMS v1加密數(shù)據(jù)時(shí),每次加密都會(huì)生成一個(gè)新的數(shù)據(jù)加密密鑰(DEK)。Kubernetes集群?jiǎn)?dòng)時(shí),需要訪問(wèn)并解密存儲(chǔ)在etcd中的Secret。如果集群存儲(chǔ)的Secret過(guò)多,集群在啟動(dòng)或升級(jí)時(shí)需要解密大量的數(shù)據(jù),影響集群性能。 | 將開(kāi)啟KMS V1加密的集群中存儲(chǔ)的Secret數(shù)量控制在2,000以下。 |
合理設(shè)置管控組件參數(shù)
ACK集群Pro版提供自定義Pro版集群的控制面組件參數(shù)功能,支持修改kube-apiserver、kube-controller-manager、kube-scheduler等核心托管組件的參數(shù)。在大規(guī)模集群中,您需要合理調(diào)整管控組件限流的相關(guān)參數(shù)。
kube-apiserver
為了避免大量并發(fā)請(qǐng)求導(dǎo)致控制面超載,kube-apiserver限制了它在特定時(shí)間內(nèi)可以處理的并發(fā)請(qǐng)求數(shù)。一旦超出此限制,API Server將開(kāi)始限流請(qǐng)求,向客戶端返回429 HTTP響應(yīng)碼,即請(qǐng)求過(guò)多,并讓客戶端稍后再試。如果服務(wù)端沒(méi)有任何限流措施,可能導(dǎo)致控制面因處理超出其承載能力的請(qǐng)求而過(guò)載,嚴(yán)重影響整個(gè)服務(wù)或集群的穩(wěn)定性以及可用性。因此,推薦您在服務(wù)端配置限流機(jī)制,避免因控制面崩潰而帶來(lái)更廣泛的問(wèn)題。
限流分類(lèi)
kube-apiserver的限流分為兩種。
v1.18以下:kube-apiserver僅支持最大并發(fā)度限流,將請(qǐng)求區(qū)分為讀類(lèi)型和寫(xiě)類(lèi)型,通過(guò)啟動(dòng)參數(shù)
--max-requests-inflight
和--max-mutating-requests-inflight
限制讀寫(xiě)請(qǐng)求的最大并發(fā)度。該方式不區(qū)分請(qǐng)求優(yōu)先級(jí)。某些低優(yōu)先級(jí)的慢請(qǐng)求可能占用大量資源,造成API Server請(qǐng)求堆積,導(dǎo)致一些更高優(yōu)先級(jí)或更緊急的請(qǐng)求無(wú)法及時(shí)處理。ACK集群Pro版支持自定義kube-apiserver的max-requests-inflight和max-mutating-requests-inflight的參數(shù)配置。更多信息,請(qǐng)參見(jiàn)自定義Pro版集群的控制面組件參數(shù)。
v1.18及以上:引入APF(API優(yōu)先級(jí)和公平性)機(jī)制來(lái)進(jìn)行更細(xì)粒度的流量管理,支持根據(jù)預(yù)設(shè)的規(guī)則和優(yōu)先級(jí)來(lái)分類(lèi)和隔離請(qǐng)求,從而確保更重要和緊急的請(qǐng)求優(yōu)先處理,同時(shí)遵循一定的公平性策略,保證不同類(lèi)型的請(qǐng)求都能夠得到合理的處理機(jī)會(huì)。該特性于v1.20進(jìn)入Beta階段,默認(rèn)開(kāi)啟。
在v1.20及以上的Kubernetes集群中,kube-apiserver通過(guò)
--max-requests-inflight
和--max-mutating-requests-inflight
兩個(gè)參數(shù)的總和來(lái)配置可以并發(fā)處理的請(qǐng)求總數(shù);通過(guò)FlowSchema和PriorityLevelConfiguration兩種自定義資源對(duì)象(CRD)來(lái)控制總請(qǐng)求數(shù)在不同類(lèi)型請(qǐng)求之間分配的并發(fā)數(shù),更精細(xì)地控制請(qǐng)求的流量。PriorityLevelConfiguration:優(yōu)先級(jí)配置,決定某個(gè)優(yōu)先級(jí)可以分配到全部并發(fā)度的比例。
FlowSchema:決定某個(gè)請(qǐng)求屬于哪個(gè)PriorityLevelConfiguration。
PriorityLevelConfiguration和FlowSchema由kube-apiserver自動(dòng)維護(hù),Kubernetes集群中會(huì)自動(dòng)生成當(dāng)前集群版本的默認(rèn)配置。您可以執(zhí)行以下命令來(lái)查看。
kubectl get PriorityLevelConfiguration # 預(yù)期輸出 NAME TYPE ASSUREDCONCURRENCYSHARES QUEUES HANDSIZE QUEUELENGTHLIMIT AGE catch-all Limited 5 <none> <none> <none> 4m20s exempt Exempt <none> <none> <none> <none> 4m20s global-default Limited 20 128 6 50 4m20s leader-election Limited 10 16 4 50 4m20s node-high Limited 40 64 6 50 4m20s system Limited 30 64 6 50 4m20s workload-high Limited 40 128 6 50 4m20s workload-low Limited 100 128 6 50 4m20s
說(shuō)明ACK在FlowSchema中添加了ACK核心組件相關(guān)的分類(lèi)ack-system-leader-election和ack-default。其余與社區(qū)保持一致。
kubectl get flowschemas # 預(yù)期輸出 NAME PRIORITYLEVEL MATCHINGPRECEDENCE DISTINGUISHERMETHOD AGE MISSINGPL exempt exempt 1 <none> 4d18h False probes exempt 2 <none> 4d18h False system-leader-election leader-election 100 ByUser 4d18h False endpoint-controller workload-high 150 ByUser 4d18h False workload-leader-election leader-election 200 ByUser 4d18h False system-node-high node-high 400 ByUser 4d18h False system-nodes system 500 ByUser 4d18h False ack-system-leader-election leader-election 700 ByNamespace 4d18h False ack-default workload-high 800 ByNamespace 4d18h False kube-controller-manager workload-high 800 ByNamespace 4d18h False kube-scheduler workload-high 800 ByNamespace 4d18h False kube-system-service-accounts workload-high 900 ByNamespace 4d18h False service-accounts workload-low 9000 ByUser 4d18h False global-default global-default 9900 ByUser 4d18h False catch-all catch-all 10000 ByUser 4d18h False
限流監(jiān)測(cè)與推薦解決方案
客戶端可以通過(guò)返回狀態(tài)碼429或通過(guò)監(jiān)控指標(biāo)apiserver_flowcontrol_rejected_requests_total
來(lái)判斷服務(wù)端是否有限流行為。當(dāng)觀測(cè)到有限流行為時(shí),可以通過(guò)以下方式解決。
監(jiān)控API Server資源用量:當(dāng)資源用量較低時(shí),可調(diào)整
max-requests-inflight
和max-mutating-requests-inflight
參數(shù)總和提高總的限流值。對(duì)于500個(gè)節(jié)點(diǎn)以上的集群,建議參數(shù)總和配置為2000~3000之間;對(duì)于3000個(gè)節(jié)點(diǎn)以上的集群,建議參數(shù)總和配置在3000~5000之間。
重新配置PriorityLevelConfiguration:
高優(yōu)先級(jí)請(qǐng)求:為不期望限流的請(qǐng)求劃分新的FlowSchema,匹配高優(yōu)先級(jí)的PriorityLevelConfiguration,例如
workload-high
或exempt
。但exempt
的請(qǐng)求不會(huì)被APF限流,請(qǐng)謹(jǐn)慎配置。您也可以為高優(yōu)先級(jí)的請(qǐng)求配置新的PriorityLevelConfiguration,給予更高的并發(fā)度。低優(yōu)先級(jí)請(qǐng)求:當(dāng)?shù)拇_存在某些客戶端慢請(qǐng)求導(dǎo)致API Server資源用量高或響應(yīng)慢時(shí),可以為該類(lèi)請(qǐng)求新增一個(gè)FlowSchema,并為該FlowSchema匹配低并發(fā)度的PriorityLevelConfiguration。
ACK集群Pro版會(huì)為您托管kube-apiserver組件。kube-apiserver默認(rèn)為多AZ高可用,會(huì)保證至少2個(gè)副本,并隨著控制面資源使用率增大而逐漸調(diào)整至最大6個(gè)副本。
可并發(fā)的總實(shí)際請(qǐng)求值 = 副本數(shù)單個(gè)副本總請(qǐng)求量
。修改kube-apiserver的自定義參數(shù)會(huì)觸發(fā)API Server的滾動(dòng)更新,可能導(dǎo)致客戶端Controller重新進(jìn)行List-Watch操作。在大規(guī)模集群下,這可能會(huì)造成API Server負(fù)載過(guò)高,導(dǎo)致其服務(wù)暫時(shí)不可用。
kube-controller-manager和kube-scheduler
kube-controller-manager和kube-scheduler分別通過(guò)kubeAPIQPS/kubeAPIBurst、connectionQPS/connectionBurst參數(shù)控制與API Server通信的QPS。更多信息,請(qǐng)參見(jiàn)自定義Pro版集群的控制面組件參數(shù)、自定義調(diào)度器參數(shù)。
kube-controller-manager:對(duì)于1000個(gè)節(jié)點(diǎn)以上的集群,建議將kubeAPIQPS/kubeAPIBurst調(diào)整為300/500以上。
kube-scheduler:一般無(wú)需調(diào)整。Pod速率超過(guò)300/s時(shí)建議將connectionQPS/connectionBurst調(diào)整為800/1000。
kubelet
kubelet組件的kube-api-burst/qps
默認(rèn)值為5/10,一般無(wú)需調(diào)整。當(dāng)您的集群出現(xiàn)Pod狀態(tài)更新緩慢、調(diào)度延遲、存儲(chǔ)卷掛載緩慢等顯著性能問(wèn)題時(shí),建議您調(diào)大參數(shù)。操作步驟及說(shuō)明,請(qǐng)參見(jiàn)自定義節(jié)點(diǎn)池kubelet配置。
調(diào)大kubelet該參數(shù)會(huì)增大kubelet與API Server的通信QPS。如果kubelet發(fā)送的請(qǐng)求數(shù)量過(guò)多,可能會(huì)增大API Server的負(fù)載。建議您逐步增加取值,并關(guān)注API Server的性能和資源用量,確保控制面穩(wěn)定性。
對(duì)節(jié)點(diǎn)kubelet執(zhí)行變更操作時(shí),需合理控制更新頻率。為保證變更過(guò)程中控制面的穩(wěn)定性,ACK限制單節(jié)點(diǎn)池每批次的最大并行數(shù)不超過(guò)10。
規(guī)劃集群資源彈性速率
在大規(guī)模集群中,當(dāng)集群處于穩(wěn)定運(yùn)行狀態(tài)時(shí),通常不會(huì)給控制面帶來(lái)太大的壓力。但當(dāng)集群進(jìn)行大規(guī)模變更操作時(shí),例如快速創(chuàng)建或刪除大量資源,或者大規(guī)模擴(kuò)縮集群節(jié)點(diǎn)數(shù)時(shí),可能會(huì)造成控制面壓力過(guò)大,導(dǎo)致集群性能下降、響應(yīng)延遲,甚至服務(wù)中斷。
例如,在一個(gè)5,000個(gè)節(jié)點(diǎn)的集群中,如果存在大量固定數(shù)量的Pod且保持穩(wěn)定運(yùn)行狀態(tài),那么它對(duì)控制面的壓力通常不會(huì)太大。但在一個(gè)1,000個(gè)節(jié)點(diǎn)的集群中,如果需要在一分鐘內(nèi)創(chuàng)建10,000個(gè)短暫運(yùn)行的Job,或并發(fā)擴(kuò)容2,000個(gè)節(jié)點(diǎn),那么控制面的壓力會(huì)激增。
因此,在大規(guī)模集群中進(jìn)行資源變更操作時(shí),需根據(jù)集群運(yùn)行狀態(tài)謹(jǐn)慎規(guī)劃彈性操作的變更速率,以確保集群和控制面的穩(wěn)定性。
推薦操作如下。
由于集群控制面影響因素較多,以下數(shù)字僅供參考。實(shí)際操作時(shí),請(qǐng)遵循變更速率由小到大的操作順序,觀察控制面響應(yīng)正常后再適當(dāng)提高彈性速率。
節(jié)點(diǎn)擴(kuò)縮容:對(duì)于2000個(gè)節(jié)點(diǎn)以上的集群,建議在通過(guò)節(jié)點(diǎn)池手動(dòng)擴(kuò)縮容節(jié)點(diǎn)時(shí),單個(gè)節(jié)點(diǎn)池單次操作的節(jié)點(diǎn)數(shù)不超過(guò)100,多個(gè)節(jié)點(diǎn)池單次操作的總節(jié)點(diǎn)數(shù)不超過(guò)300。
應(yīng)用Pod擴(kuò)縮容:若您的應(yīng)用關(guān)聯(lián)了Service,擴(kuò)縮容過(guò)程中Endpoint、EndpointSlice的更新會(huì)推送到所有節(jié)點(diǎn)。在節(jié)點(diǎn)數(shù)量多的場(chǎng)景下,需要更新的相關(guān)數(shù)據(jù)也很多,可能導(dǎo)致集群風(fēng)暴效應(yīng)。對(duì)5000節(jié)點(diǎn)以上的集群,建議非Endpoint關(guān)聯(lián)的Pod更新QPS不超過(guò)300/s;Endpoints關(guān)聯(lián)的Pod更新QPS不超過(guò)10/s。例如,在Deployment中聲明Pod滾動(dòng)更新(Rolling Update)策略時(shí),推薦您先設(shè)置較小的
maxUnavailable
和maxSurge
取值,以降低Pod更新速率。
優(yōu)化客戶端訪問(wèn)集群模式
在Kubernetes集群中,客戶端(客戶業(yè)務(wù)應(yīng)用程序或kubectl等)通過(guò)API Server來(lái)獲取集群資源信息。隨著集群中的資源數(shù)量的增加,如果客戶端以相同的頻率進(jìn)行請(qǐng)求,這些請(qǐng)求可能會(huì)給集群控制面帶來(lái)更大的負(fù)載,導(dǎo)致控制面響應(yīng)延遲,甚至導(dǎo)致管控面雪崩。在訪問(wèn)集群資源時(shí),需了解并規(guī)劃訪問(wèn)資源的大小和頻率。大規(guī)模集群使用建議如下。
優(yōu)先使用informer訪問(wèn)本地緩存數(shù)據(jù)
優(yōu)先使用client-go的informer獲取資源,通過(guò)本地緩存(Cache)查詢數(shù)據(jù),避免List請(qǐng)求直接訪問(wèn)API Server,以減少API Server的負(fù)載壓力。
優(yōu)化通過(guò)API Server獲取資源的方式
對(duì)于未訪問(wèn)過(guò)的本地緩存,仍需直接通過(guò)API Server獲取資源。但可以遵循以下建議。
在List請(qǐng)求中設(shè)置
resourceVersion=0
。resourceVersion
表示資源狀態(tài)的版本。設(shè)置為0
時(shí),請(qǐng)求會(huì)獲取API Server的緩存數(shù)據(jù),而非直接訪問(wèn)etcd,減少API Server與etcd之間的內(nèi)部交互次數(shù),更快地響應(yīng)客戶端List請(qǐng)求。示例如下。k8sClient.CoreV1().Pods("").List(metav1.ListOptions{ResourceVersion: "0"})
避免全量List資源,防止數(shù)據(jù)檢索量過(guò)大。
為了減少請(qǐng)求返回的數(shù)據(jù)量,應(yīng)使用過(guò)濾條件(Filter)來(lái)限定List請(qǐng)求的范圍,例如lable-selector(基于資源標(biāo)簽篩選)或field-selector(基于資源字段篩選)。
說(shuō)明etcd是一個(gè)鍵值(KV)存儲(chǔ)系統(tǒng),本身不具備按label或field過(guò)濾數(shù)據(jù)的功能,請(qǐng)求帶有的過(guò)濾條件實(shí)際由API Server處理。因此,當(dāng)使用Filter功能時(shí),建議同時(shí)將List請(qǐng)求的
resourceVersion
設(shè)置為0
。請(qǐng)求數(shù)據(jù)將從API Server的緩存中獲取,而不會(huì)直接訪問(wèn)etcd,減少對(duì)etcd的壓力。使用Protobuf(而非JSON)訪問(wèn)非CRD資源。
API Server可以以不同的數(shù)據(jù)格式向客戶端返回資源對(duì)象,包括JSON和Protobuf。默認(rèn)情況下,當(dāng)客戶端請(qǐng)求Kubernetes API時(shí),Kubernetes返回序列化為JSON的對(duì)象,其內(nèi)容類(lèi)型(Content-Type)為
application/json
。 客戶端可以指定請(qǐng)求使用Protobuf格式的數(shù)據(jù),Protobuf在內(nèi)存使用和網(wǎng)絡(luò)傳輸流量方面相較JSON更具優(yōu)勢(shì)。但并非所有API資源類(lèi)型都支持Protobuf。發(fā)送請(qǐng)求時(shí),可以在
Accept
請(qǐng)求頭中指定多種內(nèi)容類(lèi)型(例如application/json
、application/vnd.kubernetes.protobuf
),從而支持在無(wú)法使用Protobuf時(shí)回退到默認(rèn)的JSON格式。更多信息,請(qǐng)參見(jiàn)Alternate representations of resources 。示例如下。Accept: application/vnd.kubernetes.protobuf, application/json
使用中心化控制器
避免在每個(gè)節(jié)點(diǎn)上都創(chuàng)建獨(dú)立的控制器用于Watch集群的全量數(shù)據(jù)。在這種情況下,控制器啟動(dòng)時(shí),將幾乎同時(shí)向API Server發(fā)送大量的List請(qǐng)求以同步當(dāng)前的集群狀態(tài),對(duì)控制面造成巨大壓力,繼而導(dǎo)致服務(wù)不穩(wěn)定或崩潰。
為了避免此問(wèn)題,建議采用中心化的控制器設(shè)計(jì),為整個(gè)集群創(chuàng)建一個(gè)或一組集中管理的控制器實(shí)例,運(yùn)行在單個(gè)節(jié)點(diǎn)或少數(shù)幾個(gè)節(jié)點(diǎn)上。中心化的控制器會(huì)負(fù)責(zé)監(jiān)聽(tīng)和處理所需的集群數(shù)據(jù),僅啟動(dòng)一次(或少數(shù)幾次)List請(qǐng)求,并僅維護(hù)必要數(shù)量的Watch連接,大大減少了對(duì)API Server的壓力。
合理規(guī)劃大規(guī)模工作負(fù)載
停用自動(dòng)掛載默認(rèn)的Service Account
為了確保Pod中的Secret的同步更新,kubelet會(huì)為Pod配置的每個(gè)Secret建立一個(gè)Watch長(zhǎng)連接。Watch機(jī)制可以讓kubelet實(shí)時(shí)接收Secret的更新通知。但當(dāng)所有節(jié)點(diǎn)創(chuàng)建的Watch數(shù)量總和過(guò)多時(shí),大量Watch連接可能會(huì)影響集群控制面的性能。
Kubernetes 1.22版本以前:創(chuàng)建Pod時(shí),如果未指定ServiceAccount,Kubernetes會(huì)自動(dòng)掛載默認(rèn)的ServiceAccount作為Pod的Secret,使得Pod內(nèi)部的應(yīng)用能夠與API Server安全通信。
對(duì)于批處理系統(tǒng)和無(wú)需訪問(wèn)API Server的業(yè)務(wù)Pod,建議您顯式聲明禁止自動(dòng)掛載ServiceAccount Token,以避免創(chuàng)建相關(guān)的Secret和Watch(更多信息,請(qǐng)參見(jiàn)automountServiceAccountToken)。在大規(guī)模集群中,該操作可以避免創(chuàng)建不必要的Secret和與API Server的Watch連接,減輕集群控制面的負(fù)擔(dān)。
Kubernetes 1.22及之后:使用TokenRequest API來(lái)獲取一個(gè)短期的、自動(dòng)輪換的令牌,并以投射卷的形式掛載此令牌。在提高Secret安全性的同時(shí),該操作還能減少kubelet為每個(gè)ServiceAccount的Secret建立的Watch連接,降低集群的性能開(kāi)銷(xiāo)。
關(guān)于如何啟用ServiceAccount Token投射卷功能,請(qǐng)參見(jiàn)使用ServiceAccount Token卷投影。
控制Kubernetes Object數(shù)量和大小
請(qǐng)及時(shí)清理無(wú)需使用的Kubernetes資源,例如ConfigMap、Secret、PVC等,減少系統(tǒng)資源的占用,保持集群健康、高效運(yùn)轉(zhuǎn)。有以下使用建議。
限制Deployment歷史記錄數(shù):revisionHistoryLimit聲明了要為Deployment保留多少個(gè)舊的ReplicaSet。如果取值太高,Kubernetes會(huì)保留很多歷史版本的ReplicaSet,增加kube-controller-manager的管理負(fù)擔(dān)。在大規(guī)模集群中,如果Deployment較多且更新頻繁,您可以調(diào)低Deployment的revisionHistoryLimit的取值,清理舊的ReplicaSet。Deployment的revisionHistoryLimit默認(rèn)取值為10。
清理無(wú)需使用的Job和相關(guān)的Pod:如果集群中通過(guò)CronJob或其他機(jī)制創(chuàng)建了大量的作業(yè)(Job)對(duì)象,請(qǐng)使用ttlSecondsAfterFinished來(lái)自動(dòng)清理集群中較舊的Pod,指定在某個(gè)時(shí)間周期后Job和相關(guān)的Pod將完成自動(dòng)清理(刪除)。
合理配置Informer類(lèi)型組件的資源配置
Informer類(lèi)型的組件主要用于監(jiān)控和同步Kubernetes集群的資源狀態(tài)。Informer類(lèi)組件會(huì)建立對(duì)集群API Server資源狀態(tài)的Watch連接,并在本地維護(hù)一個(gè)資源對(duì)象的緩存,以便快速響應(yīng)資源狀態(tài)的變化。
對(duì)于Informer類(lèi)型的組件,例如Controller組件、kube-scheduler等,組件內(nèi)存占用與其Watch的資源大小相關(guān)。大規(guī)模集群下,請(qǐng)關(guān)注該類(lèi)組件的內(nèi)存資源消耗,避免組件OOM。組件頻繁O(jiān)OM會(huì)導(dǎo)致組件持續(xù)資源監(jiān)聽(tīng)出現(xiàn)問(wèn)題。組件頻繁重啟時(shí),每次執(zhí)行的List-Watch操作也會(huì)對(duì)集群控制面(尤其是API Server)造成額外的壓力。
關(guān)注集群控制面指標(biāo)
您可以查看控制面組件監(jiān)控大盤(pán),獲取控制面核心組件的指標(biāo)清單、異常指標(biāo)問(wèn)題解析等。在大規(guī)模集群中,請(qǐng)重點(diǎn)關(guān)注以下指標(biāo)。關(guān)于指標(biāo)的使用說(shuō)明、詳細(xì)說(shuō)明,請(qǐng)參見(jiàn)控制面組件監(jiān)控。
管控資源用量
目前管控組件所有資源用量均可以查看,相關(guān)指標(biāo)和介紹如下:
指標(biāo)名稱(chēng) | PromQL | 說(shuō)明 |
內(nèi)存使用量 | memory_utilization_byte{container="kube-apiserver"} | API Server的內(nèi)存使用量。單位:字節(jié)。 |
CPU使用量 | cpu_utilization_core{container="kube-apiserver"}*1000 | API Server的CPU使用量。單位:毫核。 |
kube-apiserver
關(guān)于如何查看指標(biāo)及指標(biāo)的完整說(shuō)明,請(qǐng)參見(jiàn)kube-apiserver組件監(jiān)控指標(biāo)說(shuō)明。
資源對(duì)象數(shù)量
名稱(chēng)
PromQL
說(shuō)明
資源對(duì)象數(shù)量
max by(resource)(apiserver_storage_objects)
max by(resource)(etcd_object_counts)
當(dāng)ACK為1.22及以上版本時(shí), 指標(biāo)名字為apiserver_storage_objects
當(dāng)ACK為1.22及以下版本時(shí),指標(biāo)名字為etcd_object_counts。
說(shuō)明由于兼容性問(wèn)題,1.22版本中apiserver_storage_objects名稱(chēng)和etcd_object_counts名稱(chēng)均存在。
請(qǐng)求時(shí)延
名稱(chēng)
PromQL
說(shuō)明
GET讀請(qǐng)求時(shí)延
histogram_quantile($quantile, sum(irate(apiserver_request_duration_seconds_bucket{verb="GET",resource!="",subresource!~"log|proxy"}[$interval])) by (pod, verb, resource, subresource, scope, le))
展示GET請(qǐng)求的響應(yīng)時(shí)間,維度包括API Server Pod、Verb(GET)、Resources、Scope。
LIST讀請(qǐng)求時(shí)延
histogram_quantile($quantile, sum(irate(apiserver_request_duration_seconds_bucket{verb="LIST"}[$interval])) by (pod_name, verb, resource, scope, le))
展示LIST請(qǐng)求的響應(yīng)時(shí)間,維度包括API Server Pod、Verb(LIST)、Resources、Scope。
寫(xiě)請(qǐng)求時(shí)延
histogram_quantile($quantile, sum(irate(apiserver_request_duration_seconds_bucket{verb!~"GET|WATCH|LIST|CONNECT"}[$interval])) by (cluster, pod_name, verb, resource, scope, le))
展示Mutating請(qǐng)求的響應(yīng)時(shí)間,維度包括API Server Pod、Verb(GET、WATCH、LIST、CONNECT)、Resources、Scope。
請(qǐng)求限流
名稱(chēng)
PromQL
說(shuō)明
請(qǐng)求限流速率
sum(irate(apiserver_dropped_requests_total{request_kind="readOnly"}[$interval])) by (name)
sum(irate(apiserver_dropped_requests_total{request_kind="mutating"}[$interval])) by (name)
API Server的限流速率 ,
No data
或者0
表示沒(méi)有限流。
kube-scheduler
關(guān)于如何查看指標(biāo)及指標(biāo)的完整說(shuō)明,請(qǐng)參見(jiàn)kube-scheduler組件監(jiān)控指標(biāo)說(shuō)明。
Pending Pod數(shù)
名稱(chēng)
PromQL
說(shuō)明
Scheduler Pending Pods
scheduler_pending_pods{job="ack-scheduler"}
Pending Pod的數(shù)量。隊(duì)列種類(lèi)如下:
unschedulable:不可調(diào)度的Pod數(shù)量。
backoff:backoffQ的Pod數(shù)量,即因?yàn)槟撤N原因暫時(shí)不能被調(diào)度的Pod數(shù)量。
active:activeQ的Pod數(shù)量,即準(zhǔn)備就緒并等待被調(diào)度的Pod數(shù)量。
請(qǐng)求時(shí)延
名稱(chēng)
PromQL
說(shuō)明
Kube API 請(qǐng)求時(shí)延
histogram_quantile($quantile, sum(rate(rest_client_request_duration_seconds_bucket{job="ack-scheduler"}[$interval])) by (verb,url,le))
kube-scheduler對(duì)kube-apiserver組件發(fā)起的HTTP請(qǐng)求時(shí)延,從方法(Verb)和請(qǐng)求URL維度分析。
kube-controller-manager
關(guān)于如何查看指標(biāo)及指標(biāo)的完整說(shuō)明,請(qǐng)參見(jiàn)kube-controller-manager組件監(jiān)控指標(biāo)說(shuō)明。
Workqueue
名稱(chēng) | PromQL | 說(shuō)明 |
Workqueue深度 | sum(rate(workqueue_depth{job="ack-kube-controller-manager"}[$interval])) by (name) | Workqueue深度在單位時(shí)間內(nèi)的變化。 |
Workqueue處理時(shí)延 | histogram_quantile($quantile, sum(rate(workqueue_queue_duration_seconds_bucket{job="ack-kube-controller-manager"}[5m])) by (name, le)) | 事件在Workqueue中存在的時(shí)長(zhǎng)。 |
etcd
關(guān)于如何查看指標(biāo)及指標(biāo)的完整說(shuō)明,請(qǐng)參見(jiàn)etcd組件監(jiān)控指標(biāo)說(shuō)明。
KV總數(shù)
名稱(chēng)
PromQL
說(shuō)明
kv總數(shù)
etcd_debugging_mvcc_keys_total
etcd集群KV對(duì)(鍵對(duì))總數(shù)。
數(shù)據(jù)庫(kù)大小(DB Size)
名稱(chēng)
PromQL
說(shuō)明
磁盤(pán)大小
etcd_mvcc_db_total_size_in_bytes
etcd Backend DB總大小,即etcd后端數(shù)據(jù)庫(kù)總大小。
etcd_mvcc_db_total_size_in_use_in_bytes
etcd Backend DB實(shí)際使用大小,即etcd后端數(shù)據(jù)庫(kù)實(shí)際使用大小。
相關(guān)文檔
關(guān)于ACK集群的配額與限制,請(qǐng)參見(jiàn)配額與限制。
關(guān)于如何合理規(guī)劃集群VPC網(wǎng)絡(luò)及容器網(wǎng)絡(luò),請(qǐng)參見(jiàn)Kubernetes集群網(wǎng)絡(luò)規(guī)劃。
關(guān)于如何實(shí)現(xiàn)集群創(chuàng)建、工作負(fù)載的高可靠配置,請(qǐng)參見(jiàn)工作負(fù)載推薦配置。
使用ACK集群時(shí),如遇報(bào)錯(cuò)或相關(guān)問(wèn)題,請(qǐng)先參見(jiàn)故障排除、集群管理FAQ自排查。