一、kube-scheduler的作用
kube-scheduler是一個調度器,負責調度Pod到集群內的Node節點上。監聽kube-apiserver上Node和Pod變化情況。查詢Node節點上未分配的Pod,根據調度策略為這些Pod分配Node節點。
在調度過程中需要考慮:
- 公平調度
- 資源合理和高效利用
- 服務質量(QoS)
- 靈活性
- 可擴展性和高可用性
- 內部負載干擾
二、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指定一個調度策略文件來自定義調度策略,如下圖所示:
三、指定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 來選擇使用哪一個調度器(默認使用內置的調度器)。
閱讀更多 DoDo在線 的文章