《蹲坑學kubernetes》之9-3:kube-scheduler原理詳解

一、kube-scheduler的作用

kube-scheduler是一個調度器,負責調度Pod到集群內的Node節點上。監聽kube-apiserver上Node和Pod變化情況。查詢Node節點上未分配的Pod,根據調度策略為這些Pod分配Node節點。

《蹲坑學kubernetes》之9-3:kube-scheduler原理詳解

圖1:kube-scheduler調度過程

在調度過程中需要考慮:

  • 公平調度
  • 資源合理和高效利用
  • 服務質量(QoS)
  • 靈活性
  • 可擴展性和高可用性
  • 內部負載干擾

二、kube-scheduler工作原理

《蹲坑學kubernetes》之9-3:kube-scheduler原理詳解

圖2:kube-scheduler調度原理

kube-scheduler調度分為兩個階段:predicate 和 priority

predicate:過濾不符合條件的節點

priority:優先級排序,選擇優先級最高的節點

1、predicates 策略:

PodFitsPorts:同 PodFitsHostPorts

PodFitsHostPorts:檢查是否有 Host Ports 衝突

PodFitsResources:檢查 Node 的資源是否充足

(包括允許的 Pod 數量、CPU、內存、GPU 個數以及其他的 OpaqueIntResources )

HostName:檢查 pod.Spec.NodeName 是否與候選節點一致

MatchNodeSelector:檢查候選節點的 pod.Spec.NodeSelector 是否匹配

NoVolumeZoneConflict:

檢查 volume zone 是否衝突

MaxEBSVolumeCount:檢查 AWS EBS Volume 數量是否過多(默認不超過 39)

MaxGCEPDVolumeCount:檢查 GCE PD Volume 數量是否過多(默認不超過 16)

MaxAzureDiskVolumeCount:檢查 Azure Disk Volume 數量是否過多(默認不超過 16)

MatchInterPodAffinity:檢查是否匹配 Pod 的親和性要求

NoDiskConflict:檢查是否存在 Volume 衝突,僅限於 GCE PD、AWS EBS、Ceph RBD 以及 ISCSI

GeneralPredicates:分為 noncriticalPredicates 和 EssentialPredicates。

( noncriticalPredicates 中包含 PodFitsResources)

( EssentialPredicates 中包含 PodFitsHost,PodFitsHostPorts 和 PodSelectorMatches )

PodToleratesNodeTaints:檢查 Pod 是否容忍 Node Taints

CheckNodeMemoryPressure:檢查 Pod 是否可以調度到 MemoryPressure 的節點上

CheckNodeDiskPressure:檢查 Pod 是否可以調度到 DiskPressure 的節點上

NoVolumeNodeConflict:檢查節點是否滿足 Pod 所引用的 Volume 的條件

2、priorities 策略:

SelectorSpreadPriority:優先減少節點上屬於同一個 Service 或 Replication Controller 的 Pod 數量

InterPodAffinityPriority:優先將 Pod 調度到相同的拓撲上(如同一個節點、Rack、Zone 等)

LeastRequestedPriority:優先調度到請求資源少的節點上

BalancedResourceAllocation:優先平衡各節點的資源使用

NodePreferAvoidPodsPriority:alpha.kubernetes.io/preferAvoidPods 字段判斷, 權重為 10000,避免其他優先級策略的影響

NodeAffinityPriority:優先調度到匹配 NodeAffinity 的節點上

TaintTolerationPriority:優先調度到匹配 TaintToleration 的節點上

ServiceSpreadingPriority:儘量將同一個 service 的 Pod 分佈到不同節點上,已經被 SelectorSpreadPriority 替代 [默認未使用]

EqualPriority:將所有節點的優先級設置為 1[默認未使用]

ImageLocalityPriority:儘量將使用大鏡像的容器調度到已經下拉了該鏡像的節點上 [默認未使用]

MostRequestedPriority:儘量調度到已經使用過的 Node 上,特別適用於 cluster-autoscaler[默認未使用]

3、自定義策略

kube-scheduler還支持使用--policy-config-file指定一個調度策略文件來自定義調度策略,如下圖所示:

《蹲坑學kubernetes》之9-3:kube-scheduler原理詳解

圖3:kube-scheduler調度策略

三、指定Node節點調度

有三種方式指定 Pod 只運行在指定的 Node 節點上

1、nodeSelector:只調度到匹配指定 label 的 Node 上

首先給 Node 打上標籤:

kubectl label nodes k8s-node-1 disktype=ssd

然後在 daemonset 中指定 nodeSelector 為 disktype=ssd

2、nodeAffinity:功能更豐富的 Node 選擇器,比如支持集合操作。

nodeAffinity 目前支持兩種:requiredDuringSchedulingIgnoredDuringExecution 和 preferredDuringSchedulingIgnoredDuringExecution,分別代表必須滿足條件和優選條件。比如下面的例子代表調度到包含標籤 kubernetes.io/e2e-az-name 並且值為 e2e-az1 或 e2e-az2 的 Node 上,並且優選還帶有標籤 another-node-label-key=another-node-label-value 的 Node。

3、podAffinity:調度到滿足條件的 Pod 所在的 Node 上

podAffinity基於Pod的標籤來選擇Node,僅調度到滿足條件Pod所在的Node上,支持podAffinity和podAntiAffinity。

三、設置汙點(Taints)和容忍(tolerations)

Taints 和 tolerations 用於保證 Pod 不被調度到不合適的 Node 上,其中 Taint 應用於 Node 上,而 toleration 則應用於 Pod 上。目前支持的 taint 類型:

NoSchedule:新的Pod不調度到該Node 上,不影響正在運行的Pod

PreferNoSchedule:soft版的NoSchedule,儘量不調度到該 Node 上

NoExecute:新的Pod不調度到該 Node 上,並且刪除(evict)已在運行的Pod。Pod可以增加一個時間(tolerationSeconds),

然而,當Pod的Tolerations匹配Node的所有Taints的時候可以調度到該Node上;當Pod是已經運行的時候,也不會被刪除(evicted)。另外對於NoExecute,如果Pod增加了一個tolerationSeconds,則會在該時間之後才刪除Pod。

例: node1上應用以下幾個taint:

<code>[root@k8s-master ~]# kubectl taint nodes k8s-master key1=value1:NoSchedule
[root@k8s-master ~]# kubectl taint nodes k8s-master key1=value1:NoExecute
[root@k8s-master ~]# kubectl taint nodes k8s-master key2=value2:NoSchedule/<code>


四、優先級調度與多調度器

1、優先級調度

從 v1.8 開始,kube-scheduler 支持定義 Pod 的優先級,從而保證高優先級的 Pod 優先調度。並從 v1.11 開始默認開啟。在指定 Pod 的優先級之前需要先定義一個 PriorityClass。value為32位整數的優先級,值越大,優先級越高。

2、多調度器

如果默認的調度器不滿足要求,還可以部署自定義的調度器。並且,在整個集群中還可以同時運行多個調度器實例,通過 podSpec.schedulerName 來選擇使用哪一個調度器(默認使用內置的調度器)。


分享到:


相關文章: