k8s-自动横向伸缩pod 根据CPU使用率,QPS访问数监控指标
k8s-自動(dòng)橫向伸縮pod 與節(jié)點(diǎn)
簡述
我們可以通過調(diào)高ReplicationController、 ReplicaSet、 Deployment等可伸縮資源的rep讓cas字段, 來手動(dòng)實(shí)現(xiàn)pod中應(yīng)用的橫向擴(kuò)容。 我們也可以通過增加pod容器的資源請(qǐng)求和限制來縱向擴(kuò)容pod (盡管目前該操作只能在pod創(chuàng)建時(shí), 而非運(yùn)行時(shí)進(jìn)行)。 雖然如果你能預(yù)先知道負(fù)載何時(shí)會(huì)飄升, 或者如果負(fù)載的變化是較長時(shí)間內(nèi)逐漸發(fā)生的, 手動(dòng)擴(kuò)容也是可以接受的, 但指望靠人工干預(yù)來處理突發(fā)而不可預(yù)測的流量增長, 仍然不夠理想。
?
Kubemetes可以監(jiān)控你的pod, 并在檢測到CPU使用率或其他度量增長時(shí)自動(dòng)對(duì)它們擴(kuò)容。 如果Kubemetes運(yùn)行在云端基礎(chǔ)架構(gòu)之上, 它甚至能在現(xiàn)有節(jié)點(diǎn)無法承載更多pod之時(shí)自動(dòng)新建更多節(jié)點(diǎn)。
pod的橫向自動(dòng)伸縮
橫向pod自動(dòng)伸縮是指由控制器管理 的pod副本數(shù)量的自動(dòng)伸 縮。 它由Horizontal控制器執(zhí)行, 我們通過創(chuàng)建 一個(gè)HorizontalpodAutoscaler C HPA)資源來啟用和配置Horizontal控制器。 該控制器周期性檢查pod度量, 計(jì)算滿足HPA資源所配置的目標(biāo)數(shù)值所需的副本數(shù)量, 進(jìn)而調(diào)整目標(biāo)資源(如Deployment、ReplicaSet、 ReplicationController、StatefulSet等)的replicas字段。
?
自動(dòng)伸縮過程
自動(dòng)伸縮的過程可以分為三個(gè)步驟:
? 獲取被伸縮資源對(duì)象所管理的所有pod度量。
? 計(jì)算使度量數(shù)值到達(dá)(或接近)所指定目標(biāo)數(shù)值所需的pod數(shù)量。
? 更新被伸縮資源的replicas字段。?
?
下面我們就來看看這三個(gè)步驟。
獲取pod度量?
Autoscaler本身并不負(fù)責(zé)采集pod度量數(shù)據(jù) , 而是從另外的來源獲取。 正如之前提到的, pod與節(jié)點(diǎn)度量數(shù)據(jù)是由運(yùn)行在每個(gè)節(jié)點(diǎn)的kubelet之上, 名為cAdvisor的agent采集的;這些數(shù)據(jù)將由 集群級(jí)的組件Heapster聚合。 HPA控制器向Heapster 發(fā)起REST調(diào)用來獲取 所有pod度量數(shù)據(jù)。?
計(jì)算所需的 pod 數(shù)量
一 旦Autoscaler獲得了它所調(diào)整的資源(Deployment、 ReplicaSet、ReplicationController或State伈!Set)所轄pod的全部度量, 它便可以利用這些度量計(jì)算出所需的副本數(shù)量。 它需要計(jì)算出一個(gè)合適的副本數(shù)量, 以使所有副本上度量的平均值盡量接近配置的目標(biāo)值。 該計(jì)算的輸入是一組pod度量(每個(gè)pod可能有多個(gè)), 輸出則是一個(gè)整數(shù)(pod副本數(shù)量)。
當(dāng)Autoscaler配置為只考慮單個(gè)度量時(shí), 計(jì)算所需 副本數(shù)很簡單。 只要將所有pod的度量求和后除以HPA資源上配置的目標(biāo)值, 再向上取整即可。 實(shí)際的計(jì)算稍微復(fù)雜一些; Autoscaler還保證了度量數(shù)值不穩(wěn)定、 迅速抖動(dòng)時(shí)不會(huì)導(dǎo)致系統(tǒng)抖動(dòng)(thrash)。
基于多個(gè)pod度量的自動(dòng)伸縮(例如: CPU使用率和每秒查詢率[QPS])的計(jì)算也并不復(fù)雜。 Autoscaler單獨(dú)計(jì)算每個(gè)度量的副本數(shù), 然后取最大值(例如:如果需要4個(gè)pod達(dá)到目標(biāo)CPU使用率, 以及需要3個(gè)pod來達(dá)到目標(biāo)QPS, 那么Autoscaler 將擴(kuò)展到4個(gè)pod)。 下圖展示了這個(gè)示例。
更新被伸縮資源的副本數(shù)
自動(dòng)伸縮操作的最后 一 步是更新被伸縮資源對(duì)象(比如ReplicaSet)上的副本數(shù)字段 然后讓ReplicaSet控制器負(fù)責(zé)啟動(dòng)更多pod或者刪除多余的pod。Autoscaler控制器通過scale子資源來修改被伸縮資源的rep巨cas字段。 這樣Autoscaler不必了解它所管理資源的細(xì)節(jié),而只需要通過Scale子資源暴露的界面,就可以完成它的工作了,如下圖
HPA只對(duì)Scale子資源進(jìn)行更改 。
這意味著只要API服務(wù)器為某個(gè)可伸縮資源暴露了Scale子資源, Autoscaler即可操作該資源。 目前暴露了Scale子資源的資源有:?
?
?View Code?
了解整個(gè)自動(dòng)伸縮過程
從pod指向 cAdvisor, 再經(jīng)過Heapster , 而最終到達(dá)HPA的箭頭代表度量數(shù)據(jù)的流向。 值得注意的是, 每個(gè)組件從其他組件拉取數(shù)據(jù)的動(dòng)作是周期性的 (即cAdvisor用 一個(gè)無限循環(huán)從pod中采集數(shù)據(jù); Heapster與HPA控制器亦是如此)。這意味著度量數(shù)據(jù)的傳播與相應(yīng)動(dòng)作的觸發(fā)都需要相當(dāng)一段時(shí)間, 不是立即發(fā)生的。接下來實(shí)地觀察Autoscaler行為時(shí)要注意這一點(diǎn)。?
基于CPU使用率進(jìn)行自動(dòng)伸縮
可能你最想用以指導(dǎo)自動(dòng)伸縮的度量就是pod中進(jìn)程的CPU使用率了。 假設(shè)你用幾個(gè)pod來提供服務(wù), 如果它們的CPU使用率達(dá)到了100%, 顯然它們已經(jīng)扛不住壓力了, 要么進(jìn)行縱向擴(kuò)容(scale up), 增加它們可用的CPU時(shí)間, 要么進(jìn)行橫向擴(kuò)容(scale out), 增加pod 數(shù)量 。 因?yàn)楸菊抡務(wù)摰氖荋PA, 我們僅僅關(guān)注橫向擴(kuò)容。
這么一來, 平均CPU使用率就應(yīng)該下降了。因?yàn)镃PU使用通常是不穩(wěn)定的, 比較靠譜的做法是在CPU被壓垮之前就橫向擴(kuò)容一—可能平均負(fù)載達(dá)到或超過80%的時(shí)候就進(jìn)行擴(kuò)容。 但這里有個(gè)問題, 到底是誰的80%呢。
?
就 Autoscaler而言, 只有pod的保證CPU用量(CPU請(qǐng)求)才與確認(rèn)pod的CPU使用有關(guān)。 Autoscaler對(duì)比pod的實(shí)際CPU使用與它的請(qǐng)求, 這意味著你需要給被伸縮的pod設(shè)置CPU請(qǐng)求,不管是直接設(shè)置還是通過LimitRange對(duì)象間接設(shè)置,這樣Autoscaler才能確定CPU使用率。
基于CPU使用率創(chuàng)建HPA
?
?
創(chuàng)建deployment 資源 apiVersion: extensions/vlbetal kind: Deployment metadata:name: kubia spec: replicas: 3 #手動(dòng)設(shè)置(初始)想要的副本數(shù)為3template: metadata:name: kubia labels: app: kubia spec: containers: - image: luksa/kubia:vl name: nodejs resources: requests: cpu: 100m #每個(gè)pod請(qǐng)求100毫核的CPU創(chuàng)建了Deployment之后, 為了給它的pod 啟用橫向自動(dòng)伸縮 , 需要?jiǎng)?chuàng)建一個(gè) HorizontalpodAutoscaler (HPA)對(duì)象, 并把它指向該Deployment。$ kubectl autoscale deploymen七kubia --cpu-percent=30 --min=l --max=5這會(huì)幫你創(chuàng)建 HPA對(duì)象,并將叫作kubia的Deployment設(shè)置為伸縮目標(biāo)。你還設(shè)置了pod的目標(biāo) CPU使用率為30%, 指定了副本的最小和最大數(shù)量。Autoscaler會(huì)持續(xù)調(diào)整副本的數(shù)量 以使CPU使用率接近30%, 但它永遠(yuǎn)不會(huì)調(diào)整到少于1個(gè)或者多于5個(gè)。提示:一定要確保自動(dòng)伸縮的目標(biāo)是Deployinent 而不是底層的 ReplicaSet。 這樣才能確保預(yù)期的副本數(shù)量在應(yīng)用更新后繼續(xù)保持(記著 Deployment 會(huì)給每個(gè)應(yīng)用版本創(chuàng)建一個(gè) 新的 ReplicaSet)。 手動(dòng)伸縮也是同樣的道理。
修改一個(gè)已有 HPA 對(duì)象的目標(biāo)度量值?
?可能你 開始設(shè)置的目標(biāo)值30 有點(diǎn)太低了,我們把它提高到 你將使用 kubectl edit 命令來完成這項(xiàng)工作。文本編輯器打開之后,把 targetAverageUtilization 字段改為 60,
正如大多數(shù)其他資源 樣,在你修改資源之后, Autosca er 控制器會(huì)檢測到這一變更,并執(zhí)行相應(yīng)動(dòng)作 也可以先刪除 HPA 資源再用新的值創(chuàng)建一個(gè),因?yàn)閯h除HPA 資源只會(huì)禁用目標(biāo)資源的自動(dòng)伸縮(本例中為 Deployment ,而它的伸縮規(guī)模會(huì)保持在刪除資源的時(shí)刻 在你為 Deployment 創(chuàng)建一個(gè)新的 HPA 資源之后,自動(dòng)伸縮過程就會(huì)繼續(xù)進(jìn)行
伸縮操作的最大速率
因?yàn)?Autosca 在單次擴(kuò)容操作中可增加的副本數(shù)受到限制。如果當(dāng)前副本數(shù)大于 2,Autoscaler 單次操作至多使副本數(shù)翻倍;如果副本數(shù)只有 2, Autoscaler 最多擴(kuò)容到4個(gè)副
另外 Autoscaler 兩次擴(kuò)容操作之間的時(shí)間間隔是有限制。目前,只有當(dāng)3鐘內(nèi)沒有任何伸縮操作時(shí)才會(huì)觸發(fā)擴(kuò)容,縮容操作頻率更低一- 5分鐘 記住這點(diǎn),這樣你再看到度量數(shù)據(jù)很明顯應(yīng)該觸發(fā)伸縮卻沒有觸發(fā)的時(shí)候,就不會(huì)感到奇怪了。
基于內(nèi)存使用進(jìn)行自動(dòng)伸縮
基于內(nèi)存的自動(dòng)伸縮比基于CPU 困難很多, 主要原因在于,擴(kuò)容之后原有的pod 需要有辦法釋放內(nèi)存。這只能由應(yīng)用完成,系統(tǒng)無法代勞,系統(tǒng)所能做的只有殺死并重啟應(yīng)用,希望它能比之前少占用 些內(nèi)存;但如果應(yīng)用使用了跟之前多的內(nèi)存 Autoscaler 就會(huì)擴(kuò)容、擴(kuò)容 再擴(kuò)容到達(dá)到HPA資源上配置的最大pod 數(shù)量,顯然沒有人想要這種行為。基于內(nèi)存使用的自動(dòng)伸縮在 Kubernetes 1.8 中得到支持,配置方法與基于 CPU 的自動(dòng)伸縮完全相同 。
?
基于其他自定義度量進(jìn)行自動(dòng)伸縮
?
?
... spec: maxReplicas: 5 metrics: - type: Resourceresource: name: cputargetAverageUtilization:30 ...如上所示, metrics 字段允許你定義多個(gè)度量供使用。在代碼清單中使用了單個(gè)度量。每個(gè)條目都指定相應(yīng)度量的類型一一本例中為一個(gè) Resource 度量。可以在HPA 對(duì)象中使用三種度量:
? 定義 metric 類型
?使用情況會(huì)被監(jiān)控的資源
?資源的 目標(biāo)使用量
Resurce 量類型
Resource 類型使 autoscaler 基于一個(gè)資源度量做出自動(dòng)伸縮決策,在容器的資源請(qǐng)求中指定的那些度量即為一例 。這一類型的使用方式我們己經(jīng)看過了,所以重點(diǎn)關(guān)注另外兩種類型。
?
pods 度量類型
Pods 類型用來引用任何其他種類的(包括自定義的)與 pod 直接相關(guān)的度量。每秒查詢次數(shù) CQPS ),或者消息隊(duì)列中的消息數(shù)量(當(dāng)消息隊(duì)列服務(wù)運(yùn)行在 pod 之中 )都屬于這種度量。要配置autoscaler 使用 pod QPS 度量, HPA 對(duì)象的 metrics 字段中就需要包含以下代碼清單所示的條目。
?
?
... spec: metrics: - type: Podsresource: metricName: qpstargetAverageValue:100 ...
代碼清單中的示例配置 Autoscaler ,使該 HPA 控制的 ReplicaSet (或其他)控制器下所轄 pod 的平均 QPS 維持 100 的水平。
Object 度量類型
Object 類型被用來讓 Autoscaler 基于并非直接與 pod 關(guān)聯(lián)的度量來進(jìn)行伸縮,比方說,你可能希望基于另一集群對(duì)象 ,比如 Ingress 對(duì)象來伸縮你的?pod。 這度量可能是代碼清單 15.8 中的 QPS ,也可能是平均請(qǐng)求延遲,或者完全是不相干的其他東西。與此前的例子不同,使用 object 度量類型時(shí), Autoscaler 只會(huì)從這單個(gè)對(duì)象中獲取單個(gè)度量數(shù)據(jù);在此前的例子中, Autoscaler 需要從所有下屬 pod 中獲取度量,并使用它們的平均值。你需要在HPA對(duì)象的定義中指定目標(biāo)對(duì)象與目標(biāo)值。如下所示:
?
?View Code該例中 HPA 被配置為使用 Ingress 對(duì)象 frontend 的 latencyMillis 度量,目標(biāo)值為 20 。HPA 會(huì)監(jiān)控該 Ingress 度量,如果該度量超過了目標(biāo)值太多autoscaler 便會(huì)對(duì) kubia Deployment 資源進(jìn)行擴(kuò)容了。
確定哪些度量適合用于自動(dòng)伸縮
不是所有度量都適合作為自動(dòng)伸縮的基礎(chǔ)。正如之前提到的, pod?中容器的內(nèi)存占用并不是自動(dòng)伸縮的一個(gè)好度量。如果增加副本數(shù)不能導(dǎo)致被觀測度量平均值的線性(或者至少接近線性)下降 ,那么 autoscaler 就不能正常工作比方說,如果你只有 pod 實(shí)例,度量數(shù)值為 X,這時(shí) autoscaler 擴(kuò)容到了2個(gè)副本,度量數(shù)值就需要落在接近 X/2 位置 每秒查詢次數(shù) QPS )就是這么一種自定義度量,對(duì) we 應(yīng)用而 即為應(yīng)用每秒接收的請(qǐng)求數(shù)。增大副本數(shù)總會(huì)導(dǎo)致QPS 成比例下降,因?yàn)橥瑯佣嗟恼?qǐng)求數(shù)現(xiàn)在被更多數(shù)量的 pod 處理了。在你決定基于應(yīng)用自有的自定義度量來伸縮它之前,一定要思考 pod 數(shù)量增加或減少時(shí),它的值會(huì)如何變化。?
?
縮容到0個(gè)副本
HPA 目前不允許設(shè)置 minReplicas 字段為0 ,所以 autoscaler 永遠(yuǎn)不會(huì)縮容到0個(gè)副本,即便 pod 什么都沒做也不會(huì)。允許 pod 數(shù)量縮容到0可以大幅提升硬件利用率:如果你運(yùn)行的服幾個(gè)小時(shí)甚至幾天才會(huì)收到1次請(qǐng)求,就沒有道理留著它們一直運(yùn)行,占用本來可以給其他服務(wù)利用的資源:然而一旦客戶端請(qǐng)求進(jìn)來了,你仍然還想讓這些服務(wù)馬上可用。
這叫空載( idling )與解除空載 (un-idling ),即允許提供特定服務(wù)的 pod 被縮容量到0 副本。在新的請(qǐng)求到來時(shí),請(qǐng)求會(huì)先被阻塞,直到 pod 被啟動(dòng),從而請(qǐng)求被轉(zhuǎn)發(fā)到新的 pod 為止。Kubernetes 目前暫時(shí)沒有提供這個(gè)特性,但在未來會(huì)實(shí)現(xiàn)。可 以檢查 Kubernetes?文檔來看看空載特性有沒有被實(shí)現(xiàn)。
??
pod 的縱向自動(dòng)伸縮
橫向伸縮很棒,但并不是所有應(yīng)用都能被橫向伸縮,對(duì)這些應(yīng)用而言,唯一選項(xiàng)是縱向伸縮一-給它們更多 CPU 和(或)內(nèi)存。因?yàn)槊總€(gè)節(jié)點(diǎn)所擁有的資源通常都比單個(gè) pod 請(qǐng)求的要多 ,我們應(yīng)該幾乎總能縱向擴(kuò)容 pod ,因?yàn)?pod 的資源請(qǐng)求是通過 pod manifest 的字段配置的,縱向伸縮 pod 將會(huì)通過改變這些字段來實(shí)現(xiàn)。筆者這里說的是“將會(huì)”,因?yàn)槟壳斑€不可能改變己有 pod的資源請(qǐng)求和限制, 在筆者動(dòng)筆之前(已經(jīng)是一年多之前了),請(qǐng)參考Kubemetes文檔來檢查縱向pod自動(dòng)伸縮實(shí)現(xiàn)了沒有。
集群節(jié)點(diǎn)的橫向伸縮
HPA在需要的時(shí)候會(huì)創(chuàng)建更多的pod實(shí)例。 但萬一所有的節(jié)點(diǎn)都滿了, 放不下更多pod了, 怎么辦?顯然這個(gè)問題并不局限于Autoscaler創(chuàng)建新pod實(shí)例的場景。即便是手動(dòng)創(chuàng)建pod, 也可能碰到因?yàn)橘Y源被已有pod使用殆盡, 以至于沒有節(jié)點(diǎn)能接收新pod的清況。?
Kubernetes支持在需要時(shí)立即自動(dòng)從云服務(wù)提供者請(qǐng)求更多節(jié)點(diǎn)。 該特性由?Cluster Autoscaler執(zhí)行。
?
Cluster Autoscaler介紹
Cluster Autoscaler負(fù)責(zé)在由于節(jié)點(diǎn)資源不足, 而無法調(diào)度某pod到已有節(jié)點(diǎn)時(shí),自動(dòng)部署新節(jié)點(diǎn)。它也會(huì)在 節(jié)點(diǎn)長時(shí)間使用率低下的情況下下線節(jié)點(diǎn)。?
?從云端基礎(chǔ)架構(gòu)請(qǐng)求新節(jié)點(diǎn)
如果在 一個(gè)pod被創(chuàng)建之后,Scheduler無法將其調(diào)度到任何一個(gè)已有 節(jié)點(diǎn),一個(gè)新節(jié)點(diǎn)就會(huì)被創(chuàng)建。ClusterAutoscaler會(huì)注意此類pod, 并請(qǐng)求云服務(wù)提供者啟動(dòng) 一個(gè)新節(jié)點(diǎn)。但在這么做之前,它會(huì)檢查新節(jié)點(diǎn)有沒有可能容納這個(gè)(些) pod,畢竟如果 新節(jié)點(diǎn)本來就不可能容納它們,就沒必要啟動(dòng)這么一個(gè)節(jié)點(diǎn)了。
?
云服務(wù)提供者通常把相同規(guī)格(或者有相同特性)的節(jié)點(diǎn)聚合成組。因此Cluster Autoscaler不能單純地說 “給我多一個(gè)節(jié)點(diǎn)”,它還需要指明節(jié)點(diǎn)類型。Cluster Autoscaler 通過檢查可用的節(jié)點(diǎn)分組來確定是否有至少一種節(jié)點(diǎn)類型能容納未被調(diào)度的pod。如果只存在唯一一個(gè)此種節(jié)點(diǎn)分組,ClusterAutoscaler就可以增加節(jié)點(diǎn)分組的大小,讓云服務(wù)提供商給分組中增加一個(gè)節(jié)點(diǎn)。但如果存在多個(gè)滿足條件的節(jié)點(diǎn)分組,ClusterAutoscaler就必須挑一個(gè)最合適的。這里 “ 最合適” 的精確含義顯然必須是可配置的。在 最壞的情況下,它會(huì)隨機(jī)挑選一個(gè)。
新節(jié)點(diǎn)啟動(dòng)后,其上運(yùn)行的Kubelet會(huì)聯(lián)系A(chǔ)PI服務(wù)器,創(chuàng)建一個(gè)Node資源以注冊(cè)該節(jié)點(diǎn)。從這一刻起,該節(jié)點(diǎn)即成為Kubernetes集群的一部分,可 以調(diào)度pod于其上了。
歸還節(jié)點(diǎn)
當(dāng)節(jié)點(diǎn)利用率不足時(shí), Cluster Autoscaler 也需要能夠減少節(jié)點(diǎn)的數(shù)目。 Cluster?Autoscaler 通過監(jiān)控所有節(jié)點(diǎn)上請(qǐng)求的CPU 與內(nèi)存來實(shí)現(xiàn)這一點(diǎn)。 如果某個(gè)節(jié)點(diǎn)上
所有pod請(qǐng)求的CPU、 內(nèi)存都不 到 50%, 該節(jié)點(diǎn)即被認(rèn)定 為不再需要。這并不是決定是否要?dú)w還某 一 節(jié)點(diǎn)的唯一因素。 Cluster Autoscaler 也會(huì)檢查是否有系統(tǒng) pod (僅僅)運(yùn)行在該節(jié)點(diǎn)上(這并不包括每個(gè)節(jié)點(diǎn)上都運(yùn)行的服務(wù), 比如 DaemonSet所部署的服務(wù))。 如果節(jié)點(diǎn)上有系統(tǒng) pod 在運(yùn)行,該節(jié)點(diǎn)就不會(huì)被歸還。
?
對(duì)非托管 pod, 以及有本地存儲(chǔ)的pod 也是如此, 否則就會(huì)造成這些 pod 提供的服務(wù)中斷。 換句話說, 只有當(dāng) Cluster Autoscaler 知道節(jié)點(diǎn)上運(yùn)行的pod 能夠重新調(diào)度到其他節(jié)點(diǎn), 該節(jié)點(diǎn)才會(huì)被 歸還。
?
當(dāng)一個(gè)節(jié)點(diǎn)被選中下線, 它首先會(huì)被標(biāo)記為不可調(diào)度, 隨后運(yùn)行其上的pod 將被疏散至其他節(jié)點(diǎn)。 因?yàn)樗羞@些 pod 都屬于 ReplicaSet 或者其他控制器, 它們的替代 pod會(huì)被創(chuàng)建并調(diào)度到其他剩下的節(jié)點(diǎn)(這就是為何正被下線的節(jié)點(diǎn)要先標(biāo)記為不可調(diào)度的原因)。?
?
手動(dòng)標(biāo)記節(jié)點(diǎn)為不可調(diào)度、 排空節(jié)點(diǎn)?
?
節(jié)點(diǎn)也可以手動(dòng)被標(biāo)記為不可調(diào)度并排空。 不涉及細(xì)節(jié), 這些工作可用以下 kubectl 命令完成:? kubectl cordon <node> 標(biāo)記節(jié)點(diǎn)為不可調(diào)度(但對(duì)其上的 pod不做任何事)。 ? kubectl drain <node> 標(biāo)記節(jié)點(diǎn)為不可調(diào)度, 隨后疏散其上所有pod。兩種情形下, 在你用 kubectl uncordon <node> 解除節(jié)點(diǎn)的不可調(diào)度狀態(tài)之前, 不會(huì)有新 pod被調(diào)度到該節(jié)點(diǎn)。限制集群縮容時(shí)的服務(wù)干擾?
如果 一個(gè)節(jié)點(diǎn)發(fā)生非預(yù)期故障, 你不可能阻止其上的pod變?yōu)椴豢捎?#xff1b;但如果一個(gè)節(jié)點(diǎn)被Cluster Autoscaler或者人類操作員主動(dòng)下線,可以用一個(gè)新特性來確保下線操作不會(huì)干擾到這個(gè)節(jié)點(diǎn)上pod所提供的服務(wù)。一些服務(wù)要求至少保持一定數(shù)量的pod持續(xù)運(yùn)行 , 對(duì)基于quorum的集群應(yīng)用而言尤其如此。 為此, Kubemetes可以指定 下線等操作時(shí)需要保待的最少 pod數(shù)量,我們通過創(chuàng)建一個(gè)podDisruptionBudget資源的方式來利用這一特性。盡管這個(gè)資源的名稱聽起來挺復(fù)雜的, 實(shí)際上 它是最簡單的Kubemetes資源
之一 。 它只包含 一個(gè)pod 標(biāo)簽選擇器和 一個(gè)數(shù)字, 指定 最少需要維持運(yùn)行的podYAML文件。
如果想確保你的kubiapod總有3個(gè)實(shí)例在運(yùn)行(它們有 app=kubia這個(gè)標(biāo)簽), 像這樣創(chuàng)建PodDisruptionBudget資源 :
?
?
$ kubectl create pdb kubia-pdb --selector=app=kubia --min-available=3 poddisruptionbudget "kubia-pdb" created現(xiàn)在獲取這個(gè)pod 的YAML文件, 如以下代碼清單所示。
也可以用 一個(gè)百分比而非絕對(duì)數(shù)值來寫minAvailable字段。 比方說,可以指定60%帶app=kubia標(biāo)簽的pod應(yīng)當(dāng)時(shí)刻保持運(yùn)行。注意從Kubemetes 1. 7開始podDismptionBudget資源也支持maxUnavailable。如果當(dāng)很多pod不可用而想要阻止pod被剔除時(shí),就可以用maxUnavailable字段而不是minAvailable。
關(guān)于這個(gè)資源, 沒有更多要講的了。 只 要它存在 ,Cluster Autoscaler與?kubectl drain 命令都會(huì)遵守它;如果疏散一個(gè)帶有app=kubia標(biāo)簽的pod會(huì)導(dǎo)致它們的總數(shù)小于3, 那這個(gè)操作就永遠(yuǎn)不會(huì)被執(zhí)行。比方說,如果總共有4個(gè)pod, minAvailable像例子中 一 樣被設(shè)為3, pod?疏散過程就會(huì)挨個(gè)進(jìn)行,待ReplicaSet控制器把被疏散的pod換成新的,才繼續(xù)下一個(gè)。
?
簡述
我們可以通過調(diào)高ReplicationController、 ReplicaSet、 Deployment等可伸縮資源的rep讓cas字段, 來手動(dòng)實(shí)現(xiàn)pod中應(yīng)用的橫向擴(kuò)容。 我們也可以通過增加pod容器的資源請(qǐng)求和限制來縱向擴(kuò)容pod (盡管目前該操作只能在pod創(chuàng)建時(shí), 而非運(yùn)行時(shí)進(jìn)行)。 雖然如果你能預(yù)先知道負(fù)載何時(shí)會(huì)飄升, 或者如果負(fù)載的變化是較長時(shí)間內(nèi)逐漸發(fā)生的, 手動(dòng)擴(kuò)容也是可以接受的, 但指望靠人工干預(yù)來處理突發(fā)而不可預(yù)測的流量增長, 仍然不夠理想。
Kubemetes可以監(jiān)控你的pod, 并在檢測到CPU使用率或其他度量增長時(shí)自動(dòng)對(duì)它們擴(kuò)容。 如果Kubemetes運(yùn)行在云端基礎(chǔ)架構(gòu)之上, 它甚至能在現(xiàn)有節(jié)點(diǎn)無法承載更多pod之時(shí)自動(dòng)新建更多節(jié)點(diǎn)。
pod的橫向自動(dòng)伸縮
橫向pod自動(dòng)伸縮是指由控制器管理 的pod副本數(shù)量的自動(dòng)伸 縮。 它由Horizontal控制器執(zhí)行, 我們通過創(chuàng)建 一個(gè)HorizontalpodAutoscaler C HPA)資源來啟用和配置Horizontal控制器。 該控制器周期性檢查pod度量, 計(jì)算滿足HPA資源所配置的目標(biāo)數(shù)值所需的副本數(shù)量, 進(jìn)而調(diào)整目標(biāo)資源(如Deployment、ReplicaSet、 ReplicationController、StatefulSet等)的replicas字段。
自動(dòng)伸縮過程
自動(dòng)伸縮的過程可以分為三個(gè)步驟:
? 獲取被伸縮資源對(duì)象所管理的所有pod度量。
? 計(jì)算使度量數(shù)值到達(dá)(或接近)所指定目標(biāo)數(shù)值所需的pod數(shù)量。
? 更新被伸縮資源的replicas字段。?
下面我們就來看看這三個(gè)步驟。
獲取pod度量?
Autoscaler本身并不負(fù)責(zé)采集pod度量數(shù)據(jù) , 而是從另外的來源獲取。 正如之前提到的, pod與節(jié)點(diǎn)度量數(shù)據(jù)是由運(yùn)行在每個(gè)節(jié)點(diǎn)的kubelet之上, 名為cAdvisor的agent采集的;這些數(shù)據(jù)將由 集群級(jí)的組件Heapster聚合。 HPA控制器向Heapster 發(fā)起REST調(diào)用來獲取 所有pod度量數(shù)據(jù)。?
計(jì)算所需的 pod 數(shù)量
一 旦Autoscaler獲得了它所調(diào)整的資源(Deployment、 ReplicaSet、ReplicationController或State伈!Set)所轄pod的全部度量, 它便可以利用這些度量計(jì)算出所需的副本數(shù)量。 它需要計(jì)算出一個(gè)合適的副本數(shù)量, 以使所有副本上度量的平均值盡量接近配置的目標(biāo)值。 該計(jì)算的輸入是一組pod度量(每個(gè)pod可能有多個(gè)), 輸出則是一個(gè)整數(shù)(pod副本數(shù)量)。
當(dāng)Autoscaler配置為只考慮單個(gè)度量時(shí), 計(jì)算所需 副本數(shù)很簡單。 只要將所有pod的度量求和后除以HPA資源上配置的目標(biāo)值, 再向上取整即可。 實(shí)際的計(jì)算稍微復(fù)雜一些; Autoscaler還保證了度量數(shù)值不穩(wěn)定、 迅速抖動(dòng)時(shí)不會(huì)導(dǎo)致系統(tǒng)抖動(dòng)(thrash)。
基于多個(gè)pod度量的自動(dòng)伸縮(例如: CPU使用率和每秒查詢率[QPS])的計(jì)算也并不復(fù)雜。 Autoscaler單獨(dú)計(jì)算每個(gè)度量的副本數(shù), 然后取最大值(例如:如果需要4個(gè)pod達(dá)到目標(biāo)CPU使用率, 以及需要3個(gè)pod來達(dá)到目標(biāo)QPS, 那么Autoscaler 將擴(kuò)展到4個(gè)pod)。 下圖展示了這個(gè)示例。
更新被伸縮資源的副本數(shù)
自動(dòng)伸縮操作的最后 一 步是更新被伸縮資源對(duì)象(比如ReplicaSet)上的副本數(shù)字段 然后讓ReplicaSet控制器負(fù)責(zé)啟動(dòng)更多pod或者刪除多余的pod。Autoscaler控制器通過scale子資源來修改被伸縮資源的rep巨cas字段。 這樣Autoscaler不必了解它所管理資源的細(xì)節(jié),而只需要通過Scale子資源暴露的界面,就可以完成它的工作了,如下圖
HPA只對(duì)Scale子資源進(jìn)行更改 。
這意味著只要API服務(wù)器為某個(gè)可伸縮資源暴露了Scale子資源, Autoscaler即可操作該資源。 目前暴露了Scale子資源的資源有:?
?View Code
了解整個(gè)自動(dòng)伸縮過程
從pod指向 cAdvisor, 再經(jīng)過Heapster , 而最終到達(dá)HPA的箭頭代表度量數(shù)據(jù)的流向。 值得注意的是, 每個(gè)組件從其他組件拉取數(shù)據(jù)的動(dòng)作是周期性的 (即cAdvisor用 一個(gè)無限循環(huán)從pod中采集數(shù)據(jù); Heapster與HPA控制器亦是如此)。這意味著度量數(shù)據(jù)的傳播與相應(yīng)動(dòng)作的觸發(fā)都需要相當(dāng)一段時(shí)間, 不是立即發(fā)生的。接下來實(shí)地觀察Autoscaler行為時(shí)要注意這一點(diǎn)。?
基于CPU使用率進(jìn)行自動(dòng)伸縮
可能你最想用以指導(dǎo)自動(dòng)伸縮的度量就是pod中進(jìn)程的CPU使用率了。 假設(shè)你用幾個(gè)pod來提供服務(wù), 如果它們的CPU使用率達(dá)到了100%, 顯然它們已經(jīng)扛不住壓力了, 要么進(jìn)行縱向擴(kuò)容(scale up), 增加它們可用的CPU時(shí)間, 要么進(jìn)行橫向擴(kuò)容(scale out), 增加pod 數(shù)量 。 因?yàn)楸菊抡務(wù)摰氖荋PA, 我們僅僅關(guān)注橫向擴(kuò)容。
這么一來, 平均CPU使用率就應(yīng)該下降了。因?yàn)镃PU使用通常是不穩(wěn)定的, 比較靠譜的做法是在CPU被壓垮之前就橫向擴(kuò)容一—可能平均負(fù)載達(dá)到或超過80%的時(shí)候就進(jìn)行擴(kuò)容。 但這里有個(gè)問題, 到底是誰的80%呢。
就 Autoscaler而言, 只有pod的保證CPU用量(CPU請(qǐng)求)才與確認(rèn)pod的CPU使用有關(guān)。 Autoscaler對(duì)比pod的實(shí)際CPU使用與它的請(qǐng)求, 這意味著你需要給被伸縮的pod設(shè)置CPU請(qǐng)求,不管是直接設(shè)置還是通過LimitRange對(duì)象間接設(shè)置,這樣Autoscaler才能確定CPU使用率。
基于CPU使用率創(chuàng)建HPA
創(chuàng)建deployment 資源 apiVersion: extensions/vlbetal kind: Deployment metadata:name: kubia spec: replicas: 3 #手動(dòng)設(shè)置(初始)想要的副本數(shù)為3template: metadata:name: kubia labels: app: kubia spec: containers: - image: luksa/kubia:vl name: nodejs resources: requests: cpu: 100m #每個(gè)pod請(qǐng)求100毫核的CPU創(chuàng)建了Deployment之后, 為了給它的pod 啟用橫向自動(dòng)伸縮 , 需要?jiǎng)?chuàng)建一個(gè) HorizontalpodAutoscaler (HPA)對(duì)象, 并把它指向該Deployment。$ kubectl autoscale deploymen七kubia --cpu-percent=30 --min=l --max=5這會(huì)幫你創(chuàng)建 HPA對(duì)象,并將叫作kubia的Deployment設(shè)置為伸縮目標(biāo)。你還設(shè)置了pod的目標(biāo) CPU使用率為30%, 指定了副本的最小和最大數(shù)量。Autoscaler會(huì)持續(xù)調(diào)整副本的數(shù)量 以使CPU使用率接近30%, 但它永遠(yuǎn)不會(huì)調(diào)整到少于1個(gè)或者多于5個(gè)。提示:一定要確保自動(dòng)伸縮的目標(biāo)是Deployinent 而不是底層的 ReplicaSet。 這樣才能確保預(yù)期的副本數(shù)量在應(yīng)用更新后繼續(xù)保持(記著 Deployment 會(huì)給每個(gè)應(yīng)用版本創(chuàng)建一個(gè) 新的 ReplicaSet)。 手動(dòng)伸縮也是同樣的道理。修改一個(gè)已有 HPA 對(duì)象的目標(biāo)度量值?
?可能你 開始設(shè)置的目標(biāo)值30 有點(diǎn)太低了,我們把它提高到 你將使用 kubectl edit 命令來完成這項(xiàng)工作。文本編輯器打開之后,把 targetAverageUtilization 字段改為 60,
正如大多數(shù)其他資源 樣,在你修改資源之后, Autosca er 控制器會(huì)檢測到這一變更,并執(zhí)行相應(yīng)動(dòng)作 也可以先刪除 HPA 資源再用新的值創(chuàng)建一個(gè),因?yàn)閯h除HPA 資源只會(huì)禁用目標(biāo)資源的自動(dòng)伸縮(本例中為 Deployment ,而它的伸縮規(guī)模會(huì)保持在刪除資源的時(shí)刻 在你為 Deployment 創(chuàng)建一個(gè)新的 HPA 資源之后,自動(dòng)伸縮過程就會(huì)繼續(xù)進(jìn)行
伸縮操作的最大速率
因?yàn)?Autosca 在單次擴(kuò)容操作中可增加的副本數(shù)受到限制。如果當(dāng)前副本數(shù)大于 2,Autoscaler 單次操作至多使副本數(shù)翻倍;如果副本數(shù)只有 2, Autoscaler 最多擴(kuò)容到4個(gè)副
另外 Autoscaler 兩次擴(kuò)容操作之間的時(shí)間間隔是有限制。目前,只有當(dāng)3鐘內(nèi)沒有任何伸縮操作時(shí)才會(huì)觸發(fā)擴(kuò)容,縮容操作頻率更低一- 5分鐘 記住這點(diǎn),這樣你再看到度量數(shù)據(jù)很明顯應(yīng)該觸發(fā)伸縮卻沒有觸發(fā)的時(shí)候,就不會(huì)感到奇怪了。
基于內(nèi)存使用進(jìn)行自動(dòng)伸縮
基于內(nèi)存的自動(dòng)伸縮比基于CPU 困難很多, 主要原因在于,擴(kuò)容之后原有的pod 需要有辦法釋放內(nèi)存。這只能由應(yīng)用完成,系統(tǒng)無法代勞,系統(tǒng)所能做的只有殺死并重啟應(yīng)用,希望它能比之前少占用 些內(nèi)存;但如果應(yīng)用使用了跟之前多的內(nèi)存 Autoscaler 就會(huì)擴(kuò)容、擴(kuò)容 再擴(kuò)容到達(dá)到HPA資源上配置的最大pod 數(shù)量,顯然沒有人想要這種行為。基于內(nèi)存使用的自動(dòng)伸縮在 Kubernetes 1.8 中得到支持,配置方法與基于 CPU 的自動(dòng)伸縮完全相同 。
基于其他自定義度量進(jìn)行自動(dòng)伸縮
... spec: maxReplicas: 5 metrics: - type: Resourceresource: name: cputargetAverageUtilization:30 ...如上所示, metrics 字段允許你定義多個(gè)度量供使用。在代碼清單中使用了單個(gè)度量。每個(gè)條目都指定相應(yīng)度量的類型一一本例中為一個(gè) Resource 度量。可以在HPA 對(duì)象中使用三種度量:
? 定義 metric 類型
?使用情況會(huì)被監(jiān)控的資源
?資源的 目標(biāo)使用量
Resurce 量類型
Resource 類型使 autoscaler 基于一個(gè)資源度量做出自動(dòng)伸縮決策,在容器的資源請(qǐng)求中指定的那些度量即為一例 。這一類型的使用方式我們己經(jīng)看過了,所以重點(diǎn)關(guān)注另外兩種類型。
pods 度量類型
Pods 類型用來引用任何其他種類的(包括自定義的)與 pod 直接相關(guān)的度量。每秒查詢次數(shù) CQPS ),或者消息隊(duì)列中的消息數(shù)量(當(dāng)消息隊(duì)列服務(wù)運(yùn)行在 pod 之中 )都屬于這種度量。要配置autoscaler 使用 pod QPS 度量, HPA 對(duì)象的 metrics 字段中就需要包含以下代碼清單所示的條目。
... spec: metrics: - type: Podsresource: metricName: qpstargetAverageValue:100 ...代碼清單中的示例配置 Autoscaler ,使該 HPA 控制的 ReplicaSet (或其他)控制器下所轄 pod 的平均 QPS 維持 100 的水平。
Object 度量類型
Object 類型被用來讓 Autoscaler 基于并非直接與 pod 關(guān)聯(lián)的度量來進(jìn)行伸縮,比方說,你可能希望基于另一集群對(duì)象 ,比如 Ingress 對(duì)象來伸縮你的?pod。 這度量可能是代碼清單 15.8 中的 QPS ,也可能是平均請(qǐng)求延遲,或者完全是不相干的其他東西。與此前的例子不同,使用 object 度量類型時(shí), Autoscaler 只會(huì)從這單個(gè)對(duì)象中獲取單個(gè)度量數(shù)據(jù);在此前的例子中, Autoscaler 需要從所有下屬 pod 中獲取度量,并使用它們的平均值。你需要在HPA對(duì)象的定義中指定目標(biāo)對(duì)象與目標(biāo)值。如下所示:
?View Code
該例中 HPA 被配置為使用 Ingress 對(duì)象 frontend 的 latencyMillis 度量,目標(biāo)值為 20 。HPA 會(huì)監(jiān)控該 Ingress 度量,如果該度量超過了目標(biāo)值太多autoscaler 便會(huì)對(duì) kubia Deployment 資源進(jìn)行擴(kuò)容了。
確定哪些度量適合用于自動(dòng)伸縮
不是所有度量都適合作為自動(dòng)伸縮的基礎(chǔ)。正如之前提到的, pod?中容器的內(nèi)存占用并不是自動(dòng)伸縮的一個(gè)好度量。如果增加副本數(shù)不能導(dǎo)致被觀測度量平均值的線性(或者至少接近線性)下降 ,那么 autoscaler 就不能正常工作比方說,如果你只有 pod 實(shí)例,度量數(shù)值為 X,這時(shí) autoscaler 擴(kuò)容到了2個(gè)副本,度量數(shù)值就需要落在接近 X/2 位置 每秒查詢次數(shù) QPS )就是這么一種自定義度量,對(duì) we 應(yīng)用而 即為應(yīng)用每秒接收的請(qǐng)求數(shù)。增大副本數(shù)總會(huì)導(dǎo)致QPS 成比例下降,因?yàn)橥瑯佣嗟恼?qǐng)求數(shù)現(xiàn)在被更多數(shù)量的 pod 處理了。在你決定基于應(yīng)用自有的自定義度量來伸縮它之前,一定要思考 pod 數(shù)量增加或減少時(shí),它的值會(huì)如何變化。?
縮容到0個(gè)副本
HPA 目前不允許設(shè)置 minReplicas 字段為0 ,所以 autoscaler 永遠(yuǎn)不會(huì)縮容到0個(gè)副本,即便 pod 什么都沒做也不會(huì)。允許 pod 數(shù)量縮容到0可以大幅提升硬件利用率:如果你運(yùn)行的服幾個(gè)小時(shí)甚至幾天才會(huì)收到1次請(qǐng)求,就沒有道理留著它們一直運(yùn)行,占用本來可以給其他服務(wù)利用的資源:然而一旦客戶端請(qǐng)求進(jìn)來了,你仍然還想讓這些服務(wù)馬上可用。
這叫空載( idling )與解除空載 (un-idling ),即允許提供特定服務(wù)的 pod 被縮容量到0 副本。在新的請(qǐng)求到來時(shí),請(qǐng)求會(huì)先被阻塞,直到 pod 被啟動(dòng),從而請(qǐng)求被轉(zhuǎn)發(fā)到新的 pod 為止。Kubernetes 目前暫時(shí)沒有提供這個(gè)特性,但在未來會(huì)實(shí)現(xiàn)。可 以檢查 Kubernetes?文檔來看看空載特性有沒有被實(shí)現(xiàn)。
??
pod 的縱向自動(dòng)伸縮
橫向伸縮很棒,但并不是所有應(yīng)用都能被橫向伸縮,對(duì)這些應(yīng)用而言,唯一選項(xiàng)是縱向伸縮一-給它們更多 CPU 和(或)內(nèi)存。因?yàn)槊總€(gè)節(jié)點(diǎn)所擁有的資源通常都比單個(gè) pod 請(qǐng)求的要多 ,我們應(yīng)該幾乎總能縱向擴(kuò)容 pod ,因?yàn)?pod 的資源請(qǐng)求是通過 pod manifest 的字段配置的,縱向伸縮 pod 將會(huì)通過改變這些字段來實(shí)現(xiàn)。筆者這里說的是“將會(huì)”,因?yàn)槟壳斑€不可能改變己有 pod的資源請(qǐng)求和限制, 在筆者動(dòng)筆之前(已經(jīng)是一年多之前了),請(qǐng)參考Kubemetes文檔來檢查縱向pod自動(dòng)伸縮實(shí)現(xiàn)了沒有。
集群節(jié)點(diǎn)的橫向伸縮
HPA在需要的時(shí)候會(huì)創(chuàng)建更多的pod實(shí)例。 但萬一所有的節(jié)點(diǎn)都滿了, 放不下更多pod了, 怎么辦?顯然這個(gè)問題并不局限于Autoscaler創(chuàng)建新pod實(shí)例的場景。即便是手動(dòng)創(chuàng)建pod, 也可能碰到因?yàn)橘Y源被已有pod使用殆盡, 以至于沒有節(jié)點(diǎn)能接收新pod的清況。?
Kubernetes支持在需要時(shí)立即自動(dòng)從云服務(wù)提供者請(qǐng)求更多節(jié)點(diǎn)。 該特性由?Cluster Autoscaler執(zhí)行。
Cluster Autoscaler介紹
Cluster Autoscaler負(fù)責(zé)在由于節(jié)點(diǎn)資源不足, 而無法調(diào)度某pod到已有節(jié)點(diǎn)時(shí),自動(dòng)部署新節(jié)點(diǎn)。它也會(huì)在 節(jié)點(diǎn)長時(shí)間使用率低下的情況下下線節(jié)點(diǎn)。?
?從云端基礎(chǔ)架構(gòu)請(qǐng)求新節(jié)點(diǎn)
如果在 一個(gè)pod被創(chuàng)建之后,Scheduler無法將其調(diào)度到任何一個(gè)已有 節(jié)點(diǎn),一個(gè)新節(jié)點(diǎn)就會(huì)被創(chuàng)建。ClusterAutoscaler會(huì)注意此類pod, 并請(qǐng)求云服務(wù)提供者啟動(dòng) 一個(gè)新節(jié)點(diǎn)。但在這么做之前,它會(huì)檢查新節(jié)點(diǎn)有沒有可能容納這個(gè)(些) pod,畢竟如果 新節(jié)點(diǎn)本來就不可能容納它們,就沒必要啟動(dòng)這么一個(gè)節(jié)點(diǎn)了。
云服務(wù)提供者通常把相同規(guī)格(或者有相同特性)的節(jié)點(diǎn)聚合成組。因此Cluster Autoscaler不能單純地說 “給我多一個(gè)節(jié)點(diǎn)”,它還需要指明節(jié)點(diǎn)類型。Cluster Autoscaler 通過檢查可用的節(jié)點(diǎn)分組來確定是否有至少一種節(jié)點(diǎn)類型能容納未被調(diào)度的pod。如果只存在唯一一個(gè)此種節(jié)點(diǎn)分組,ClusterAutoscaler就可以增加節(jié)點(diǎn)分組的大小,讓云服務(wù)提供商給分組中增加一個(gè)節(jié)點(diǎn)。但如果存在多個(gè)滿足條件的節(jié)點(diǎn)分組,ClusterAutoscaler就必須挑一個(gè)最合適的。這里 “ 最合適” 的精確含義顯然必須是可配置的。在 最壞的情況下,它會(huì)隨機(jī)挑選一個(gè)。
新節(jié)點(diǎn)啟動(dòng)后,其上運(yùn)行的Kubelet會(huì)聯(lián)系A(chǔ)PI服務(wù)器,創(chuàng)建一個(gè)Node資源以注冊(cè)該節(jié)點(diǎn)。從這一刻起,該節(jié)點(diǎn)即成為Kubernetes集群的一部分,可 以調(diào)度pod于其上了。
歸還節(jié)點(diǎn)
當(dāng)節(jié)點(diǎn)利用率不足時(shí), Cluster Autoscaler 也需要能夠減少節(jié)點(diǎn)的數(shù)目。 Cluster?Autoscaler 通過監(jiān)控所有節(jié)點(diǎn)上請(qǐng)求的CPU 與內(nèi)存來實(shí)現(xiàn)這一點(diǎn)。 如果某個(gè)節(jié)點(diǎn)上
所有pod請(qǐng)求的CPU、 內(nèi)存都不 到 50%, 該節(jié)點(diǎn)即被認(rèn)定 為不再需要。這并不是決定是否要?dú)w還某 一 節(jié)點(diǎn)的唯一因素。 Cluster Autoscaler 也會(huì)檢查是否有系統(tǒng) pod (僅僅)運(yùn)行在該節(jié)點(diǎn)上(這并不包括每個(gè)節(jié)點(diǎn)上都運(yùn)行的服務(wù), 比如 DaemonSet所部署的服務(wù))。 如果節(jié)點(diǎn)上有系統(tǒng) pod 在運(yùn)行,該節(jié)點(diǎn)就不會(huì)被歸還。
對(duì)非托管 pod, 以及有本地存儲(chǔ)的pod 也是如此, 否則就會(huì)造成這些 pod 提供的服務(wù)中斷。 換句話說, 只有當(dāng) Cluster Autoscaler 知道節(jié)點(diǎn)上運(yùn)行的pod 能夠重新調(diào)度到其他節(jié)點(diǎn), 該節(jié)點(diǎn)才會(huì)被 歸還。
當(dāng)一個(gè)節(jié)點(diǎn)被選中下線, 它首先會(huì)被標(biāo)記為不可調(diào)度, 隨后運(yùn)行其上的pod 將被疏散至其他節(jié)點(diǎn)。 因?yàn)樗羞@些 pod 都屬于 ReplicaSet 或者其他控制器, 它們的替代 pod會(huì)被創(chuàng)建并調(diào)度到其他剩下的節(jié)點(diǎn)(這就是為何正被下線的節(jié)點(diǎn)要先標(biāo)記為不可調(diào)度的原因)。?
手動(dòng)標(biāo)記節(jié)點(diǎn)為不可調(diào)度、 排空節(jié)點(diǎn)?
節(jié)點(diǎn)也可以手動(dòng)被標(biāo)記為不可調(diào)度并排空。 不涉及細(xì)節(jié), 這些工作可用以下 kubectl 命令完成:? kubectl cordon <node> 標(biāo)記節(jié)點(diǎn)為不可調(diào)度(但對(duì)其上的 pod不做任何事)。 ? kubectl drain <node> 標(biāo)記節(jié)點(diǎn)為不可調(diào)度, 隨后疏散其上所有pod。兩種情形下, 在你用 kubectl uncordon <node> 解除節(jié)點(diǎn)的不可調(diào)度狀態(tài)之前, 不會(huì)有新 pod被調(diào)度到該節(jié)點(diǎn)。限制集群縮容時(shí)的服務(wù)干擾?
如果 一個(gè)節(jié)點(diǎn)發(fā)生非預(yù)期故障, 你不可能阻止其上的pod變?yōu)椴豢捎?#xff1b;但如果一個(gè)節(jié)點(diǎn)被Cluster Autoscaler或者人類操作員主動(dòng)下線,可以用一個(gè)新特性來確保下線操作不會(huì)干擾到這個(gè)節(jié)點(diǎn)上pod所提供的服務(wù)。一些服務(wù)要求至少保持一定數(shù)量的pod持續(xù)運(yùn)行 , 對(duì)基于quorum的集群應(yīng)用而言尤其如此。 為此, Kubemetes可以指定 下線等操作時(shí)需要保待的最少 pod數(shù)量,我們通過創(chuàng)建一個(gè)podDisruptionBudget資源的方式來利用這一特性。盡管這個(gè)資源的名稱聽起來挺復(fù)雜的, 實(shí)際上 它是最簡單的Kubemetes資源
之一 。 它只包含 一個(gè)pod 標(biāo)簽選擇器和 一個(gè)數(shù)字, 指定 最少需要維持運(yùn)行的podYAML文件。
如果想確保你的kubiapod總有3個(gè)實(shí)例在運(yùn)行(它們有 app=kubia這個(gè)標(biāo)簽), 像這樣創(chuàng)建PodDisruptionBudget資源 :
$ kubectl create pdb kubia-pdb --selector=app=kubia --min-available=3 poddisruptionbudget "kubia-pdb" created現(xiàn)在獲取這個(gè)pod 的YAML文件, 如以下代碼清單所示。
也可以用 一個(gè)百分比而非絕對(duì)數(shù)值來寫minAvailable字段。 比方說,可以指定60%帶app=kubia標(biāo)簽的pod應(yīng)當(dāng)時(shí)刻保持運(yùn)行。注意從Kubemetes 1. 7開始podDismptionBudget資源也支持maxUnavailable。如果當(dāng)很多pod不可用而想要阻止pod被剔除時(shí),就可以用maxUnavailable字段而不是minAvailable。
關(guān)于這個(gè)資源, 沒有更多要講的了。 只 要它存在 ,Cluster Autoscaler與?kubectl drain 命令都會(huì)遵守它;如果疏散一個(gè)帶有app=kubia標(biāo)簽的pod會(huì)導(dǎo)致它們的總數(shù)小于3, 那這個(gè)操作就永遠(yuǎn)不會(huì)被執(zhí)行。比方說,如果總共有4個(gè)pod, minAvailable像例子中 一 樣被設(shè)為3, pod?疏散過程就會(huì)挨個(gè)進(jìn)行,待ReplicaSet控制器把被疏散的pod換成新的,才繼續(xù)下一個(gè)。
總結(jié)
以上是生活随笔為你收集整理的k8s-自动横向伸缩pod 根据CPU使用率,QPS访问数监控指标的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 部分排序算法c语言实现
- 下一篇: 安卓逆向代码反混淆 Simplify工具