k8s的集群调度

schedule:负责调度资源,把pod调度到node节点

1、List-watch

k8s集群当中,通过list-watch的机制进行每个组件的协作,保持数据同步,保持数据同步,每个组件之间的解耦

kubectl 配置文件,向APIserver发送命令-----APIserver把命令发送各个组件

kubectl run nginx ---image=nginx:1.22 ---apiserver  ---controller manager ----scheduler ---kubelet

创建成功之后 kubectl get pod kubectl describe pod nginx  ------->> etcd 的数据库当中

list-watch --会在每一步把监听的消息(APIserver:6443)-----controller manager , scheduler,kubectl,etcd都会监听APIserver:6443端口

2、调度的过程和策略

scheduler是k8s集群的调度器,把pod分配到集群的节点上

以下几个问题

1、公平,每个节点都能够分配资源
2、资源高效利用  集群当中的资源可以被最大化使用
3、效率 调度的性能要好,能够尽快的完成大批量的pod的调度
4、灵活  允许用户根据自己的需求,控制和改变调度的逻辑(扩缩容)

scheduler是一个单独运行的程序,启动之后就会一直监听APIserver,获取报文中的字段 spec nodename

床架pod时,为每个pod创建一个binding,表示该往哪个节点上部署

创建pod 到节点时,有两个策略,先执行预算策略,再执行优先策略,这两步的操作都必须成功,否则立刻返回报错,也就是说,部署的node,必须满足这两个策略

预算策略: predicate 自带一些算法,选择node节点(scheduler自带额度算法策略,不需要人工干预)
1、podfitsresources:pod适应资源,检查节点上的剩余资源是否满足pod请求的资源,主要是cpu和内存
2、podfitshost:pod适应主机,如果pod指定了node的name,nginx1pod----node01 ,检测主机名是都存在,存在要和pod指定的名称匹配,这才能调度过去
3、podselectormatches:pod的选择器匹配,创建pod的时候可以根据node的标签来进行匹配,查找指定的node节点上标签是否存在,存在的标签是否匹配
4、nodiskconflict:无磁盘冲突,确保已挂载的卷与pod的卷不发生冲突  如node1 上  nginx1 pod opt/nginx
nginx2 pod opt/nginx冲突之后会把nginx2挂载node2节点上
如果预算策略都不满足,pod将始终处于pending状态,不断的重试调度,直到有节点满足条件为止
例如
node1 node2 node3 
经过预先策略,上述三个节点都满足条件,那该怎么办?---->> 优先策略
优先策略:
1、leastrequestedpriority:最低请求优先级,通过算法计算节点上的cpu和内存使用率,确定节点的权重,使用率越低的节点相应的权重越高,调度时会更倾向于使用率的节点,实现资源合理的利用
2、balanceresourceallocation:平衡资源分配,cpu和内存的使用率,给节点赋予权重,权重算的是cpu和内存使用率接近,权重越高,和上面的leastrequestedpriority最低请求优先级一起使用
例如:
node1 cpu和内存使用率 20:60
node2 cpu和内存使用率 50:50
node2 在被调度时会被优先
3、imagelocalityriority:节点上是否已经有了要部署的镜像,镜像的总数成正比,满足的镜像数越多,权重越好
例如
nginx1.22
node1 无
node2 有
node2 优先级高
以上策略都是scheduler自带的算法
通过预算选择出可以部署的节点,再通过优先选择出来最好的节点,以上都是自带的算法,k8s集群自己来选择
指定节点和标签
指定节点
spec参数设置:
  nodeName: node02

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.22
      nodeName: node02
指定了节点,在参数中设置了nodeName,指定了节点的名称,会跳过scheduler的调度策略,这个规则是强制匹配


指定标签
spec参数设置:
 nodeSelector: 

查看node节点上的标签
kubectl get nodes --show-labels 
命令行添加
kubectl label nodes node02 test3=c
如何删除标签
kubectl label nodes node01 test3-



apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      nodeSelector:
        test1: a
      containers:
      - name: nginx
        image: nginx:1.22
      nodeName: node02
指定节点标签部署pod,是经过scheduler,如果节点不满足条件,pod会进入pending状态,直到节点满足条件为止

node的亲和性

节点亲和性

pod亲和性

软策略和硬策略

node节点的亲和性:

node节点的亲和性:
preferredDuringSchedulingIgnoredDuringExecution  软策略:
选择node节点时,我声明了我最好能不输在node01,软策略会尽量满足这个条件,不一定会完全部署在node01节点上
requiredDuringSchedulingIgnoredDuringExecution   硬策略:选择pod时,声明了node01,我是硬策略,必须满足硬策略的条件,必须部署在node01 ,强制性要求

pod的亲和性:
preferredDuringSchedulingIgnoredDuringExecution  软策略:
要求调度器讲pod调度到其他pod的亲和性匹配的节点上,可以是,也可以不是,尽量满足
例如
pod  nginx1 node01
podnginx2 nginx2 希望和nginx1部署在一个节点上

requiredDuringSchedulingIgnoredDuringExecution   硬策略:
要求调度器讲pod调度到其他pod的亲和性匹配的节点上,必须是
例如
pod  nginx1 node01
pod nginx2 nginx2必须要和nginx的亲和性匹配,只能往node01
键值的运算关系
标签,都是根据标签来选择亲和性
In:在
选择的标签值,在node节点上存在
Notin:不在
选择label的值不再node节点上
Gt:大于,大于选择的标签值
Lt:小于,小于选择的标签值
Exists: 存在,选择标签对象,值不考虑。
DoesNotExist: 不存在, 选择不具有指定标签的对象。值不考虑。

软策略
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.22
      affinity:
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 1
            preference:
#选择节点的倾向,尽量满足要求而不是一定
              matchExpressions:
              - key: memory
                operator: In
                values:
                - "1000"



Gt:大于,大于选择的标签值
Lt:小于,小于选择的标签值
只能比较整数值
亲和性策略更具标签来进行选择

#指定键值对的算法Exists或者DoesNotExist  不能使用values字段

硬策略

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.22
      affinity:
#选择亲和性部署方式
        nodeAffinity:
#选择的是node节点的亲和性
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
#选择了亲和性的策略,nodeSelectorTerms你要选择哪个node作为硬策略,匹配的节点的标签
            - matchExpressions:
              - key: test3
                operator: In
#指定键值对的算法
                values:
                - c


软策略
多个软策略看权重,权重高,执行指定的软策略
硬策略:
先满足软策略,在满足硬策略
pod的亲和性和反亲和性
调度策略 匹配标签 操作符 拓扑域 调度目标
node的亲和性 主机标签 In NotIn exists DoesNotExist Gt Lt 不支持 指定主机
pod的亲和性 pod的标签 In NotIn exists DoesNotExist 支持 pod和指定标签的pod部署在同一拓扑域
pod的反亲和性 pod的标签 In NotIn exists DoesNotExist 支持 pod和指定标签的pod部署在不同拓扑域
拓扑域

k8s集群节点当中的一个组织结构,可以根据节点的物理关系或者逻辑关系进行划分,可以用来表示节点之间的空间关系,关系关系或者其他类型的关系

先给node节点设置标签

硬策略
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx1
  name: nginx1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx1
  template:
    metadata:
      labels:
        app: nginx1
    spec:
      containers:
      - image: nginx:1.22
        name: nginx
      affinity:
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: DoesNotExist
            topologyKey: test
# topologyKey 指定拓扑域的关键字段,表示正在使用test1作为拓扑域的关键字,test1 一般是节点标签,表示,希望把pod调度到包含有app标签的pod,值为nginx1的在test1的拓扑域上的节点



apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx1
  name: nginx1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx1
  template:
    metadata:
      labels:
        app: nginx1
    spec:
      containers:
      - image: nginx:1.22
        name: nginx
      affinity:
        podAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 1
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                 - key: app
                   operator: DoesNotExist
              topologyKey: test1
# topologyKey 指定拓扑域的关键字段,表示正在使用test1作为拓扑域的关键字,test1 一般是节点标签,表示,希望把pod调度到包含有app标签的pod,值为nginx1的在test1的拓扑域上的节点

反亲和性

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx1
  name: nginx1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx1
  template:
    metadata:
      labels:
        app: nginx1
    spec:
      containers:
      - image: nginx:1.22
        name: nginx
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 1
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                 - key: app
                   operator: In
                   values:
                   - nginx1
              topologyKey: test1



apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx1
  name: nginx1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx1
  template:
    metadata:
      labels:
        app: nginx1
    spec:
      containers:
      - image: nginx:1.22
        name: nginx
      affinity:
        podAntiAffinity:
         requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - nginx1
            topologyKey: test1

注意点:
1、pod的亲和性策略,在配置时,必须要加上拓扑域的关键字topologyKey指向的是节点标签
2、pod的亲和性的策略分为硬策略和软策略
3、pod的亲和性的notln可以替代反亲和性
4、pod亲和性只要是为了把相关联的pod部署在同一节点,lnmp
污点和容忍

污点

你在进行部署的时候怎么考虑node节点:

污点和容忍可以配合node的亲和性一块使用

污点:是node的调度机制,不是pod

被设为污点的节点,不会部署pod

污点和亲和性能相反,亲和性是尽量选择和一定选择

污点的节点一定不被选择?

taint三种:

1、NoSchedule k8s不会把pod调度到这个节点上

2、PreferNotSchedule 如果污点类型是它,尽量避免把pod部署在该节点上,不是一定(master节点的污点就是这个)

3、NotExecute 如果污点类型是它,k8s将会把节点上的pod驱逐出去,而且也不会调度到这个节点

基于控制器创建的pod,虽然被驱逐,会在其他节点重新部署

如何查看污点
kubectl describe nodes master01  | grep -i taints

如何设置污点
kubectl taint node node01 key=1:NoSchedule

去除污点
kubectl taint node node01 key:NoSchedule-

注意点:
节点服务器需要维护的,服务器关机,节点上pod将会失效,在工作中我们主要部署pod的方式控制器部署,deployment最多的,一旦节点设置为驱逐,控制器创建的pod会在其他节点重新部署
所有的pod都会被驱逐,跟命名空间无关,所有的一切的都会被驱逐
不论你的创建方式是什么,都会被驱逐
系统集群组件不会被驱逐
容忍

即使节点上设置了污点,有了容忍机制,依然可以在设置为污点你的节点上部署pod

NoSchedule类型

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx1
  name: nginx1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx1
  template:
    metadata:
      labels:
        app: nginx1
    spec:
      containers:
      - image: nginx:1.22
        name: nginx
      tolerations:
      - key: key
        operator: Equal
        value: "1"
        effect: NoSchedule
#容忍策略,容忍节点上的标签key,对应的标签值是1,effect就是对应的污点的类型



NoExecute类型
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx1
  name: nginx1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx1
  template:
    metadata:
      labels:
        app: nginx1
    spec:
      containers:
      - image: nginx:1.22
        name: nginx
      tolerations:
      - key: key
        operator: Equal
        value: "1"
        effect: NoExecute
        tolerationSeconds: 36
特殊情况:NoExecute依然可以部署pod,但是有生命周期,时间一到,pod会被销毁然后重新拉起
生命周期结束之后,会驱逐一部分pod到其他节点

      tolerations:
      - key: key
        operator: Equal
指定key的值,指定节点的标签值,但是不指定污点的类型,那么所有节点上只要包含了这个指定的标签名,可以容忍所有的污点


      tolerations:
      - operator: Exists
        effect: NoSchedule
没有key,不匹配节点标签,容忍所有污点,但是类型是指定的类型
污点的作用

node的亲和性

pod的亲和性和反亲和性

污点和容忍

如何选择node节点部署pod

选择一个期望的节点来部署pod

例:
多个master节点
kubectl taint node master节点名称 node-role.kubernetes.io/master=:PreferNoSchedule
尽量不往master节点上部署pod,但是不是一定的,防止资源浪费,自定义一个标签

业务维护
node02需要维护2个小时,但是这个节点还有业务pod在运行,就需要把这个节点的污点设置为:NoExecute
我们部署pod一般都是使用deployment部署,会在其他的重新部署,并不是被杀死
自主式的pod会被杀死

一旦节点恢复,一定把污点去除
cordon和drain

cordon:可以直接把节点标记为不可用状态

标记节点为不可用状态
kubectl cordon master01

[root@master01 opt]# kubectl get pod -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
nginx1-654cb56c4-5jt7q   1/1     Running   0          21s   10.244.2.45   node02   <none>           <none>
nginx1-654cb56c4-nbprv   1/1     Running   0          22s   10.244.2.44   node02   <none>           <none>
nginx1-654cb56c4-ppt55   1/1     Running   0          24s   10.244.2.43   node02   <none>           <none>


取消标记节点为不可用状态
kubectl uncordon master01

drain:排水,把该节点下的pod全部转移到其他的node节点上运行

使用标记会有两种变化
1、一旦执行drain,被执行的节点会变成不可调度状态
2、会驱逐该节点上的所有pod

kubectl drain node02 --ignore-daemonsets --delete-local-data --force

drain :排水,标记node节点为不可调度,然后驱逐pod
 --ignore-daemonsets  忽视daemonsets部署的pod,daemonsets部署的pod还在节点
 --delete-local-data  有本地挂载卷的pod会被强制杀死
--force  强制释放不是控制器管理的pod

还是如何管理和部署pod

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-01-09 17:56:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-09 17:56:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-09 17:56:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-09 17:56:02       18 阅读

热门阅读

  1. MySQL第五战:常见面试题(下)

    2024-01-09 17:56:02       35 阅读
  2. 秒杀业务

    2024-01-09 17:56:02       34 阅读
  3. Android-消息机制Handler

    2024-01-09 17:56:02       31 阅读
  4. 17.热帖排行 + 生成长图

    2024-01-09 17:56:02       29 阅读
  5. 详解Nacos和Eureka的区别

    2024-01-09 17:56:02       30 阅读