作者:Choerodon猪齿鱼社区 钟梓凌&黄显东
Kubernetes作为一个容器编排调度引擎,资源调度是它的最基本也是最重要的功能。当开发者部署一个应用时它运行在哪个节点?这个节点满不满足开发的运行要求?Kubernetes又是如何进行资源调度的呢?
▌通过本文可了解到以下信息:
- 资源请求及限制对pod调度的影响
- 查看调度事件events
- 了解label选择器对pod调度的影响
- 了解节点亲和性和Pod亲和性对调度的影响
- 不使用调度器,手动调度一个pod
- 了解Daemonset的角色
- 了解如何配置Kubernetes scheduler
在Kubernetes中有一个kube-scheduler组件,该组件运行在master节点上,它主要负责pod的调度。Kube-scheduler监听kube-apiserver中是否有还未调度到node上的pod(即Spec.NodeName为空的Pod),再通过特定的算法为pod指定分派node运行。如果分配失败,则将该pod放置调度队列尾部以重新调度。调度主要分为几个部分:首先是预选过程,过滤不满足Pod要求的节点。然后是优选过程,对通过要求的节点进行优先级排序,最后选择优先级最高的节点分配,其中涉及到的两个关键点是过滤和优先级评定的算法。调度器使用一组规则过滤不符合要求的节点,其中包括设置了资源的request和指定了Nodename或者其他亲和性设置等等。优先级评定将过滤得到的节点列表进行打分,调度器考虑一些整体的优化策略,比如将Deployment控制的多个副本集分配到不同节点上等。
资源请求及限制对pod调度的影响
在部署应用时,开发者会考虑到使这个应用运行起来需要多少的内存和CPU资源的使用量,这样才能判断应将他运行在哪个节点上。在部署文件resource属性中添加requests字段用于说明运行该容器所需的最少资源,当调度器开始调度该Pod时,调度程序确保对于每种资源类型,计划容器的资源请求总和必须小于节点的容量才能分配该节点运行Pod,resource属性中添加limits字段用于限制容器运行时所获得的最大资源。如果该容器超出其内存限制,则可能被终止。 如果该容器可以重新启动,kubelet会将它重新启动。如果调度器找不到合适的节点运行Pod时,就会产生调度失败事件,调度器会将Pod放置调度队列以循环调度,直到调度完成。
在下面例子中,运行一个nginx Pod,资源请求了256Mi的内存和100m的CPU,调度器将判断哪个节点还剩余这么多的资源,寻找到了之后就会将这个Pod调度上去。同时也设置了512Mi的内存和300m的CPU的使用限制,如果该Pod运行之后超出了这一限制就将被重启甚至被驱逐。
apiVersion: v1kind: Podmetadata: name: nginxspec: containers: - name: nginx image: nginx resources: requests: memory: "256Mi" cpu: "100m" limits: memory: "512Mi" cpu: "300m"
参考文档:
- Assign CPU Resources to Containers and Pods
- Assign Memory Resources to Containers and Pods
查看调度事件events
在部署应用后,可以使用 kubectl describe 命令进行查看Pod的调度事件,下面是一个coredns被成功调度到node3运行的事件记录。
$ kubectl describe po coredns-5679d9cd77-d6jp6 -n kube-system...Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 29s default-scheduler Successfully assigned kube-system/coredns-5679d9cd77-d6jp6 to node3 Normal Pulled 28s kubelet, node3 Container image "grc.io/kubernetes/coredns:1.2.2" already present on machine Normal Created 28s kubelet, node3 Created container Normal Started 28s kubelet, node3 Started container
下面是一个coredns被调度失败的事件记录,根据记录显示不可调度的原因是没有节点满足该Pod的内存请求。
$ kubectl describe po coredns-8447874846-5hpmz -n kube-system...Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 22s (x3 over 24s) default-scheduler 0/3 nodes are available: 3 Insufficient memory.
label选择器对pod调度的影响
例如开发者需要部署一个ES集群,由于ES对磁盘有较高的要求,而集群中只有一部分节点有SSD磁盘,那么就需要将标记一下带有SSD磁盘的节点即给这些节点打上Lable,让ES的pod只能运行在带这些标记的节点上。
Lable是附着在K8S对象(如Pod、Service等)上的键值对。它可以在创建对象的时候指定,也可以在对象创建后随时指定。Kubernetes最终将对labels最终索引和反向索引用来优化查询和watch,在UI和命令行中会对它们排序。通俗的说,就是为K8S对象打上各种标签,方便选择和调度。
完整内容,可点击此处查看:
关于Choerodon猪齿鱼
开源多云集成平台,基于开源技术Kubernetes,Istio,knative,Gitlab和Spring Cloud来实现本地和云端环境的集成,实现企业多云/混合云应用环境的一致性。平台通过提供精益敏捷、持续交付、容器环境、微服务、DevOps等能力来帮助组织团队来完成软件的生命周期管理,从而更快、更频繁地交付更稳定的软件。
大家也可以通过以下社区途径了解猪齿鱼的最新动态、产品特性,以及参与社区贡献:
- 官网:
- 论坛:
- Github:
- 微信号:Choerodon猪齿鱼
- 微博:Choerodon猪齿鱼