听说过k8s应该都知道,k8s能管理集群,那么通过k8s所运行的容器,又是如何选择节点的呢?实际中k8s对容器的调度非常复杂,针对不同场景有不同的选择方式,这里只说明调度流程,更加详细的调度原理以后会出不存在,只管挖不管埋
指定node运行
在容器yaml配置中,有nodeName这样一个字段,用于将容器在指定node上运行。
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
nodeName: minikube
containers:
- name: nginx
image: nginx
...
这段yaml发送到api server后,api server将发送请求到minikube的kubelet上,由kubelet在minikube上启动一个nginx
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 2/2 Running 0 87s minikube <none> <none>
在k8s中,不仅由nodeSelect也有labelSelect,这个就不详细介绍。
scheduler
k8s的调度器运行在控制平面,用于确保容器匹配到kubelet能运行的node。
修改nginx配置文件,删除nodeName字段,如果没有scheduler,那么api server不知道容器启动请求发送到那个node,所以并不会成功执行。
$ ./kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-without-nodename 0/2 Pending 0 20s
在scheduler的帮助下,即使不指定容器,也可以成功运行。在describe命令中进一步观察,此时存在scheduled事件,表明通过scheduler分配node
$ kubectl describe pods nginx |grep -A8 ^Events
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 77s default-scheduler Successfully assigned default/nginx to minikube
Normal Pulling 76s kubelet Pulling image "nginx"
Normal Pulled 70s kubelet Successfully pulled image "nginx" in 5.553537391s
Normal Created 70s kubelet Created container nginx
Normal Started 70s kubelet Started container nginx
Normal Pulling 70s kubelet Pulling image "busybox"
相比之下,如果指定node,则没有Scheduled事件出现
$ kubectl describe pods nginx |grep -A6 ^Event
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Pulling 2m13s kubelet Pulling image "nginx"
Normal Pulled 2m8s kubelet Successfully pulled image "nginx" in 5.224338933s
Normal Created 2m7s kubelet Created container nginx
Normal Started 2m7s kubelet Started container nginx
scheduler调度逻辑
这里简单说明一下k8s的调度逻辑。scheduler根据容器的配置,如操作系统,可用资源等因素,筛选出feasible node。如果没有满足容器要求的node,那么scheduler就会一直等待,不会调度。 不过一般来说,feasible node会有多个,这时scheduler对每个feasible node评分,选择评分最高的node安排容器启动。 分配完毕后,通知api server在对应node上启动容器。
参考资料
[1]: Kubernetes Scheduler [2]: Kubernetes from the ground up: the scheduler [3]: how-does-kubernetes-scheduler-work [4]: Kubernetes Scheduler