云原生|kubernetes |一文带你搞懂pod调度策略,驱逐策略,污点、容忍调度(一)

简介: 云原生|kubernetes |一文带你搞懂pod调度策略,驱逐策略,污点、容忍调度

前言


kubernetes集群不是简单的安装部署就完事了,还需要根据业务的性质设定一些策略,比如,某些pod不希望被调度到硬件条件比较差的节点,某些pod又希望调度到含有比如有特定的硬件GPU的节点上。又或者某个节点由于硬件资源比如CPU,内存并没有彻底耗尽,但如果在继续调度pod到此节点有造成集群崩溃的风险,如何阻止并驱逐此节点在运行的pod,以及集群需要检修或者重建某个节点,此时的节点上运行的pod应该如何处置等等各种各样的问题以及解决方案就形成了pod调度策略,驱逐策略,污点、容忍调度策略。

说人话,这些也可以说是kubernetes集群的优化策略。下面将就以上提出的情况和一些没有提到过的情况做一个总结吧!!!

主要的pod调度策略:

  • 自由调度:pod运行在哪个节点完全由scheduler经过一系列算法计算得出(如果没有定向调度,亲和性,容忍策略,此策略就是默认的啦)
  • 定向调度:采用nodeName、nodeSelector来实现pod定向调度(pod面向节点)
  • 亲和性调度:NodeAffinityinity、PodAffinity、PodAntiAffinity
  • 污点、容忍调度:Taints、Toleration(前面讲过了)

一,节点维护状态(cordon,uncordondrain)


节点情况举例:

例如有三个节点,k8s-node1,k8s-node2,k8s-master

[root@master ~]# k get no
NAME         STATUS   ROLES    AGE   VERSION
k8s-master   Ready    <none>   25d   v1.18.3
k8s-node1    Ready    <none>   25d   v1.18.3
k8s-node2    Ready    <none>   25d   v1.18.3

现有两个pod在节点2运行,其中pod  kube-flannel-ds-mlb7l是daemonsets方式部署,是核心组件:

NAMESPACE     NAME                       READY   STATUS    RESTARTS   AGE     IP               NODE         NOMINATED NODE   READINESS GATES
default       busybox-7bf6d6f9b5-jg922   1/1     Running   2          24d     10.244.0.11      k8s-master   <none>           <none>
default       nginx-7c96855774-28b5w     1/1     Running   2          24d     10.244.0.12      k8s-master   <none>           <none>
default       nginx-7c96855774-d592j     1/1     Running   0          4h44m   10.244.0.13      k8s-master   <none>           <none>
default       nginx1                     1/1     Running   2          24d     10.244.2.11      k8s-node2    <none>           <none>
kube-system   coredns-76648cbfc9-lb75g   1/1     Running   2          24d     10.244.2.10      k8s-node2    <none>           <none>
kube-system   kube-flannel-ds-mhkdq      1/1     Running   7          24d     192.168.217.17   k8s-node1    <none>           <none>
kube-system   kube-flannel-ds-mlb7l      1/1     Running   6          24d     192.168.217.18   k8s-node2    <none>           <none>
kube-system   kube-flannel-ds-sl4qv      1/1     Running   2          24d     192.168.217.16   k8s-master   <none>           <none>

假如现在需要维护node2节点,那么,先需要驱逐node2节点上的所有pod,pod方式部署的直接驱逐,daemonsets的忽略:

[root@master ~]# k drain k8s-node2 --force --ignore-daemonsets
node/k8s-node2 already cordoned
WARNING: deleting Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet: default/nginx1; ignoring DaemonSet-managed Pods: kube-system/kube-flannel-ds-mlb7l
evicting pod default/nginx1
evicting pod kube-system/coredns-76648cbfc9-lb75g
pod/coredns-76648cbfc9-lb75g evicted
pod/nginx1 evicted
node/k8s-node2 evicted

结果是这样的:

可以看到,coredns这个pod漂移到了node1,pod方式部署的nginx直接销毁了,kube-flannel-ds-mlb7l没有变动

[root@master ~]# k get po -A -owide
NAMESPACE     NAME                       READY   STATUS    RESTARTS   AGE     IP               NODE         NOMINATED NODE   READINESS GATES
default       busybox-7bf6d6f9b5-jg922   1/1     Running   2          24d     10.244.0.11      k8s-master   <none>           <none>
default       nginx-7c96855774-28b5w     1/1     Running   2          24d     10.244.0.12      k8s-master   <none>           <none>
default       nginx-7c96855774-d592j     1/1     Running   0          4h52m   10.244.0.13      k8s-master   <none>           <none>
kube-system   coredns-76648cbfc9-z8kh5   1/1     Running   0          2m2s    10.244.1.8       k8s-node1    <none>           <none>
kube-system   kube-flannel-ds-mhkdq      1/1     Running   7          24d     192.168.217.17   k8s-node1    <none>           <none>
kube-system   kube-flannel-ds-mlb7l      1/1     Running   6          24d     192.168.217.18   k8s-node2    <none>           <none>
kube-system   kube-flannel-ds-sl4qv      1/1     Running   2          24d     192.168.217.16   k8s-master   <none>           <none>

这个时候的节点是部分禁用的(这里的意思是scheduler服务不会调度新的pod到此节点,但,如果强制nodeselector,仍然会运行新pod)

此时的scheduler不会调度新pod到node2节点

[root@master ~]# k get no
NAME         STATUS                     ROLES    AGE   VERSION
k8s-master   Ready                      <none>   25d   v1.18.3
k8s-node1    Ready                      <none>   25d   v1.18.3
k8s-node2    Ready,SchedulingDisabled   <none>   25d   v1.18.3

节点维护状态和解除节点维护状态:

[root@master coredns]# k cordon k8s-node2
node/k8s-node2 cordoned
[root@master coredns]# k uncordon k8s-node2
node/k8s-node2 uncordoned

小结:

cordon,uncordon,drain这三个命令主要是用在节点维护场景,drain有安全驱逐pod的功能,pod会实现漂移,但此驱逐并非硬性驱逐,管不了pod的指定调度策略。

适用范围是比较窄的哦,比如,使用了本地存储卷的pod或者有状态pod不适合使用drain,因为drain了相关服务就完蛋了。

二,taints--节点污点


关于污点的解释


[root@master coredns]# k explain node.spec.taints
KIND:     Node
VERSION:  v1
RESOURCE: taints <[]Object>
DESCRIPTION:
     If specified, the node's taints.
     The node this Taint is attached to has the "effect" on any pod that does
     not tolerate the Taint.
FIELDS:
   effect <string> -required-
     Required. The effect of the taint on pods that do not tolerate the taint.
     Valid effects are NoSchedule, PreferNoSchedule and NoExecute.
   key  <string> -required-
     Required. The taint key to be applied to a node.
   timeAdded  <string>
     TimeAdded represents the time at which the taint was added. It is only
     written for NoExecute taints.
   value  <string>
     The taint value corresponding to the taint key.

taint的子选项effect有三个结果定义:


1,NoSchedule:表示k8s将不会将Pod调度到具有该污点的Node上
2,PreferNoSchedule:表示k8s将尽量避免将Pod调度到具有该污点的Node上
3,NoExecute:表示k8s将不会将Pod调度到具有该污点的Node上,同时会将Node上已经存在的Pod驱逐出去

污点的设置:


例如设置node2节点污点为NoExecute(这里的key=value 可以随意设置,比如,A=B:noExecute

也是OK的,但最好有意义,后面的容忍会用到key和values的值):

kubectl taint nodes k8s-node2 key=value:NoExecute

查看节点和pod(可以看到,node2不可调度,并且其上的pod都被Terminating,因为busybox这个pod我是设置了nodeSelector   ):

[root@master coredns]# k get no
NAME         STATUS                     ROLES    AGE   VERSION
k8s-master   Ready                      <none>   25d   v1.18.3
k8s-node1    Ready                      <none>   25d   v1.18.3
k8s-node2    Ready,SchedulingDisabled   <none>   25d   v1.18.3
[root@master coredns]# k get po -A -owide
NAMESPACE     NAME                       READY   STATUS        RESTARTS   AGE    IP               NODE         NOMINATED NODE   READINESS GATES
default       busybox-68c4f6755d-24f79   0/1     Terminating   0          18s    <none>           k8s-node2    <none>           <none>
default       busybox-68c4f6755d-26f5j   0/1     Terminating   0          34s    <none>           k8s-node2    <none>           <none>
default       busybox-68c4f6755d-28m4l   0/1     Terminating   0          42s    <none>           k8s-node2    <none>           <none>
default       busybox-68c4f6755d-2bb7z   0/1     Terminating   0          39s    <none>           k8s-node2    <none>           <none>
default       busybox-68c4f6755d-2gkss   0/1     Terminating   0          4s     <none>           k8s-node2    <none>           <none>
default       busybox-68c4f6755d-2gpq4   0/1     Terminating   0          87s    <none>           k8s-node2    <none>           <none>
kube-system   kube-flannel-ds-mlb7l      1/1     Terminating   6          25d    192.168.217.18   k8s-node2    <none>           <none>

解除污点


1. kubectl taint nodes k8s-node2 key:NoExecute-
2. kubectl uncordon k8s-node2

污点的查看


1. [root@master ~]# kubectl describe nodes k8s-node2 |grep Taints
2. Taints:             key=value:NoSchedule

OK,现在node2有污点,此节点不调度新pod,那么,我们来部署一个三副本的pod看看能否成功:

[root@master coredns]# cat test.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: busybox
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: busybox
  template:
    metadata:
      labels:
        app: busybox
    spec:
 #     nodeName: k8s-node2
      containers:
      - name: busybox
        image: busybox:1.28.3
        imagePullPolicy: IfNotPresent
        args:
        - /bin/sh
        - -c
        - sleep 10; touch /tmp/healthy; sleep 30000

可以看到,pod确实没有在node2上,即使副本数修改为10个,仍然是不会调度到node2这个节点。

[root@master coredns]# k get po -o wide
NAME                       READY   STATUS    RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES
busybox-7bf6d6f9b5-5qzfn   1/1     Running   0          44s   10.244.1.10   k8s-node1    <none>           <none>
busybox-7bf6d6f9b5-j72q7   1/1     Running   0          44s   10.244.0.14   k8s-master   <none>           <none>
busybox-7bf6d6f9b5-mgt8j   1/1     Running   0          44s   10.244.0.15   k8s-master   <none>           <none>


相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
存储 Kubernetes 开发者
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
Docker 是一种开源的应用容器引擎,允许开发者将应用程序及其依赖打包成可移植的镜像,并在任何支持 Docker 的平台上运行。其核心概念包括镜像、容器和仓库。镜像是只读的文件系统,容器是镜像的运行实例,仓库用于存储和分发镜像。Kubernetes(k8s)则是容器集群管理系统,提供自动化部署、扩展和维护等功能,支持服务发现、负载均衡、自动伸缩等特性。两者结合使用,可以实现高效的容器化应用管理和运维。Docker 主要用于单主机上的容器管理,而 Kubernetes 则专注于跨多主机的容器编排与调度。尽管 k8s 逐渐减少了对 Docker 作为容器运行时的支持,但 Doc
644 5
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
|
Kubernetes Cloud Native 开发者
云原生入门:Kubernetes的简易指南
【10月更文挑战第41天】本文将带你进入云原生的世界,特别是Kubernetes——一个强大的容器编排平台。我们将一起探索它的基本概念和操作,让你能够轻松管理和部署应用。无论你是新手还是有经验的开发者,这篇文章都能让你对Kubernetes有更深入的理解。
|
Kubernetes Cloud Native 微服务
云原生入门与实践:Kubernetes的简易部署
云原生技术正改变着现代应用的开发和部署方式。本文将引导你了解云原生的基础概念,并重点介绍如何使用Kubernetes进行容器编排。我们将通过一个简易的示例来展示如何快速启动一个Kubernetes集群,并在其上运行一个简单的应用。无论你是云原生新手还是希望扩展现有知识,本文都将为你提供实用的信息和启发性的见解。
|
存储 运维 Kubernetes
K8s业务迁移最佳实践: 灵活管理资源备份与调整策略,实现高效简便的应用恢复
在当今快速变化的云原生领域,Kubernetes(K8s)集群的运维面临着诸多挑战,其中灾备与业务迁移尤为关键。ACK备份中心支持丰富的资源调整策略,在数据恢复阶段即可自动适配目标集群环境,确保业务无缝重启。
|
运维 Kubernetes Cloud Native
云原生技术入门:Kubernetes和Docker的协同工作
【10月更文挑战第43天】在云计算时代,云原生技术成为推动现代软件部署和运行的关键力量。本篇文章将带你了解云原生的基本概念,重点探讨Kubernetes和Docker如何协同工作以支持容器化应用的生命周期管理。通过实际代码示例,我们将展示如何在Kubernetes集群中部署和管理Docker容器,从而为初学者提供一条清晰的学习路径。
|
Kubernetes 负载均衡 Cloud Native
探索Kubernetes:云原生应用的基石
探索Kubernetes:云原生应用的基石
|
Kubernetes Cloud Native 云计算
云原生入门:Kubernetes 和容器化基础
在这篇文章中,我们将一起揭开云原生技术的神秘面纱。通过简单易懂的语言,我们将探索如何利用Kubernetes和容器化技术简化应用的部署和管理。无论你是初学者还是有一定经验的开发者,本文都将为你提供一条清晰的道路,帮助你理解和运用这些强大的工具。让我们从基础开始,逐步深入了解,最终能够自信地使用这些技术来优化我们的工作流程。
|
应用服务中间件 调度 nginx
Kubernetes-项目中pod调度使用法则
前言kubernetes中部署的pod默认根据资源使用情况自动调度到某个节点。可在实际项目的使用场景中都会有更细粒度的调度需求,比如:某些pod调度到指定主机、某几个相关的服务的pod最好调度到一个节点上、Master节点不允许某些pod调度等。
2212 0
|
Kubernetes 应用服务中间件 调度
Kubernetes之Pod调度
Kubernetes调度器根据特定的算法与策略将pod调度到工作节点上。在默认情况下,Kubernetes调度器可以满足绝大多数需求,例如调度pod到资源充足的节点上运行,或调度pod分散到不同节点使集群节点资源均衡等。
1616 0
|
Kubernetes 应用服务中间件 调度
Kubernetes之Pod调度
本文讲的是Kubernetes之Pod调度【编者的话】Kubernetes调度器根据特定的算法与策略将pod调度到工作节点上。在默认情况下,Kubernetes调度器可以满足绝大多数需求,例如调度pod到资源充足的节点上运行,或调度pod分散到不同节点使集群节点资源均衡等。
2980 0

推荐镜像

更多