1. 程式人生 > >kubernetes排程之pod優先順序和資源搶佔

kubernetes排程之pod優先順序和資源搶佔

系列目錄

Pod可以擁有優先順序.優先意味著相對於其它pod某個pod更為重要.如果重要的pod不能被排程,則kubernetes排程器會優先於(驅離)低優先順序的pod來讓處於pending狀態的高優先順序pod被排程.

kubernetes 1.9以後,優先順序會影響pod的排程順序和資源耗盡時pod的驅離順序

警告:在一個不是所有使用者都被信任的叢集裡,可能有惡意使用者建立最高可能優先順序的pod,導致其它pod被驅離或者無法排程.為了解決這個問題,需要增大資源配額來支援優先pod.叢集管理員可以為特定使用者建立特定優先順序級別,防止他們建立高優先順序的pod.這項功能在1.12版本里為beta狀態.

怎樣使用優先順序和搶佔

在1.11或以後的版本里,按下面指示來操作:

  • 建立一個或者多個PriorityClasses

  • 建立一個pod,並把priorityClassName設定為以上新增的priorityClassName中的一個.當然你不必直接建立pod,你可以把priorityClassName新增到集合物件(比如deployment)的template裡.

如果你僅想嘗試這項功能並且然後把它禁用,你必須把PodPriority設定為false,然後重啟apiserver和排程器.被禁用以後,已經存在的pod仍然保留有它們的優先順序欄位,但是搶佔不會再生效,並且優先欄位被忽略.你也不能再向新的pod新增priorityClassName

欄位

怎樣禁用搶佔

在kubernetes 1.12+ 當叢集處於較大資源壓力時,一些關鍵的pod依賴搶佔排程.因此強烈為建議禁用搶佔

在kubernetes1.11以後版本,搶佔被kube-scheduler的的disablePreemption標識控制,預設設定是false.如果你不顧建議仍然想要禁用它,可以把它設定為true

這個選項僅僅在元件的配置裡有效,在舊式的命令列下無效.下面是一個配置的示例:

apiVersion: componentconfig/v1alpha1
kind: KubeSchedulerConfiguration
algorithmSource:
  provider: DefaultProvider

...

disablePreemption: true

搶佔

當pod被建立,他們進入佇列等待被排程.排程器從佇列取出一個pod並且嘗試把它排程到一個節點上.如果沒有節點能夠滿足這個pod的所有要求,搶佔邏輯被觸發,我們把這個掛起的pod稱作P.排程器嘗試尋找移除一個或者多個比P低的pod後能夠使得P被排程的節點.如果找到了一個這樣的節點,一個或者多個優先順序低的節點被驅離,然後P被排程到這個節點上.

當pod P搶佔了Node N上的一個或者多個pod的資源,P的nominatedNodeName(候選節點)欄位被設定為節點N的名字.這個欄位幫助排程器追蹤為P預留的資源資訊,並給使用者提供叢集資源搶佔的一些資訊.

需要注意的是pod P並不總是排程到候選節點(nominated Node)上,當受害的pod被搶佔,他們進入終止階段.當受害pod停止的過程中其它節點變得可用,這時候排程器就會使用這個可用的節點來接收pod P,這樣就造成nominatedNodeNamenodeName並不總是相同.並且,pod P搶佔了節點N上的優先順序低的pod的資源時,這時候有更高優先順序的pod到達,這時候排程器可能會把節點N讓給這個更高優先順序的pod使用.這時候排程器會清除pod P的nominatedNodeName欄位,這樣,排程器使用pod P可以搶佔其它節點上的資源.

搶佔限制

受害pod的優雅終止

當被搶佔,受害pod進入優雅終止期,它們將有時間完成工作並退出.否則,會被殺掉.這個優雅終止期在排程器搶佔受害pod資源和優先pod被排程到Node N之間建立了一個時間間隔.同時,排程器繼續排程其它狀態為pending的pod.為了縮短這個時間間隔,使用者可以把優雅終止期設定為0或者一個很小的時間

低優先順序pod的pod間親和性

問題:如果所有低優先順序的pod都從一個節點上移除了,那麼掛起(pending)的pod是否可以排程到此節點上?

這個問題的意義在於如果所有的pod都被移除,資源仍然不夠容納掛起的pod會怎麼樣?

僅當以上問題的答案是肯定的(yes)的時候,節點的搶佔才會發生(也就是如果全部低優先順序的pod都被驅離仍然不夠容納新的pod時,節點上不會發生搶佔)

需要注意的是,並不是總是要移除節點上的所有低優先順序的pod.如果僅僅移除一些pod就足以容納掛起的pod時,僅有部分低優先順序的pod被移除.但是以上問題的答案仍然需要是肯定的(也就是說低優先順序pod的移除建立在移除後資源足以容納新的掛起的節點的基礎上的)

如果掛起的pod(即將被排程的)和一個或者多個節點N上的低優先順序的pod有pod間親和關係,如果低優先順序pod離開後pod間的親和關係不能被滿足時,排程器這時候不會再搶佔節點N上的pod.排程器可能會找到一個其它的合適的節點,也可能找不到.這就無法保證掛起的pod被排程.

對於這個問題我們的建議是建立pod間親和關係時,只向同等優先順序和更高優先順序的pod建立.

跨節點搶佔

假設Node N 上準備搶佔以便是pod P可以被排程到N上,但是P依賴於其它節點上的pod被驅離才可以被排程到N上,以下示例說明這個問題

  • Pod P準備排程到節點N上

  • pod Q們於和節點N同一區域的其它節點上

  • pod P和pod Q有區域級別的反親和關係(topologyKey: failure-domain.beta.kubernetes.io/zone)

  • pod P和同一區域內的其它pod沒有反親和關係

  • 為了把pod P排程到節點N上,Pod Q可以被搶佔,但是排程器不會執行跨節點搶佔,因此pod P不會被排程到節點N上.

  • 如果pod Q從它的節點上移除,這時候違反親和關係也消失,此時pod P可能會被排程到節點N上

  • 在未來的版本中如果能找到一個能保證效能的演算法,我們可能會考慮增加跨節點驅離.但是目前我們什麼都不能保證.

排程pod優先順序和搶佔

pod優先順序和資源搶佔的編排如果有bug的話則往往是導致節點排程中斷的主要原因之一

pod優先順序和資源搶佔可能導致的問題

以下是如果pod優先順序和資源搶佔包含bug可能導致的問題的不完全羅列:

  • pod被非必要地搶佔

當叢集出現資源壓力時,排程器會移除優先順序低的pod來為優先順序高的pod騰出資源,如果使用者錯誤地給分配給一些pod過高的優先權,這些無意分配的高優先權會導致叢集搶佔.像上面提到的,pod的優先權通過設定podSpec欄位的priorityClassName來實現的,優先順序的整數字段然被解析後傳入到podSpec欄位的priority欄位裡

為了解決這個問題,priorityClassName欄位必須改變到更小的優先順序或者留空,priorityClassName欄位留空會被解析為0

當一個pod被搶佔,則它會產生一條event記錄來記錄這個事件.僅當叢集沒有足夠的資源時搶佔才會發生.這種情況僅發生在(掛起)的pod的優先順序高於受害pod.如果沒有掛起的pod,則搶佔事件一定不能發生.如果沒有掛起pod,或者掛起pod的優先順序等於或小於受害pod時發生搶佔事件,則是系統bug,請提交一個issue給我們.

pod被搶佔,但是搶佔的pod並沒有被排程

當pod被搶佔,他們將接收到一個優雅停止的時間段,預設是30秒,但是也可以是任意在podSpec裡指定的值.如果受害pod沒有在指定的時段裡停止,他們會被強行終止.當所有受害者都被移除,優先pod可以被排程.

當優先pod等待受害者被移除時,一個適合排程到這個節點上的更高優先順序的pod被建立.這時候排程器會優先排程這個更高優先順序的pod

高優先順序的pod比優先順序更低的pod被搶佔

排程器會盡力尋找適合的節點來排程掛起的pod,如果找不一節點來排程,排程器會從一個包含低優先順序的節點上移除pod來為掛起的pod騰出空間.如果有低優先順序pod的節點不適合被排程,排程器可能會選擇一個更高優先順序的節點來搶佔(這裡說的更高是相對前面找到的低優先順序的pod而言的,而不是對優先pod而言的).被搶佔的pod仍然必須要比優先pod(指掛起的需要排程的pod)優先級別低

當有多個節點可以被搶佔時,排程器會嘗試選擇有最低優先順序pod的節點來排程.但是如果pod有PodDisruptionBudget並且搶佔可能會違反PodDisruptionBudget時,排程器可能會選擇一個更高優先順序的pod來搶佔.

當有多個節點可以被搶佔並且沒有出現以上情形,則排程器會選擇優先順序最低的pod來搶佔,如果不是這樣的,則意味著排程器本身存在bug.

pod優先順序和Qos互動

pod優先順序和QoS是兩個正交的功能,幾乎沒有交叉.排程器的搶佔邏輯當選擇搶佔物件時不會考慮QoS.搶佔會考慮pod的優先順序並選擇出一系列低優先順序搶佔目標.只有當即便移除低優先順序pod也不足以執行掛起的pod或者低優先順序的pod被PodDisruptionBudget保護時,排程器才會選擇更高優先順序的pod作為搶佔物件.

僅有Kubelet的 out-of-resource eviction元件才會同時考慮pod優先順序和QoS,kubelet首先會根據使用的資源是否超過請求的值來對要驅離的pod進行排序,然後根據優先順序.Kubelet out-of-resource eviction 不會驅離使用資源低於請求資源的pod,如果一個低優先順序的pod使用的資源沒有超過它請求的,則它不會被驅離.其它的使用資源超過其申請資源的更高優先順序的pod可能會被驅