Kubernets解析-容器调度浅析

102 阅读1分钟

听说过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