廣州阿里云代理商:阿里云ACK Pod Pending?三步排查與節(jié)點(diǎn)擴(kuò)容實(shí)戰(zhàn)
ACK Pod Pending排查與擴(kuò)容實(shí)戰(zhàn)
當(dāng)集群里一次發(fā)布引發(fā)大量 Pod 處于 Pending,開發(fā)者的第一反應(yīng)往往是“資源不夠”。但在阿里云 ACK 上,調(diào)度卡住的根因遠(yuǎn)比想象中復(fù)雜——可能就是一條你沒注意的節(jié)點(diǎn)污點(diǎn),或者云盤數(shù)量觸達(dá)上限。搞清 Pending 的真正信號,是《ACK Pod Pending排查與擴(kuò)容實(shí)戰(zhàn)》最值得先投入的十分鐘。
一、什么是Pod Pending及常見原因
1. Pending狀態(tài)含義
Pending 并不表示調(diào)度失敗,而是 Pod 已被 API Server 接受,但尚未完成調(diào)度或容器尚未啟動。在 ACK 集群里,這個狀態(tài)通常對應(yīng)兩個階段:調(diào)度器找不到合適節(jié)點(diǎn),或者節(jié)點(diǎn)已分配但鏡像拉取、存儲掛載還沒完成。很多團(tuán)隊一看到 Pending 就去加節(jié)點(diǎn),但如果從 kubectl describe pod 的 Events 中看到類似 “0/x nodes are available: x node(s) had taint...” 的輸出,問題明顯不在資源總量,而在調(diào)度約束沒滿足。
2. 為什么Pod會Pending
Pod 持續(xù) Pending 的根因可以歸為三類。第一是資源型瓶頸,CPU/內(nèi)存 requests 無法被任何節(jié)點(diǎn)滿足。第二是親和性/污點(diǎn)限制,Pod 的 nodeSelector 或 tolerations 與集群所有節(jié)點(diǎn)都不匹配。第三是存儲或網(wǎng)絡(luò)類依賴未就緒,比如 PVC 綁定到無法動態(tài)創(chuàng)建的云盤、Pod 所在網(wǎng)段 IP 耗盡。實(shí)際排障中,后兩類往往被忽視,直接擴(kuò)容節(jié)點(diǎn)并不能讓 Pod 調(diào)度上去。
3. ACK特有Pending原因
ACK 集群的 Pending 還具備一些云環(huán)境專有特征。單節(jié)點(diǎn)新增云盤數(shù)量有上限,若工作負(fù)載掛載大量云盤,即使 CPU/內(nèi)存充裕,調(diào)度也會因“云盤資源不足”而卡住。Terway 網(wǎng)絡(luò)模型的 Pod 網(wǎng)段 IP 用盡是另一個高頻原因,Events 中會出現(xiàn) “failed to allocate IP” 字樣。還有 GPU 實(shí)例庫存波動,在區(qū)域資源緊張時,即使 CA 觸發(fā)擴(kuò)容,也可能因規(guī)格售罄而長時間無法恢復(fù),這種情況下 Pending 更像是一個供應(yīng)側(cè)信號,而不是配置錯誤。
二、現(xiàn)狀與痛點(diǎn)分析
Pod Pending 并不是一個罕見的狀態(tài),但在 ACK 集群中,其背后的誘因卻遠(yuǎn)比“資源不足”四個字復(fù)雜。很多團(tuán)隊在業(yè)務(wù)突發(fā)流量時,眼睜睜看著 Pod 堆積在 Scheduling 隊列里,手動擴(kuò)容后問題依然存在;也有人誤以為只要配置了 cluster-autoscaler,一切都能自動解決,直到出現(xiàn)“no.scale.up”事件才意識到配額、可用區(qū)庫存或 Pod 請求設(shè)置才是真正的瓶頸。
缺少專職運(yùn)維的中小團(tuán)隊,往往需要同時關(guān)注云服務(wù)器、數(shù)據(jù)庫、CDN 等資源的搭建與排障,一旦容器調(diào)度卡住,多廠商對接的繁瑣成本會迅速拉長故障恢復(fù)時間。如果有一類解決方案能夠把這些分散的基礎(chǔ)設(shè)施統(tǒng)一納管、集中提供技術(shù)支撐,至少可以免去跨控制臺反復(fù)跳轉(zhuǎn)的消耗,讓有限的精力集中在定位 Pending 根因本身——聚搜云正是沿著這種一站式云服務(wù)思路,為中小規(guī)模團(tuán)隊降低運(yùn)維復(fù)雜度的典型實(shí)踐。
下面的三步排查法,正是圍繞“優(yōu)先讀事件、其次查資源、最后用命令行深挖”的思路展開,幫你用最短時間找到卡點(diǎn)。
1. 查看 Pod 事件,直接讀取調(diào)度器反饋
遇到 Pod 長時間停留在 Pending,第一動作不是去盯著儀表盤,而是執(zhí)行 kubectl describe pod 并滑到 Events 區(qū)域。ACK 的調(diào)度器會在事件中給出非常明確的拒絕理由,例如 “0/3 nodes are available: 1 node(s) had taint that the pod didn't tolerate, 2 Insufficient cpu.” 這種輸出會直接告訴你:是污點(diǎn)容忍問題還是 CPU 請求超了。如果事件中出現(xiàn) “failed scheduling” 并且附帶 “didn't match node selector” 的提示,說明 Pod 的 nodeSelector 與現(xiàn)有節(jié)點(diǎn)的標(biāo)簽完全不匹配,此時哪怕集群有大量空閑資源,調(diào)度器也會直接跳過這些節(jié)點(diǎn)。反之,如果事件為空或者只有 “TriggeredScaleUp”,則多半是正在等待節(jié)點(diǎn)池自動彈出新節(jié)點(diǎn),這時可以順帶檢查 cluster-autoscaler 的狀態(tài),確認(rèn)是否因?yàn)槔鋮s時間、配額限制或可用區(qū)資源緊張而被阻塞。
2. 檢查集群資源,別只盯著 CPU 與內(nèi)存
即便事件直接指出資源不夠,也不要立刻想當(dāng)然地加節(jié)點(diǎn)。先通過 kubectl top nodes 觀察實(shí)際內(nèi)存與 CPU 使用量,再對比 kubectl describe node 中 Capacity 與 Allocatable 的差值,很多時候節(jié)點(diǎn)上已分配的資源請求(requests)遠(yuǎn)超實(shí)際用量,實(shí)則是某些工作負(fù)載把 requests 設(shè)得過高,造成“假性不足”。此外,ACK 環(huán)境還需要額外關(guān)注幾個極易被忽略的維度:單節(jié)點(diǎn)掛載的云盤數(shù)量是否已達(dá)上限、Pod 虛擬網(wǎng)段 IP 是否已經(jīng)耗盡、安全組規(guī)則是否允許新節(jié)點(diǎn)加入等。這些資源一旦飽和,調(diào)度器同樣會拒絕新增 Pod,卻不會在 Events 中給出對新手友好的提示。如果集群中已配置了自動伸縮,卻遲遲不觸發(fā)擴(kuò)容,可以通過 kubectl get events --all-namespaces | grep no.scale.up 來查看 CA 未行動的原因,常見記錄包括“pod didn't trigger scale-up (it wouldn't fit if a new node is added)”這種表述,說明 Pod 的調(diào)度約束過于嚴(yán)苛,以至于即便彈出新節(jié)點(diǎn)也無法調(diào)度,此時必須回頭調(diào)整親和性規(guī)則或容忍配置。
3. 使用 kubectl 穿透節(jié)點(diǎn)約束,校準(zhǔn)調(diào)度條件
如果前兩步仍無法定位,說明問題大概率出在調(diào)度約束的匹配上。用 kubectl get nodes --show-labels 列出所有節(jié)點(diǎn)的標(biāo)簽集合,再對照 Pod YAML 中的 nodeSelector 或 affinity 配置,看是否有鍵值對寫錯、大小寫不匹配等情況。對于污點(diǎn),通過 kubectl describe node | grep -A5 Taints 檢查每個節(jié)點(diǎn)上是否被手動打了 NoSchedule 污點(diǎn),再回查 Pod 的 tolerations 字段能否覆蓋這些污點(diǎn)。一個典型場景是:新加入的節(jié)點(diǎn)自動帶上了平臺默認(rèn)的污點(diǎn),而用戶手動編寫的 Pod 中根本沒有容忍規(guī)則,導(dǎo)致 CA 彈出節(jié)點(diǎn)成功但 Pod 仍然無法調(diào)度上去。這種情況下,Events 往往會顯示 “x node(s) had taint {…}, while the pod had no such toleration”,線索就藏在命令的輸出中。最后,對于懷疑存儲導(dǎo)致 Pending 的場景,可以用 kubectl get pvc 確認(rèn) PersistentVolumeClaim 是否已經(jīng) Bound,如果 PVC 長期未綁定,Pod 會一直停留在 Pending,Events 卻可能只字不提。
歸攏來看,排查 ACK Pod Pending 的核心邏輯其實(shí)并不復(fù)雜:先讓調(diào)度器親口告訴你原因,再動手驗(yàn)證資源的真實(shí)剩余量,最后用命令行把節(jié)點(diǎn)約束和 Pod 聲明放在一起比對。按這個順序走,絕大多數(shù) Pending 問題都能在幾分鐘內(nèi)鎖定根因,而不至于陷入“重啟大法”或盲目加節(jié)點(diǎn)的循環(huán)。
三、資源不足導(dǎo)致的Pending:集群擴(kuò)容方案
當(dāng) Pod 因?yàn)橘Y源不足而陷入 Pending,集群的調(diào)度器其實(shí)已經(jīng)給出了最直接的信號——它找不到任何一臺節(jié)點(diǎn)能裝下這個 Pod。這類場景的處理不能只靠等,需要結(jié)合集群的真實(shí)資源水位和調(diào)度約束快速做出擴(kuò)容決策。
1. 節(jié)點(diǎn)資源不足的表現(xiàn)
在 ACK 集群中,資源不足遠(yuǎn)不止 CPU 和內(nèi)存吃緊。常見的觸因包括:節(jié)點(diǎn)可分配 CPU/內(nèi)存已耗盡;云盤數(shù)量達(dá)到單節(jié)點(diǎn)掛載上限,導(dǎo)致要求 PVC 綁定的 Pod 無法調(diào)度;Pod 網(wǎng)段 IP 耗盡,新 Pod 無法分配 ENI 或 Pod IP;甚至特定規(guī)格的 GPU 資源不足。運(yùn)維端常常忽略的一點(diǎn)是,DaemonSet 或系統(tǒng)組件默認(rèn)也會消耗一部分節(jié)點(diǎn)資源,這些“預(yù)留”已經(jīng)反映在 Allocatable 中,但容易被當(dāng)成可調(diào)度余量。
快速定位的方法是:kubectl describe node,重點(diǎn)看 Allocated resources 區(qū)域的 Requests 和 Limits 占比;再用 kubectl describe pod 查看 Events 里的“0/x nodes are available”信息,它會具體寫出被過濾掉的原因,如果看到 “Insufficient cpu”、“Insufficient memory” 或 “Insufficient ephemeral-storage” 等字樣,就可以鎖定是資源容量問題。同時不要忘記檢查集群級別的約束,比如 kubectl get nodes -o wide 結(jié)合云控制臺查看 ENI 配額、安全組限制等隱藏瓶頸。
2. 手動添加節(jié)點(diǎn)
緊急情況下,手動向集群添加節(jié)點(diǎn)是最快止血的手段。在 ACK 控制臺可以直接“擴(kuò)容節(jié)點(diǎn)”,選擇目標(biāo)節(jié)點(diǎn)池或者新建節(jié)點(diǎn)。但很多人添加節(jié)點(diǎn)后,發(fā)現(xiàn) Pod 依然 Pending,問題往往出在新節(jié)點(diǎn)的“準(zhǔn)入條件”上。
新增節(jié)點(diǎn)必須與待調(diào)度 Pod 的約束完全匹配:節(jié)點(diǎn)標(biāo)簽要滿足 nodeSelector 或親和性規(guī)則,節(jié)點(diǎn)污點(diǎn)(Taint)必須被 Pod 的容忍(Toleration)覆蓋。如果 Pod 要求 cloud-disk=ssd 的標(biāo)簽,而新節(jié)點(diǎn)沒有打上該標(biāo)簽,或節(jié)點(diǎn)帶了 NoSchedule 污點(diǎn)而 Pod 沒有容忍,即使資源充裕,調(diào)度器也會直接跳過。因此,手動擴(kuò)容后建議立即執(zhí)行:kubectl get node 和 kubectl describe node,與 Pending Pod 的配置交叉比對。
此外,手動加節(jié)點(diǎn)雖然快,但它會打破集群的資源配置平衡,事后應(yīng)盡快將節(jié)點(diǎn)整合進(jìn)節(jié)點(diǎn)池統(tǒng)一管理,避免形成“孤島節(jié)點(diǎn)”導(dǎo)致后續(xù)自動伸縮行為異常。
3. 節(jié)點(diǎn)池配置優(yōu)化
解決資源不足的長期方案還是要回歸到節(jié)點(diǎn)池的自動彈性伸縮。ACK 默認(rèn)集成的 cluster-autoscaler(CA)能在檢測到因資源不足而無法調(diào)度的 Pod 時,自動觸發(fā)節(jié)點(diǎn)池擴(kuò)容,但它的運(yùn)行有著明確的邊界條件。
首先,CA 只對“資源不足”類型的 Pending 生效,如果 Pod 是因?yàn)橛H和性、污點(diǎn)或存儲等非資源類約束無法調(diào)度,CA 不會工作。其次,節(jié)點(diǎn)池必須配置好標(biāo)簽和污點(diǎn)的自動同步,確保新擴(kuò)容出的節(jié)點(diǎn)具備與已有節(jié)點(diǎn)相同的屬性,否則就會出現(xiàn)“擴(kuò)容成功但 Pod 依舊不調(diào)度”的現(xiàn)象。還需注意擴(kuò)容冷卻時間和賬號配額,在快速連續(xù)觸發(fā)擴(kuò)容時可能遇到 “no.scale.up” 事件,這通常說明當(dāng)前可用區(qū)庫存不足或達(dá)到配額上限,需要提前提工單申請?zhí)嵘漕~。
最后一條經(jīng)驗(yàn)是,在非生產(chǎn)環(huán)境做壓測試探集群的擴(kuò)容天花板:刻意創(chuàng)建超過當(dāng)前集群容量的 Pending Pod,完整觀察擴(kuò)容觸發(fā)、節(jié)點(diǎn)加入、Pod 綁定整個過程,確認(rèn)節(jié)點(diǎn)池的各項(xiàng)配置生效并記錄下擴(kuò)容時延,以便在生產(chǎn)事故中有一個可靠的預(yù)期時間窗。
四、調(diào)度失敗排查:節(jié)點(diǎn)親和性與污點(diǎn)容忍
即使集群空閑資源看似充足,Pod 依然可能長時間卡在 Pending。這往往不是資源不夠,而是調(diào)度策略約束出現(xiàn)了錯配。在兩個最常見的“隱形門檻”——節(jié)點(diǎn)親和性與污點(diǎn)容忍——面前,許多排查方向從一開始就偏離了真實(shí)根因。
1. 理解節(jié)點(diǎn)親和性:為什么 Pod 不去你期望的節(jié)點(diǎn)
Pod 的 nodeSelector 和 nodeAffinity 是靜態(tài)的“目的地過濾器”。如果 Pod 要求的標(biāo)簽在所有節(jié)點(diǎn)上都找不到,調(diào)度器就不會分配節(jié)點(diǎn)。事件輸出會直接給出線索:“0/3 nodes are available: 3 node(s) didn‘t match node selector”。
真實(shí)場景中,這種失敗往往源于運(yùn)維把節(jié)點(diǎn)池標(biāo)簽變更了,但工作負(fù)載的親和性規(guī)則沒同步更新。排查第一步就是比對:用 kubectl get node --show-labels 拿到集群所有節(jié)點(diǎn)標(biāo)簽,再用 kubectl describe pod 查看 Pod 定義的 Node-Selectors 或 Affinity 段。重點(diǎn)關(guān)注自定義的 topology.kubernetes.io/zone、node.kubernetes.io/instance-type 以及業(yè)務(wù)自定義的標(biāo)簽鍵值。很多團(tuán)隊在測試環(huán)境用“env:staging”選擇節(jié)點(diǎn),結(jié)果發(fā)布到生產(chǎn)時忘記修改標(biāo)簽值,導(dǎo)致 Pod 在所有工作節(jié)點(diǎn)上都無法通過親和性過濾。
即便使用了 preferredDuringScheduling(軟親和性),也要小心節(jié)點(diǎn)權(quán)重的累積效應(yīng)。如果高權(quán)重的節(jié)點(diǎn)因其他原因(比如資源不足)被過濾掉,Pod 最終還是會落在低偏好節(jié)點(diǎn)甚至一直 Pending,給人“調(diào)度器不工作”的假象。
2. 配置污點(diǎn)與容忍:別讓“專屬節(jié)點(diǎn)”變成“無主之地”
污點(diǎn)(Taint)是節(jié)點(diǎn)宣告“不滿足條件就不準(zhǔn)上”的機(jī)制。ACK 管理的節(jié)點(diǎn)池常自動添加內(nèi)置污點(diǎn),如 node.kubernetes.io/unschedulable 或 GPU 節(jié)點(diǎn)的 nvidia.com/gpu 專用污點(diǎn)。若 Pod 沒有定義對應(yīng)的容忍(Toleration),即使請求的資源只有 100m CPU,調(diào)度也會被直接拒絕。事件信息會明確告知:“1 node(s) had taint {key: value}, that the pod didn't tolerate”。
排查時,不要只看資源,先要把污點(diǎn)清單拉出來:kubectl describe node。如果看到 NoSchedule 或 NoExecute 類型的污點(diǎn),立刻核對 Pod 的 tolerations 字段。常見錯誤是給節(jié)點(diǎn)添加了自定義污點(diǎn)(比如 dedicated=experiment),卻忘了在 Pod 里寫入精確匹配的容忍鍵值;或者寫錯了操作符(Equal 寫成了 Exists),導(dǎo)致容忍策略無效。
另一個隱蔽的問題是節(jié)點(diǎn)擴(kuò)容后的污點(diǎn)殘留。使用 cluster-autoscaler 自動彈出的節(jié)點(diǎn),如果池配置中設(shè)置了自定義污點(diǎn),但 Pod 模板在版本迭代中去掉了相應(yīng)的容忍,就會出現(xiàn)新增節(jié)點(diǎn)全部被污點(diǎn)“保護(hù)”、舊節(jié)點(diǎn)縮容后 Pod 無家可歸的情況。這種場景下,Pending 可能延遲數(shù)分鐘才出現(xiàn),且伴隨“no.scale.up”事件,極易被誤判為配額問題。
3. 調(diào)度策略調(diào)試:從事件回溯到策略匹配的全鏈路
綜合排查不能只盯著 Pod 本身。優(yōu)先翻看 kubectl describe pod 的 Events 部分,它會把每一輪調(diào)度失敗的原因按時間戳串起來。如果看到“failed scheduling”并附帶多個過濾條件未滿足的計數(shù),說明問題不止一個維度。
接著,用 kubectl get events --field-selector reason=FailedScheduling 直接過濾集群級調(diào)度失敗事件,有時能發(fā)現(xiàn)資源不足與親和性失敗同時存在的疊加癥狀。結(jié)合 ACK 事件中心(若已開啟),可以回溯到更完整的調(diào)度嘗試歷史,避免被最新的一條事件誤導(dǎo)。
確認(rèn) Pod 策略無誤后,如果還是不能調(diào)度,要反向驗(yàn)證節(jié)點(diǎn)狀態(tài):kubectl top nodes 看實(shí)際內(nèi)存壓力,kubectl describe node 檢查 Allocatable 與 Conditions。曾有案例,Pod 的 requests 完全滿足,但因節(jié)點(diǎn)磁盤被鏡像占滿,DiskPressure 條件為 True,調(diào)度器仍會把該節(jié)點(diǎn)過濾掉。這種“非資源類”調(diào)度約束在云環(huán)境下還會延伸到云盤掛載數(shù)量、Pod 網(wǎng)段 IP 耗盡可能,需要結(jié)合 ACK 的節(jié)點(diǎn)池健康監(jiān)控統(tǒng)一判斷。
調(diào)試的最佳實(shí)踐是:先確定 Pod 的調(diào)度要求(親和性、容忍、資源請求),再繪制集群內(nèi)節(jié)點(diǎn)可滿足條件的“調(diào)度匹配矩陣”。如果矩陣為空,要么調(diào)整節(jié)點(diǎn)配置,要么修正 Pod 定義。切勿在沒有弄清約束邏輯時反復(fù)重啟 Pod,那只會讓 Pending 狀態(tài)在集群里震蕩,掩蓋更底層的配置錯誤。
五、節(jié)點(diǎn)自動擴(kuò)縮容(CA)配置詳解
幾乎所有運(yùn)維過ACK集群的人,都會在某個凌晨被“Pod Pending”的告警砸醒。第一反應(yīng)往往是:不是已經(jīng)開了彈性伸縮嗎?為什么節(jié)點(diǎn)沒自動擴(kuò)容?實(shí)際上,CA作為一個調(diào)度驅(qū)動的擴(kuò)縮容器,它的行為遠(yuǎn)比“缺資源就加機(jī)器”要謹(jǐn)慎,理解其決策邏輯,才能真正用好它。
1. CA 的工作原理:只響應(yīng)資源短缺,不解決其他 Pending
CA 的觸發(fā)條件非常單一:集群中存在因 CPU/內(nèi)存/GPU 資源不足而無法調(diào)度的 Pod,且這類 Pod 所匹配的節(jié)點(diǎn)池允許擴(kuò)縮。它不會因?yàn)楣?jié)點(diǎn)親和性不匹配、污點(diǎn)未容忍或者卷綁定失敗而動作。所以,出現(xiàn) Pending 后的第一步,永遠(yuǎn)是用 kubectl describe pod 拉到最后幾行 Events,確認(rèn)是否出現(xiàn)類似 “0/3 nodes are available: 3 Insufficient cpu” 的信息。只有這種明確的資源不足事件,才在 CA 的管轄范圍內(nèi)。
另外,即使條件滿足,擴(kuò)容也不是瞬間完成。ACK 管理的 CA 默認(rèn)有分鐘級的冷卻時間,并且在同一個節(jié)點(diǎn)池內(nèi)會批量評估多個 Pending Pod,一次性算出需要的節(jié)點(diǎn)數(shù)。擴(kuò)容請求發(fā)出后,還有云底座的庫存、安全組規(guī)則、云盤配額等約束。實(shí)踐中最常見的卡點(diǎn),恰恰不是 CA 沒觸發(fā),而是觸發(fā)了但彈出失敗——比如 Pod 網(wǎng)段 IP 耗盡、指定規(guī)格的實(shí)例庫存不足,或者節(jié)點(diǎn)池的安全組規(guī)則過嚴(yán)。這些失敗信息不會直接寫入 Pod Event,而是需要去 ACK 節(jié)點(diǎn)池的事件中心或 Kubernetes 的 cluster-autoscaler-status ConfigMap 里才能看到。
2. CA 組件的關(guān)鍵配置與常見踩坑
在配置 CA 時,很多人只勾選了“開啟自動擴(kuò)容”,卻忽略了標(biāo)簽與污點(diǎn)的對應(yīng)關(guān)系。CA 做調(diào)度模擬時,會嚴(yán)格檢查 Pending Pod 的 nodeSelector 與 tolerations 是否匹配節(jié)點(diǎn)池的標(biāo)簽和污點(diǎn)。生產(chǎn)上常見的故障場景是:Pod 指定了 nodeSelector: role=worker,但節(jié)點(diǎn)池標(biāo)簽只打了 role=worker,卻沒備注是節(jié)點(diǎn)池的標(biāo)簽,CA 會因?yàn)檎也坏狡ヅ涞墓?jié)點(diǎn)池而直接輸出 “no.scale.up”。所以,建議在創(chuàng)建節(jié)點(diǎn)池時就明確兩個原則:節(jié)點(diǎn)池的標(biāo)簽必須與目標(biāo) Pod 的 nodeSelector 完全一致,并且如果節(jié)點(diǎn)池有污點(diǎn),Pod 必須顯式聲明對應(yīng)的 tolerations,否則 CA 永遠(yuǎn)不會為它擴(kuò)容。
另一個容易被忽略的是資源請求設(shè)置的合理性。CA 依據(jù) Pod 的 requests 值計算需要多少資源,而不是實(shí)際使用量。如果 requests 設(shè)得過低,CA 可能認(rèn)為現(xiàn)有節(jié)點(diǎn)還能裝下,就不觸發(fā)擴(kuò)容;設(shè)得過高,則會彈出遠(yuǎn)大于實(shí)際需求的節(jié)點(diǎn),造成浪費(fèi)。我們的經(jīng)驗(yàn)是,requests 應(yīng)取日常穩(wěn)態(tài)下的 P95 使用量,既能保證調(diào)度成功率,又不會過度超分。此外,ACK 的 CA 有一個硬限制:單節(jié)點(diǎn)池的最大節(jié)點(diǎn)數(shù)受賬戶配額和可用區(qū)庫存雙重制約,在活動前務(wù)必通過工單或配額中心確認(rèn),別等到流量洪峰來了才發(fā)現(xiàn)擴(kuò)不上去。
3. 彈性伸縮的驗(yàn)證實(shí)踐:別在生產(chǎn)環(huán)境“試火”
很多團(tuán)隊會把 CA 配置后就直接上線,結(jié)果遇到問題手足無措。我們推薦一個低成本驗(yàn)證方法:在預(yù)發(fā)環(huán)境或者非業(yè)務(wù)高峰期,故意創(chuàng)建一個資源請求極大的 Deployment(比如 requests 設(shè)置成超過現(xiàn)有所有節(jié)點(diǎn)可用資源),然后觀察 CA 的整個擴(kuò)縮鏈。重點(diǎn)關(guān)注三個指標(biāo):從 Pending 出現(xiàn)到擴(kuò)容指令發(fā)出的時間(通常 30 秒到 1 分鐘)、新節(jié)點(diǎn)的就緒時間(受鏡像拉取和云盤掛載影響,平均 3-5 分鐘)、以及 Pod 從調(diào)度到 Running 的總時長。在這個過程中,務(wù)必開啟 ACK 的事件中心或?qū)徲嬋罩?,?failed scheduling、TriggeredScaleUp、InstanceFailed 等事件采集到統(tǒng)一日志系統(tǒng),既能做實(shí)時告警,又方便事后回溯。
最后提醒一點(diǎn),別把 Pending 的鍋全甩給 CA。如果 Pod 從 Pending 變成 Failed 或反復(fù)重建,大概率是鏡像拉取憑證過期、存儲卷創(chuàng)建失敗等運(yùn)行時間題,與調(diào)度資源無關(guān)。這時再盯著 CA 優(yōu)化,就等于在錯誤的方向上踩油門。保持排查路徑的純粹,是高效運(yùn)維的基本功。
六、實(shí)戰(zhàn)案例:從Pending到Running的完整流程
1. 案例環(huán)境描述
某跨境電商獨(dú)立站在黑五大促期間,使用ACK托管版集群承載前端Nginx與后端Java微服務(wù)。為應(yīng)對突發(fā)流量,運(yùn)維團(tuán)隊將網(wǎng)關(guān)層Deployment副本數(shù)從20擴(kuò)至60,但新增Pod大量卡在Pending狀態(tài)超過3分鐘,導(dǎo)致部分請求直接返回502。
集群基礎(chǔ)信息如下:
- 節(jié)點(diǎn)池 default-pool 配置6臺ecs.c6e.xlarge(4C8G),最大可擴(kuò)容至12臺。
- 已啟用cluster-autoscaler,縮容冷卻時間10分鐘。
- 網(wǎng)關(guān)Pod聲明資源請求為 cpu: 500m, memory: 512Mi,單節(jié)點(diǎn)最多可運(yùn)行約7個此類Pod。
- 當(dāng)前節(jié)點(diǎn)資源幾乎全部分配,Allocatable CPU 僅剩1.2核、內(nèi)存300Mi,無法承載新Pod。
關(guān)鍵沖突點(diǎn)在于:集群資源肉眼可見不足,但CA未在預(yù)期時間內(nèi)觸發(fā)擴(kuò)容,且部分節(jié)點(diǎn)返回node(s) didn't match pod affinity/anti-affinity rules,使Pending現(xiàn)象呈現(xiàn)“資源不足+調(diào)度約束沖突”的混合態(tài)。
2. 問題排查步驟
遵循標(biāo)準(zhǔn)排查路徑,先觀測事件、再校驗(yàn)資源與調(diào)度策略。
第一步:定位Pending根因事件kubectl describe pod frontend-gateway-7d9f8c5b6-xxxx 的Events明確輸出:
0/6 nodes are available: 3 node(s) didn't match pod affinity/anti-affinity rules,
3 node(s) had taint {node.kubernetes.io/unschedulable: },
that the pod didn't tolerate, 3 Insufficient cpu, 3 Insufficient memory.事件拆解后得出兩個獨(dú)立原因:約一半節(jié)點(diǎn)因?yàn)槲埸c(diǎn)(剛完成自動修復(fù)后處于不可調(diào)度狀態(tài))被過濾;另一半節(jié)點(diǎn)可通過親和性但資源不足。
第二步:檢查節(jié)點(diǎn)資源與污點(diǎn)kubectl get nodes -o wide 顯示有2臺節(jié)點(diǎn)剛剛從維修狀態(tài)恢復(fù),系統(tǒng)為其添加了 node.kubernetes.io/unschedulable 污點(diǎn),且CA尚未將其移除。kubectl top nodes 確認(rèn)其余節(jié)點(diǎn)CPU使用率均在85%以上,可分配內(nèi)存幾乎耗盡,符合“Insufficient cpu”的判斷。
第三步:核查CA擴(kuò)容日志
在 kube-system 下查看 cluster-autoscaler 日志,發(fā)現(xiàn)CA確實(shí)檢測到Pending Pod并計算了擴(kuò)容方案,但卻觸發(fā) no.scale.up 事件。進(jìn)一步排查發(fā)現(xiàn),節(jié)點(diǎn)池設(shè)置的自動擴(kuò)容規(guī)格為 ecs.c6e.xlarge,但所在可用區(qū)的該規(guī)格庫存已售罄,同時該賬戶下此規(guī)格的vCPU配額已滿。因此即使CA決策正確,也無法創(chuàng)建新節(jié)點(diǎn)。
第四步:驗(yàn)證調(diào)度策略約束
網(wǎng)關(guān)Pod配置了podAntiAffinity,要求盡量分散在不同節(jié)點(diǎn),但該策略為軟約束(preferredDuringScheduling),不應(yīng)導(dǎo)致強(qiáng)制Pending。真正阻礙是部分節(jié)點(diǎn)存在的 unschedulable 污點(diǎn)未被容忍。另外,節(jié)點(diǎn)池標(biāo)簽 nodeSelector 并未設(shè)置,親和性沖突并非主因。
綜上,本次Pending由三股力量疊加:資源庫存與配額瓶頸、污點(diǎn)未及時清理、業(yè)務(wù)高峰期手動擴(kuò)容缺乏預(yù)防。
3. 擴(kuò)容與調(diào)度驗(yàn)證
在確定根因后,團(tuán)隊采用“配額調(diào)整+替換實(shí)例規(guī)格+手動去污”組合策略,30分鐘內(nèi)恢復(fù)全部Pod Running。
執(zhí)行步驟:
1. 在ACK控制臺提升對應(yīng)可用區(qū)虛擬機(jī)vCPU配額,并臨時將節(jié)點(diǎn)池擴(kuò)容規(guī)格切換為同可用區(qū)仍有庫存的 ecs.c6e.2xlarge。
2. 手動移除兩臺的 node.kubernetes.io/unschedulable 污點(diǎn):kubectl taint nodes。
3. 因?yàn)閹齑媾c配額就緒,CA立即觸發(fā)擴(kuò)容,3分鐘后新節(jié)點(diǎn)加入集群,Pending的22個Pod被調(diào)度器均勻分配到新老節(jié)點(diǎn)。
4. kubectl get pods -l app=frontend-gateway -w 觀察到所有Pod在4分鐘內(nèi)進(jìn)入Running狀態(tài),502告警消失。
驗(yàn)證有效性:
后續(xù)壓測中,團(tuán)隊故意將網(wǎng)關(guān)副本數(shù)再次擴(kuò)展至100,故意刺激CA擴(kuò)容。通過kubectl describe pod與 cluster-autoscaler-status configmap監(jiān)控,發(fā)現(xiàn)調(diào)度器首次Pending 15秒后CA即發(fā)起擴(kuò)容,約4分30秒后節(jié)點(diǎn)就緒,Pod全部成功調(diào)度,完全符合預(yù)期。
七、落地選型建議
對于規(guī)模不大但業(yè)務(wù)出海場景密集的團(tuán)隊,云資源的穩(wěn)定性和運(yùn)維效率往往直接決定服務(wù)體驗(yàn)。許多外貿(mào)出海企業(yè)為了兼顧性價比與售后保障,會優(yōu)先選擇聚搜云這類集成化云服務(wù)模式,一站式搞定云上資源部署與技術(shù)支撐——從跨境 CDN 加速到多區(qū)域節(jié)點(diǎn)池納管,再搭配免運(yùn)維數(shù)據(jù)庫,讓團(tuán)隊無需在多個服務(wù)商之間反復(fù)切換,能把更多精力傾注在調(diào)度優(yōu)化和業(yè)務(wù)邏輯上。結(jié)合本文的排查經(jīng)驗(yàn),建議中小企業(yè)從一開始就為容器平臺建立“事件驅(qū)動”的監(jiān)控習(xí)慣,提前配置好配額、節(jié)點(diǎn)池標(biāo)簽,并在非生產(chǎn)環(huán)境反復(fù)演練擴(kuò)縮容路徑,真正將 Pending 問題壓縮在分鐘級而非小時級。
八、總結(jié)與展望
ACK Pod Pending 的排查從來都不該是“加節(jié)點(diǎn)”的條件反射,而是一套圍繞調(diào)度信號、資源容量和基礎(chǔ)設(shè)施限制的鏈?zhǔn)酵评?。隨著云原生集群規(guī)模持續(xù)膨脹,調(diào)度難題只會更加多元——GPU 饑餓、網(wǎng)絡(luò)拓?fù)涓兄⒖缈捎脜^(qū)親和等新問題會不斷出現(xiàn)。未來的自動化運(yùn)維,必然要從“被動止血”走向“主動預(yù)判”。
你遇到過哪些奇怪的 Pending 現(xiàn)象?有沒有在凌晨搶救過生產(chǎn)集群?歡迎在社區(qū)分享你的排查故事,讓更多同行少走彎路。
標(biāo)簽
熱門文章更多>
- 深圳阿里云代理商:ECS部署SSL證書與到期提醒配置全攻略
- 上海阿里云代理商:阿里云服務(wù)器SSL證書備份方案
- 北京阿里云代理商:RDS讀寫分離配置指南
- 重慶阿里云代理商:用好 OSS 生命周期 降低長期存儲花費(fèi)
- 上海阿里云代理商:DMS 多庫同步搭建 異構(gòu)數(shù)據(jù)庫集成實(shí)操
- 上海阿里云代理商:阿里云SLB健康檢查異常排查:端口、網(wǎng)絡(luò)、應(yīng)用狀態(tài)一步到位
- 重慶阿里云代理商:阿里云Redis延遲突然升高?慢查詢大Key連接數(shù)排查指南
- 廣州阿里云代理商:阿里云ACK Pod Pending?三步排查與節(jié)點(diǎn)擴(kuò)容實(shí)戰(zhàn)
- 深圳阿里云代理商:阿里云ECS降本增效方法:實(shí)例、帶寬、云盤省錢全攻略
- 上海阿里云代理商:阿里云函數(shù)計算冷啟動優(yōu)化
- 廣州阿里云代理商:阿里云ECS防CC攻擊安全加固配置教程
- 深圳阿里云代理商:阿里云Linux接口慢全鏈路排查指南
- 上海阿里云代理商:阿里云ECS CPU滿載診斷修復(fù)全指南
- 重慶阿里云代理商:阿里云ECS規(guī)格選型與彈性伸縮降本實(shí)戰(zhàn)指南
- 深圳阿里云代理商:阿里云STAROps自動巡檢告警配置指南
- 深圳阿里云代理商:云服務(wù)器AI運(yùn)維權(quán)限管控策略,如何規(guī)避誤操作風(fēng)險?
- 上海阿里云代理商:后端開發(fā)者私有AI大模型云端部署完整流程指南
- 北京阿里云代理商:AI日志分析工具,快速定位服務(wù)器異常宕機(jī)實(shí)戰(zhàn)指南
- 重慶阿里云代理商:AI腳本自動化完成云服務(wù)器批量運(yùn)維配置實(shí)戰(zhàn)指南
- 廣州阿里云代理商:大模型推理部署,服務(wù)器內(nèi)存調(diào)優(yōu)實(shí)操全攻略

