一、Kubernetes调度过程
说白了,一个调度过程就是把pod放到合适的node上。
Kube-ApiServer <------⑴------> Controllers (Validate/Admit)
| ↑
⑶| ↑_ _ _ ⑵_ _ _ _ Kube-Scheduler (Bind NodeName)
_____|____
/ \
↓ ↓
(Kubelet) (Kubelet)
Node1 Node2
当向集群提交一个创建Pod的yaml文件时,会先发往kube-ApiServer,apiserver再将请求路由到webhooks的Controllers进行校验。
在通过校验之后,ApiServer会在集群里面生成一个pod,但此时生成的pod,它的nodeName是空的,且它的phase是Pending状态(一个pod正常运行时的状态为Running)。在生成了这个pod后,kube-Scheduler及kubelet都能watch 到这个pod的生成事件,kube-Scheduler发现这个pod的nodeName是空的之后,会认为这个pod是处于未调度状态。
然后,kube-Scheduler会对Pod进行调度。通过一系列的调度算法,包括一系列的过滤和打分的算法后,Schedule会选出一台最合适的节点,并把这一台节点的名称绑定在这个pod的spec上,完成一次调度的过程。
此时会看到,pod.spec上,nodeName已经更新成了名为Node1这个node,更新完nodeName之后,在Node1上的这台kubelet会watch到这个pod是属于自己节点上的一个pod。
然后它会把这个pod拿到节点上进行操作,包括创建一些容器storage及network,最后等所有的资源都准备完成,kubelet会把状态更新为Running,这样一个完整的调度过程就结束了。
二、基础调度(POD关系调度)
主要是指Pod与Pod之间、Pod与Node之间的关系调度。
Pod与Node的关系调度:
场景:比如某个Pod要调度到指定Node上运行。
1、节点选择器调度:nodeSelector/nodeName
这是一种常规性调度方式,通过 pod.spec.nodeSelector 或 pod.spec.nodeName 来将 Pod 调度到指定的节点上。
示例1:指定nodeSelector,将pod调度到带有k1=v1标签的Node上
# pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
nodeSelector:
k1: v1
# kubectl create -f pod-demo.yaml
# 可手动为node添加上此标签
# kubectl label nodes node1 k1=v1
示例2:指定nodeName,将pod调度到IP为172.24.11.212的Node上
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
namespace: zjmns
spec:
containers:
- image: ikubernetes/myapp:v1
name: myapp
nodeName: 172.24.11.212
2、节点亲和性调度:NodeAffinity
亲和性又分为 硬亲和性 和 软亲和性 这两种调度,通过 pod.spec.affinity.nodeAffinity 字段指定,作用是根据Node上的标签来约束Pod可以调度到哪些节点上。
requiredDuringSchedulingIgnoredDuringExecution:
硬亲和性,意思是将Pod调度至节点上时,挑选出来的Node,必须要满足这个字段定义的条件,如果集群中找不到满足这样条件的Node时,Pod会调度失败。
preferredDuringSchedulingIgnoredDuringExecution:
软亲和性,意思是将Pod调度至节点上时,会优先</