排程 是指将 Pod 放置到合适的 Node 上,然後對應 Node 上的 Kubelet 才能夠運作這些 pod。
排程概覽
排程器通過 kubernetes 的監測(Watch)機制來發現叢集中新建立且尚未被排程到 Node 上的 Pod。 排程器會将發現的每一個未排程的 Pod 排程到一個合适的 Node 上來運作。 排程器會依據下文的排程原則來做出排程選擇。
kube-scheduler排程流程
kube-scheduler 給一個 pod 做排程選擇包含兩個步驟:
- 過濾
- 打分
過濾階段會将所有滿足 Pod 排程需求的 Node 選出來。
打分階段,排程器會為 Pod 從所有可排程節點打分選取一個最合适的 Node。
NodeSelector定向排程
NodeSelector:是一個供使用者将 Pod 與 Node 進行綁定的字段.
apiVersion: v1
kind: Pod
...
spec:
nodeSelector:
disktype: ssd
指明Pod永遠隻能運作在攜帶“disktype: ssd”标簽的節點上;否則會排程失敗
Kubernetes内置的節點标簽
除了你給
Node(節點)
添加标簽外,Kubernetes也會給
Node
預設義一些标簽,包括:
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
edgenode=true
kubernetes.io/arch=amd64
kubernetes.io/hostname=ycloud
kubernetes.io/os=linux
node-role.kubernetes.io/control-plane=
node-role.kubernetes.io/master=
node.kubernetes.io/exclude-from-external-load-balancers=
注意:這些标簽的值是特定于
雲提供商
的,不保證是可靠的。例如,
kubernetes.io/hostname
的值可能與某些環境中的節點名稱相同,而在其他環境中就不同了。
nodeName排程
nodeName是最簡單的節點選擇限制方式,我常常用它來将pod直接指定到某台節點上,進行測試。
<!--注意:如果它不為空,則排程程式不會在排程這個pod了,并且在命名節點上運作的kubelet嘗試運作該pod。是以,如果在PodSpec中提供nodeName,則它将優先于其他的限制。-->
apiVersion: v1
kind: Pod
...
spec:
nodeName: ycloud
該pod将運作在名為ycloud的節點上了
Node Affinity
用節點親和性把 Pods 配置設定到節點
依據強制的節點親和性排程 Pod
下面清單描述了一個 Pod,它有一個節點親和性配置
requiredDuringSchedulingIgnoredDuringExecution
,
disktype=ssd
。 這意味着 pod 隻會被排程到具有
disktype=ssd
标簽的節點上。
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- ssd
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
使用首選的節點親和性排程 Pod
本清單描述了一個Pod,它有一個節點親和性設定
preferredDuringSchedulingIgnoredDuringExecution
,
disktype: ssd
。 這意味着 pod 将首選具有
disktype=ssd
标簽的節點。
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: disktype
operator: In
values:
- ssd
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
Taint和Toleration(污點和容忍)
節點親和性是
pod
的一種屬性(優先選擇或硬性要求),它使 pod 被優先配置設定到一類特定的節點上。而
Taint
則相反,它使
節點
能夠
排斥
一類特定的 pod。
使用kubectl taint給節點增加一個污點
[root@ycloud ~]# kubectl taint nodes ycloud app=test:NoSchedule
node/ycloud tainted
若要移除這個污點
[root@ycloud ~]# kubectl taint nodes ycloud app=test:NoSchedule-
node/ycloud untainted
你可以在 Pod 規約中為 Pod 設定容忍度。 下面兩個容忍度均與上面例子中使用
kubectl taint
指令建立的污點相比對, 是以如果一個 Pod 擁有其中的任何一個容忍度,都能夠被排程到
node
:
tolerations:
- key: "app"
operator: "Equal"
value: "test"
effect: "NoSchedule"
tolerations:
- key: "app"
operator: "Exists"
effect: "NoSchedule"
例子:
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
tolerations:
- key: "app"
operator: "Exists"
effect: "NoSchedule"
operator
的預設值是
Equal
。
一個容忍度和一個污點相“比對”是指它們有一樣的鍵名和效果,并且:
- 如果
是operator
(此時容忍度不能指定Exists
),或者value
- 如果
是operator
,則它們的Equal
應該相等value