目錄html
Scheduler調度器作爲Kubernetes三大核心組件之一, 承載着整個集羣資源的調度功能,其根據特定調度算法和策略,將Pod調度到最優工做節點上,從而更合理與充分的利用集羣計算資源。 其做用是根據特定的調度算法和策略將Pod調度到指定的計算節點(Node)上,其作爲單獨的程序運行,啓動以後會一直監聽API Server,獲取PodSpec.NodeName爲空的Pod,對每一個Pod都會建立一個綁定。 默認狀況下,k8s的調度器採用擴散策略,將同一集羣內部的pod對象調度到不一樣的Node節點,以保證資源的均衡利用。 完成調度操做的步驟:節點預選(Predicate)、節點優先級排序(Priority)、節點擇優(Select) |
Predicates是強制性規則,用來形容主機匹配Pod所須要的資源,若是沒有任何主機知足該Predicates, 則該Pod會被掛起,直到有主機可以知足。 |
Kubernetes調度器做爲集羣的大腦,在如何提升集羣的資源利用率、保證集羣中服務的穩定運行中也會變得愈來愈重要Kubernetes的資源分爲兩種屬性。node
可壓縮資源(例如CPU循環,Disk I/O帶寬)都是能夠被限制和被回收的,對於一個Pod來講能夠下降這些資源的使用量而不去殺掉Pod。python
不可壓縮資源(例如內存、硬盤空間)通常來講不殺掉Pod就無法回收。將來Kubernetes會加入更多資源,如網絡帶寬,存儲IOPS的支持。算法
預選策略 | 做用 |
---|---|
CheckNodeCondition | 檢查是否能夠在節點報告磁盤、網絡不可用或未準備好時將Pod調度其上 |
HostName | 若是Pod對象擁有spec.hostname屬性,則檢查節點名稱字符串是否和該屬性值匹配。 |
PodFitsHostPorts | Pod的spec.hostPort屬性時,檢查端口是否被佔用 |
MatchNodeSelector | Pod的spec.nodeSelector屬性時,檢查節點標籤 |
NoDiskConflict | Pod請求的存儲卷在此節點是否可用 |
PodFitsResources | 檢查節點上的資源(CPU、內存)可用性是否知足Pod對象的運行需求。 |
PodToleratesNodeTaints | Pod的spec.tolerations屬性,僅關注NoSchedule和NoExecute兩個效用標識的污點 |
PodToleratesNodeNoExecuteTaints | Pod的spec.tolerations屬性,是否能接納節點的NoExecute類型污點 |
CheckNodeLabelPresence | 僅檢查節點上指定的全部標籤的存在性 |
CheckServiceAffinity | 將相同Service的Pod對象放置在同一個或同一類節點上以提升效率 |
MaxEBSVolumeCount | 檢查節點已掛載的EBS存儲卷數量是否超過設置的最大值,默認爲39 |
MaxGCEPDVolumeCount | 檢查節點上已掛載的GCE PD 存儲卷數量是否超過最大值,默認爲16 |
MaxAzureDiskVolumeCount | 檢查節點上已掛載的Azure Disk存儲卷數量是否超過最大值,默認爲16 |
CheckVolumeBinding | 檢查節點上已綁定和未綁定的PVC是否知足需求 |
NoVolumeZoneConflict | 在給定區域zone限制下,檢查此節點部署的Pod對象是否存在存儲卷衝突 |
CheckNodeMemoryPressure | 若給定節點已報告內存資源壓力過大,檢查當前Pod是否可調度至該節點 |
CheckPodePIDPressure | 檢查節點PID資源壓力 |
CheckNodeDiskPressure | 檢查節點磁盤資源壓力 |
MatchInterPodAffinity | 檢查節點是否知足Pod對象親和性或反親和性條件 |
函數名稱 | 詳細說明 |
---|---|
LeastRequestedPriority | 節點的優先級就由節點空閒資源與節點總容量的比值,即由(總容量-節點上Pod的容量總和-新Pod的容量)/總容量)來決定。 CPU和內存具備相同權重,資源空閒比越高的節點得分越高。 cpu((capacity – sum(requested)) * 10 / capacity) + memory((capacity – sum(requested)) * 10 / capacity) / 2 |
BalancedResourceAllocation | CPU和內存使用率越接近的節點權重越高,該策略不能單獨使用,必須和LeastRequestedPriority組合使用,儘可能選擇在部署Pod後各項資源更均衡的機器。 若是請求的資源(CPU或者內存)大於節點的capacity,那麼該節點永遠不會被調度到。 |
InterPodAffinityPriority | 經過迭代 weightedPodAffinityTerm 的元素計算和,而且若是對該節點知足相應的PodAffinityTerm,則將 「weight」 加到和中,具備最高和的節點是最優選的。 |
SelectorSpreadPriority | 爲了更好的容災,對同屬於一個service、replication controller或者replica的多個Pod副本,儘可能調度到多個不一樣的節點上。 若是指定了區域,調度器則會盡可能把Pod分散在不一樣區域的不一樣節點上。當一個Pod的被調度時,會先查找Pod對於的service或者replication controller, 而後查找service或replication controller中已存在的Pod,運行Pod越少的節點的得分越高。 |
NodeAffinityPriority | 親和性機制。Node Selectors(調度時將pod限定在指定節點上), 支持多種操做符(In, NotIn, Exists, DoesNotExist, Gt, Lt),而不限於對節點labels的精確匹配。 另外支持兩種類型的選擇器,一種是「hard(requiredDuringSchedulingIgnoredDuringExecution)」選擇器, 它保證所選的主機必須知足全部Pod對主機的規則要求。 這種選擇器更像是以前的nodeselector,在nodeselector的基礎上增長了更合適的表現語法。 另外一種是「soft(preferresDuringSchedulingIgnoredDuringExecution)」選擇器, 它做爲對調度器的提示,調度器會盡可能但不保證知足NodeSelector的全部要求。 |
NodePreferAvoidPodsPriority(權重1W) | 若是 節點的 Anotation 沒有設置 key-value:scheduler. alpha.kubernetes.io/ preferAvoidPods = "...",則節點對該 policy 的得分就是10分, 加上權重10000,那麼該node對該policy的得分至少10W分。若是Node的Anotation設置了, scheduler.alpha.kubernetes.io/preferAvoidPods = "..." ,若是該 pod 對應的 Controller 是 ReplicationController 或 ReplicaSet, 則該 node 對該 policy 的得分就是0分。 |
TaintTolerationPriority | 使用 Pod 中 tolerationList 與 節點 Taint 進行匹配,配對成功的項越多,則得分越低。 |
ImageLocalityPriority | 根據Node上是否存在一個pod的容器運行所需鏡像大小對優先級打分,分值爲0-10。遍歷所有Node, 若是某個Node上pod容器所需的鏡像一個都不存在,分值爲0; 若是Node上存在Pod容器部分所需鏡像,則根據這些鏡像的大小來決定分值,鏡像越大,分值就越高;若是Node上存在pod所需所有鏡像,分值爲10。 |
EqualPriority | 是一個優先級函數,它給予全部節點相等權重。 |
MostRequestedPriority | 在 ClusterAutoscalerProvider 中,替換 LeastRequestedPriority,給使用多資源的節點,更高的優先級。 計算公式爲: (cpu(10 sum(requested) / capacity) + memory(10 sum(requested) / capacity)) / 2 |
節點親和性規則:硬親和性 required 、軟親和性 preferred。centos
# 調度至 zone = foo 的節點 kubectl label nodes kube-node1 zone=foo
apiVersion: v1 kind: Pod metadata: name: with-required-nodeaffinity spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: # 定義硬親和性 nodeSelectorTerms: - matchExpressions: - {key: zone,operator: In,values: ["foo"]} containers: - name: myapp image: ikubernetes/myapp:v1
可有多個nodeSelectorTerms,相互間爲邏輯或關係 同個nodeSelectorTerms下可有多個matchExpressions,各matchExpressions間爲邏輯與關係 同個matchExpressions下可有多條標籤選擇規則,相互間爲邏輯與關係 節點親和性僅是節點預選策略中的一項,其餘預選策略依然生效 |
apiVersion: apps/v1 kind: Deployment metadata: name: myapp-deploy-with-node-affinity spec: replicas: 2 selector: matchLabels: app: myapp template: metadata: name: myapp-pod labels: app: myapp spec: affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 60 preference: matchExpressions: - {key: zone, operator: In, values: ["foo"]} - weight: 30 preference: matchExpressions: - {key: ssd, operator: Exists, values: []} containers: - name: myapp image: ikubernetes/myapp:v1
親和性
,將一些Pod對象組織在相近的位置(同一節點、機架、區域、地區)反親和性
,將一些Pod在運行位置上隔開調度器將第一個Pod放置於任何位置,而後與其有親和或反親和關係的Pod據此動態完成位置編排
# 基於MatchInterPodAffinity
預選策略完成節點預選,基於InterPodAffinityPriority
優選函數進行各節點的優選級評估api
位置拓撲,定義"同一位置"tomcat
Pod親和性描述一個Pod與具備某特徵的現存Pod運行位置的依賴關係;即須要事先存在被依賴的Pod對象網絡
# 被依賴Pod kubectl run tomcat -l app=tomcat --image tomcat:alpine kubectl explain pod.spec.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution.topologyKey
apiVersion: v1 kind: Pod metadata: name: with-pod-affinity spec: affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: # 硬親和調度 - labelSelector: matchExpressions: - {key: app, operator: In, values: ["tomcat"]} # 選擇被依賴Pod topologyKey: kubernetes.io/hostname # 根據挑選出的Pod全部節點的hostname做爲同一位置的斷定 containers: - name: myapp image: ikubernetes/myapp:v1
調度器先基於標籤選擇器查詢擁有匹配標籤的全部被依賴Pod,再獲取它們所屬節點的topologyKey指示的屬性的標籤值,再查詢全部擁有匹配這些標籤值的全部節點,從而完成節點預選,再根據優選函數計算節點優先級,挑選出運行新建Pod的節點 若節點標籤在運行時發生更改,再也不知足Pod親和性規則時,該Pod會繼續運行;即僅對親建的Pod生效 |
apiVersion: apps/v1 kind: Deployment metadata: name: myapp-with-preferred-pod-affinity spec: replicas: 3 selector: matchLabels: app: myapp template: metadata: name: myapp labels: app: myapp spec: affinity: podAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 80 podAffinityTerm: labelSelector: matchExpressions: - {key: app, operator: In, values: ["cache"]} topologyKey: zone - weight: 20 podAffinityTerm: labelSelector: matchExpressions: - {key: app, operator: In, values: ["db"]} topologyKey: zone containers: - name: myapp image: ikubernetes/myapp:v1
Pod反親和調度用於分散同一類應用,調度至不一樣的區域、機架或節點等
將 spec.affinity.podAffinity
替換爲 spec.affinity.podAntiAffinity
app
反親和調度也分爲柔性約束和強制約束ide
apiVersion: v1 kind: Pod metadata: name: pod-first labels: app: myapp tier: fronted spec: containers: - name: myapp image: ikubernetes/myapp:v1 --- apiVersion: v1 kind: Pod metadata: name: pod-second labels: app: backend tier: db spec: containers: - name: busybox image: busybox:latest imagePullPolicy: IfNotPresent command: ["/bin/sh", "-c", "sleep 3600"] affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - {key: app, operator: In, values: ["myapp"]} topologyKey: zone
污點 taints 是定義在節點
上的鍵值型屬性數據,用於讓節點拒絕將Pod調度運行於其上,除非Pod有接納節點污點的容忍度容忍度 tolerations 是定義在Pod
上的鍵值屬性數據,用於配置可容忍的污點,且調度器將Pod調度至其能容忍該節點污點的節點上或沒有污點的節點上
使用PodToleratesNodeTaints
預選策略和TaintTolerationPriority
優選函數完成該機制
污點定義於nodes.spec.taints
容忍度定義於pods.spec.tolerations
語法: key=value:effect
NoSchedule
,不能容忍,節點現存Pod不受影響PreferNoSchedule
,柔性約束,節點現存Pod不受影響NoExecute
,不能容忍,當污點變更時,Pod對象會被驅逐一個節點可配置多個污點,一個Pod也可有多個容忍度
同一個鍵值數據,effect不一樣,也屬於不一樣的污點
kubectl taint node <node-name> <key>=<value>:<effect>
kubectl get nodes <nodename> -o go-template={{.spec.taints}}
kubectl taint node <node-name> <key>[:<effect>]- kubectl patch nodes <node-name> -p '{"spec":{"taints":[]}}' kubectl taint node kube-node1 node-type=production:NoSchedule kubectl get nodes kube-node1 -o go-template={{.spec.taints}}
# 刪除key爲node-type,effect爲NoSchedule的污點 kubectl taint node kube-node1 node-type:NoSchedule- # 刪除key爲node-type的全部污點 kubectl taint node kube-node1 node-type- # 刪除全部污點 kubectl patch nodes kube-node1 -p '{"spec":{"taints":[]}}'
spec.tolerations
字段添加
tolerationSeconds
用於定義延遲驅逐Pod的時長
# 等值判斷 tolerations: - key: "key1" operator: "Equal" value: "value1" effect: "NoExecute" tolerationSeconds: 3600 # 存在性判斷 tolerations: - key: "key1" operator: "Exists" effect: "NoExecute" tolerationSeconds: 3600
上面兩個例子表示若是某個Node存在key1=value1的污點或者存在key1的污點,Pod將不會調度到這樣的節點。 |
apiVersion: v1 kind: Deployment metadata: name: myapp-deploy namespace: default spec: replicas: 3 selector: matchLabels: app: myapp release: canary template: metadata: labels: app: myapp release: canary spec: containers: - name: myapp image: ikubernetes/myapp:v1 ports: - name: http containerPort: 80 tolerations: - key: "node-type" operator: "Equal" value: "production": effect: "NoExecute" tolerationSeconds: 3600
自動爲節點添加污點信息,使用NoExecute效用標識,會驅逐現有Pod
K8s核心組件一般都容忍此類污點
node.kubernetes.io/not-ready 節點進入NotReady狀態時自動添加
node.alpha.kubernetes.io/unreachable 節點進入NotReachable狀態時自動添加
node.kubernetes.io/out-of-disk 節點進入OutOfDisk狀態時自動添加
node.kubernetes.io/memory-pressure 節點內存資源面臨壓力
node.kubernetes.io/disk-pressure 節點磁盤面臨壓力
node.kubernetes.io/network-unavailable 節點網絡不可用
node.cloudprovider.kubernetes.io/uninitialized kubelet由外部雲環境程序啓動時,自動添加,待到去控制器初始化此節點時再將其刪除
優選級,Pod對象的重要程度
優選級會影響節點上Pod的調度順序和驅逐次序
一個Pod對象沒法被調度時,調度器會嘗試搶佔(驅逐)較低優先級的Pod對象,以即可以調度當前Pod
Pod優選級和搶佔機制默認處於禁用狀態
啓用:同時爲kube-apiserver、kube-scheduler、kubelet程序的 --feature-gates 添加 PodPriority=true
使用:
事先建立優先級類別,並在建立Pod資源時經過 priorityClassName屬性指定所屬的優選級類別
https://pdf.us/2019/04/08/3222.html
https://www.cnblogs.com/centos-python/articles/10884738.html