浅析Pod调度

目录

前言

nodeName

作用

应用场景

使用方法

nodeSelect

作用

应用场景

使用方法

Pod/Node亲和反亲和

硬软亲和

硬亲和

软亲和

Pod Affinity

作用

应用场景

使用方法

Pod AntiAffinity

作用

应用场景

使用方法

Node Affinity

作用

应用场景

使用方法

Node AntiAffinity

作用

应用场景

使用方法

污点/污点容忍

作用

应用场景

使用方法

注意点

拓展

Qos服务质量

作用

Qos类型

使用方法

Pod优先级(PriorityClass)

作用

使用方法

资源限制(limit、request)

作用

使用方法

注意点



前言

        本文将探讨 Kubernetes 中关键的调度和资源管理概念,包括 nodeName、nodeSelector、Pod/Node 的亲和性与反亲和性、污点与污点容忍、服务质量(QoS)、Pod 优先级(PriorityClass)以及资源限制(limits 和 requests)。这些功能和策略共同构成了 Kubernetes 强大的调度机制,使得管理员能够基于各种条件和需求,灵活地管理 Pod 的调度和运行。通过具体的设置和应用场景,我们将初步理解这些概念如何共同作用于 Pod 的调度过程,以及它们如何帮助提高集群的效率和应用的可靠性。


nodeName

作用

        指定节点名称,用于将Pod调度到指定的Node上,不经过调度器,优先级最高,如果节点挂了,也不会分配到其他节点

应用场景

  • 调试、测试

使用方法

apiVersion: v1
kind: Pod
metadata:
  name: example-pod
spec:
  nodeName: node-1     #在此处设置想让pod调度到哪个node节点上
  containers:
  - name: example-container
    image: example-image
    ports:
    - containerPort: 80

nodeSelect

作用

        将 Pod 约束到具有特定标签的节点上运行。通过在 Pod 的配置文件中指定 nodeSelector 字段,可以确保 Pod 只在满足特定条件的节点上进行调度和运行

应用场景

  • 调度Pod至专用节点:根据场景需求将Node分组管理,nodeSelector 可以确保 Pod 只在为特定用途预留的节点上运行
  • 把有特殊需求的Pod调度至特殊配置节点的Node:如对SSD磁盘或GPU有硬件要求的业务Pod则调度至具有相关标签的Node上

使用方法

1、给节点打上标签

kubectl label nodes node-1 disk=ssd

2、查看节点标签

kubectl get nodes --show-labels

3、在Pod的Yaml中添加nodeSelect字段,需要注意的是如果node上没有能够与yaml中nodeselector匹配的标签,则pod会一直处于pending状态

apiVersion: v1
kind: Pod
metadata:
  name: ssd-pod
spec:
  nodeSelector:    #在此处配置nodeSelector相关信息
    disk: ssd  
  containers:
  - name: nginx-container
    image: nginx


Pod/Node亲和反亲和

硬软亲和

硬亲和

        requiredDuringSchedulingIgnoredDuringExecution 这个参数指定了调度期间必须满足的亲和性或反亲和性条件。一旦 Pod 被调度(即,在创建时),这些规则就会被评估并应用。如果满足条件,Pod 将被调度到符合规则的节点上。如果在调度过程中没有任何节点满足这些条件,那么Pod会处于Pending

软亲和

        preferredDuringSchedulingIgnoredDuringExecution,与上述参数作用类似,不过它定义的是优先级而非硬性要求。调度器会尽量满足这些条件,但如果无法满足,Pod 仍然会被调度


Pod Affinity

作用

        使得 Pod 倾向于或不倾向于被调度到与符合特定规则的 Pod 同一节点上。

应用场景

  • 保证相关联的应用组件(如前端和后端服务,存在大量数据交互的服务)部署在相近的位置,以减少通信延迟。

使用方法

        这个例子中,podAffinity 要求该 Pod 被调度到运行带有标签 app=frontend 的 Pod 的同一个节点上

apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  replicas: 2
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      affinity:
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - backend
            topologyKey: "kubernetes.io/hostname"
      containers:
      - name: nginx-container
        image: nginx

Pod AntiAffinity

作用

        定义 Pod 间的排斥规则,确保 Pod 不会被调度到与符合特定规则的 Pod 同一节点上。

应用场景

  • 分散相同类型的应用实例,如多个计算类型的Pod、多个需要GPU类型的Pod
  • 高容灾能力,避免单点故障,如:ingress-controller pod、core-dns pod等

使用方法

        在 Pod 的 affinity.podAntiAffinity字段中定义反亲和性规则,通常使用标签选择器来指定排斥的 Pod。这个例子中,podAntiAffinity 要求该 Pod 不能被调度到运行带有标签 app=database的 Pod 的同一个节点上

apiVersion: apps/v1
kind: Deployment
metadata:
  name: database
spec:
  replicas: 3
  selector:
    matchLabels:
      app: database
  template:
    metadata:
      labels:
        app: database
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - database
            topologyKey: "kubernetes.io/hostname"
      containers:
      - name: db-container
        image: postgres

Node Affinity

作用

        根据节点的标签约束 Pod 被调度到特定节点或节点组。

应用场景

  • 将 Pod 调度到具有特定硬件属性(如 GPU)的节点,或满足特定需求(如地理位置)的节点。如:需要GPU资源的Pod,则调度到安装了GPU显卡的Node上

使用方法

        在 Pod 的 affinity.nodeAffinity 字段中设置节点选择规则,通过节点标签和表达式来指定所需的节点特性

        这个例子中,NodeAffinity 要求该 Pod 必须调度到运行带有标签 hardware=gpu的 Node节点上

apiVersion: apps/v1
kind: Deployment
metadata:
  name: gpu-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: gpu-app
  template:
    metadata:
      labels:
        app: gpu-app
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: hardware
                operator: In
                values:
                - gpu
      containers:
      - name: cuda-container
        image: nvidia/cuda

Node AntiAffinity

作用

        确保 Pod 不会被调度到具有特定标签或满足某些条件的节点上。

应用场景

  • 避免将 Pod 调度到不适合的节点,如具有不兼容硬件的节点。

使用方法

        使用 nodeAffinityNotInDoesNotExist 操作符定义节点反亲和性规则,以排除不希望 Pod 调度的节点。

        这个 Deployment 的 Pod 不会被调度到标签 hardware=high-performance 的节点上

apiVersion: apps/v1
kind: Deployment
metadata:
  name: legacy-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: legacy-app
  template:
    metadata:
      labels:
        app: legacy-app
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: hardware
                operator: NotIn
                values:
                - high-performance
      containers:
      - name: legacy-app-container
        image: legacy-app

污点/污点容忍

作用

污点(Taints)
        污点允许节点拒绝某些 Pod 除非该 Pod 具有相应的容忍度。污点通过键值对和效果进行定义,效果可以是 NoSchedule、PreferNoSchedule 或 NoExecute

污点容忍(Tolerations)
        污点容忍允许 Pod 调度到带有特定污点的节点上。Pod 的容忍度需要与节点的污点匹配,这样 Pod 才能被调度到该节点

应用场景

污点

  • 专用节点: 为特定类型的 Pod 保留节点,例如,只让数据库 Pod 运行在特定的节点上。
  • 节点维护: 在节点维护期间,通过添加污点来阻止新的 Pod 调度到该节点上。

污点容忍

  • 专用部署: 允许特定的 Pod 在有污点的专用节点上运行,比如,只允许有 GPU 容忍度的 Pod 在带有 GPU 的节点上运行。

使用方法

1、给节点添加污点

kubectl taint nodes node1 key1=value1:NoSchedule
#node1 是节点的名称。
#key1=value1是污点的键值对。
#NoSchedule 是污点的效果,可以是 NoSchedule、PreferNoSchedule 或 NoExecute

effect污点类型

  • NoSchedule:当节点被打上此类污点时,Kubernetes 不会把新的 Pod 调度到这个节点上。
  • PreferNoSchedule:此类污点告诉 Kubernetes 尽可能避免将新的 Pod 调度到带有该污点的节点上,但这不是一个强制性的限制。
  • NoExecute:该污点不仅阻止新的 Pod 被调度到节点上,还会导致该节点上已运行的 Pod 被驱逐,除非这些 Pod 明确声明了对该污点的容忍。

2、Pod 配置中添加污点容忍
在 的 YAML 文件中定义容忍度,具有相应容忍度的 Pod 将能够调度到具有相匹配污点的节点上,而其他 Pod 则会被排除在外:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: tolerant-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: tolerant-app
  template:
    metadata:
      labels:
        app: tolerant-app
    spec:
      tolerations:
      - key: "key1"
        operator: "Equal"
        value: "value1"
        effect: "NoSchedule"
      containers:
      - name: tolerant-container
        image: nginx

注意点

  • 污点的灵活性: 污点可以只通过  key  来定义,不一定需要指定  value 。这样的污点影响所有没有相应容忍度的 Pod。
  • 污点容忍非强制调度: 即使 Pod 配置了对某个污点的容忍,也不意味着它一定会被调度到带有该污点的节点上。污点容忍只是扩大了 Pod 的调度可能性。
  • 容忍度增加调度灵活性: Pod 的污点容忍配置相当于增加了匹配条件,让 Pod 可以在更多节点上运行。条件越多,匹配越精确。
  • 容忍度与污点效果的关系: 即使 Pod 没有配置对应的污点容忍,它仍可能被调度到带有  PreferNoSchedule  污点的节点上,因为  PreferNoSchedule  是软性限制。
  • 容忍类型需要与节点污点的效果相对应: 如果节点的污点效果为  NoExecute  而 Pod 的容忍度效果为  NoSchedule ,则 Pod 只会在没有  NoExecute  污点的节点上调度,展示了效果匹配的重要性。


拓展

Qos服务质量

作用

        服务质量 (QoS, Quality of Service) 是一种技术,在 Kubernetes 中,QoS 可以用于控制 Pod 的调度、 资源限制、自动重启等行为,以此保证应用程序的高可用性和性能

Qos类型

Guaranteed(保证型):Pod 有确定的 CPU 和内存资源,不受其他 Pod 影响,遇故障或重启时优先恢复。
Burstable(突发型):Pod 可超额使用资源应对高峰,可能与其他 Pod 竞争资源,资源紧张时可能被终止。
BestEffort(尽力型):Pod 需与所有节点进程竞争资源,性能受影响,资源不足时优先被终止。

优先级:Guaranteed > Burstable > BestEffort

使用方法

通过配置Pod的limit和request来实现

  • Guaranteed: 所有容器(包括初始化容器)都设置了相等的 requestslimits
  • Burstable: 至少一个容器设置了不相等的 requestslimits,或者只设置了 limits
  • BestEffort: 所有容器均未设置 requestslimits


Pod优先级(PriorityClass

作用

  • Pod 可配置优先级,表示其相对重要性。
  • 调度器可驱逐低优先级 Pod 以调度高优先级 Pod

使用方法

PriorityClass
- 定义优先级的集群范围对象,内置 system-cluster-critical 和`system-node-critical

1、查看PriorityClass

kubectl get pc

2、定义 PriorityClass

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: high-priority
value: 1000000    #定义优先级值,范围 [0-1000000000]
globalDefault: false  #若为 true,未指定 priorityClassName 的 Pod 使用此优先级
description: "用于 XYZ 服务的 Pod"

3、在 Pod 中指定优先级

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx
  priorityClassName: high-priority  #指定pod对应的优先级

4、通过命令查看Pod优先级

kubectl describe pod/nginx # 优先级1000000解析并填充到 podSpec 的 priority 字段

资源限制(limit、request)

作用

        LimitsRequests 是 Kubernetes 中用于管理 Pod 资源(如 CPU 和内存)的关键参数。Kubernetes 调度器会根据这些请求值将 Pod 调度到有足够资源的节点上

  • Requests: 指定了 Pod 启动时最低需要的资源量。调度器使用这个值来决定将 Pod 放置在哪个节点上,以确保每个 Pod 有足够的资源来运行。
  • Limits: 指定了 Pod 可以消耗的资源的最大量。它防止了 Pod 占用过多的节点资源,影响到其他 Pod

使用方法

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.19.0
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"

注意点

  1. requestslimits: requests 定义了 Pod 启动所需的最小资源量,而 limits 指定了 Pod 可使用的最大资源量。
  2. 设置建议: 通常建议将 requests 设置为 limits 的 20%-30%,以保证资源的有效利用;requests 应小于或等于 limits。
  3. 宿主机资源限制: limits 不应超过节点的物理资源,以避免无效的资源限制。
  4. 调度影响: requests 值影响 Pod 的调度,节点必须满足这些请求值,否则 Pod 将处于 pending 状态。
  5. 资源预留: requests 仅表示资源预留,并非宿主机的实际占用。
  6. 默认行为: 若仅设置 limits 未设置 requests,默认将 requests 与 limits 设置为相同值。
  7. 集群容量: 较大的 requests 值可能限制集群可容纳的 Pod 数量,而较小的值可能增加容纳数量。
  8. 资源不足处理: 如果 Pod 的 requests 大于节点资源,Pod 将一直处于 pending 状态。CPU 作为可压缩资源,超出 limits 时将限制 CPU 使用率而不会终止 Pod;内存是不可压缩资源,超出 limits 会导致 OOM kill。

Pod调度过程

调度分为几个部分:

  1. 首先是过滤掉不满足条件的节点,这个过程称为预选(predicate)
  2. 然后对通过的节点按照优先级排序,这个是优选(priority)
  3. 最后从中选择优先级最高的节点。如果中间任何一步骤有错误,就直接返回错误。

 预选(predicate)有一系列的算法可以使用:

  • PodFitsResources :节点上剩余的资源是否大于pod 请求的资源
  • PodFitsHost :如果pod 指定了NodeName,检查节点名称是否和NodeName匹配
  • PodFitsHostPorts :节点上已经使用的port是否和pod申请的port冲突
  • PodselectorMatches :过滤掉和pod指定的 label 不匹配的节点
  • NoDiskConflict :已经mount的volume和pod指定的volume不冲突,除非它们都 是只读

如果在predicate 过程中没有合适的节点,pod 会一直在 pending 状态,不断重试调度,直到有节点满足条件。经过这个步骤,如果有多个节点满足条件,就继续 priorities 过程:按照优先级大小对节点排序。

Pod调度策略

  1. 默认调度策略:此策略致力于在不满足Pod需求的情况下找到代价最小的节点。如果没有合适的节点,系统可能会考虑移除一些已部署的Pod以为新Pod腾出空间,从而确保资源分配的高效性。(预选阶段)

  2. 优先级调度策略:根据Pod的优先级进行节点排序,优先部署优先级高的Pod。这通过为Pod设置不同的PriorityClass来实现,以保证关键服务的高可用性。(优选阶段)

  3. 节点亲和性调度策略:依据节点的标签或其他属性,选取与Pod需求相符的节点。此策略通过在Pod配置中设置NodeAffinity来指定,以确保Pod部署在最适合的节点上。(预选阶段)

  4. Pod亲和性调度策略:根据已部署Pod的标签和属性,选择与这些Pod相似或关联的节点。通过在Pod配置中使用PodAffinity设置,此策略有助于将相互关联的服务部署在邻近的位置,以提高整体的服务效率和响应速度。(预选阶段)

  5. Pod互斥性调度策略:选择与待部署Pod不同或无关的节点,避免在同一节点上运行过多相似的Pod。通过PodAntiAffinity配置实现,这有助于分散风险,提高系统的健壮性。(预选阶段)

  6. 资源限制调度策略:优先选择资源充足的节点,满足Pod的资源要求。这通常通过设置Pod的ResourceLimits来实现,确保每个Pod都能获得必要的资源,从而保证服务的稳定性和性能。(预选阶段)

  • 40
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值