系列目錄html
Pod能夠擁有優先級.優先意味着相對於其它pod某個pod更爲重要.若是重要的pod不能被調度,則kubernetes調度器會優先於(驅離)低優先級的pod來讓處於pending狀態的高優先級pod被調度.node
kubernetes 1.9之後,優先級會影響pod的調度順序和資源耗盡時pod的驅離順序算法
警告:在一個不是全部用戶都被信任的集羣裏,可能有惡意用戶建立最高可能優先級的pod,致使其它pod被驅離或者沒法調度.爲了解決這個問題,須要增大資源配額來支持優先pod.集羣管理員能夠爲特定用戶建立特定優先級級別,防止他們建立高優先級的pod.這項功能在1.12版本里爲beta狀態.api
在1.11或之後的版本里,按下面指示來操做:dom
建立一個或者多個PriorityClasses
ide
建立一個pod,並把priorityClassName
設置爲以上添加的priorityClassName
中的一個.固然你沒必要直接建立pod,你能夠把priorityClassName
添加到集合對象(好比deployment)的template裏.性能
若是你僅想嘗試這項功能而且而後把它禁用,你必須把PodPriority
設置爲false,而後重啓apiserver和調度器.被禁用之後,已經存在的pod仍然保留有它們的優先級字段,可是搶佔不會再生效,而且優先字段被忽略.你也不能再向新的pod添加priorityClassName
字段命令行
在kubernetes 1.12+ 當集羣處於較大資源壓力時,一些關鍵的pod依賴搶佔調度.所以強烈爲建議禁用搶佔code
在kubernetes1.11之後版本,搶佔被kube-scheduler的的disablePreemption
標識控制,默認設置是false.若是你不顧建議仍然想要禁用它,能夠把它設置爲truecomponent
這個選項僅僅在組件的配置裏有效,在舊式的命令行下無效.下面是一個配置的示例:
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,這樣就形成nominatedNodeName
和nodeName
並不老是相同.而且,pod P搶佔了節點N上的優先級低的pod的資源時,這時候有更高優先級的pod到達,這時候調度器可能會把節點N讓給這個更高優先級的pod使用.這時候調度器會清除pod P的nominatedNodeName
字段,這樣,調度器使用pod P能夠搶佔其它節點上的資源.
當被搶佔,受害pod進入優雅終止期,它們將有時間完成工做並退出.不然,會被殺掉.這個優雅終止期在調度器搶佔受害pod資源和優先pod被調度到Node N之間建立了一個時間間隔.同時,調度器繼續調度其它狀態爲pending
的pod.爲了縮短這個時間間隔,用戶能夠把優雅終止期設置爲0或者一個很小的時間
問題:若是全部低優先級的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優先級和資源搶佔的編排若是有bug的話則每每是致使節點調度中斷的主要緣由之一
如下是若是pod優先級和資源搶佔包含bug可能致使的問題的不徹底羅列:
當集羣出現資源壓力時,調度器會移除優先級低的pod來爲優先級高的pod騰出資源,若是用戶錯誤地給分配給一些pod太高的優先權,這些無心分配的高優先權會致使集羣搶佔.像上面提到的,pod的優先權經過設置podSpec
字段的priorityClassName
來實現的,優先級的整數字段然被解析後傳入到podSpec
字段的priority
字段裏
爲了解決這個問題,priorityClassName
字段必須改變到更小的優先級或者留空,priorityClassName
字段留空會被解析爲0
當一個pod被搶佔,則它會產生一條event記錄來記錄這個事件.僅當集羣沒有足夠的資源時搶佔纔會發生.這種狀況僅發生在(掛起)的pod的優先級高於受害pod.若是沒有掛起的pod,則搶佔事件必定不能發生.若是沒有掛起pod,或者掛起pod的優先級等於或小於受害pod時發生搶佔事件,則是系統bug,請提交一個issue給咱們.
當pod被搶佔,他們將接收到一個優雅中止的時間段,默認是30秒,可是也能夠是任意在podSpec裏指定的值.若是受害pod沒有在指定的時段裏中止,他們會被強行終止.當全部受害者都被移除,優先pod能夠被調度.
當優先pod等待受害者被移除時,一個適合調度到這個節點上的更高優先級的pod被建立.這時候調度器會優先調度這個更高優先級的pod
調度器會盡力尋找適合的節點來調度掛起的pod,若是找不一節點來調度,調度器會從一個包含低優先級的節點上移除pod來爲掛起的pod騰出空間.若是有低優先級pod的節點不適合被調度,調度器可能會選擇一個更高優先級的節點來搶佔(這裏說的更高是相對前面找到的低優先級的pod而言的,而不是對優先pod而言的).被搶佔的pod仍然必需要比優先pod(指掛起的須要調度的pod)優先級別低
當有多個節點能夠被搶佔時,調度器會嘗試選擇有最低優先級pod的節點來調度.可是若是pod有PodDisruptionBudget
而且搶佔可能會違反PodDisruptionBudget
時,調度器可能會選擇一個更高優先級的pod來搶佔.
當有多個節點能夠被搶佔而且沒有出現以上情形,則調度器會選擇優先級最低的pod來搶佔,若是不是這樣的,則意味着調度器自己存在bug.
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可能會被驅離.