K8s的Pod调度策略详解及实战(Detailed Explanation and Practical Application of Pod Scheduling Strategy for K8s)

K8s的Pod调度策略详解及实战

在Kubernetes (K8s) 中,Pod调度策略是确保你的应用能够在合适的节点上运行的关键因素。Kubernetes 提供了多种调度策略和配置选项,以适应不同的应用需求和资源限制。本章主要详细介绍Pod的几种常用调度策略,并根据实战操作来加深原理理解,在生产环境也经常使用。

Pod 的调度策略主要包括:

  • nodeSelector

  • 亲和性与反亲和性

  • nodeName

  • Pod 拓扑分布约束

  • 污点与容忍性

1. Pod调度概述

调度器通过 Kubernetes 的监测(Watch)机制来发现集群中新创建且尚未被调度到节点上的 Pod。调度的主要任务是将Pod分配到集群中的合适的节点上。调度器根据Pod的需求(如CPU、内存、存储等)和节点的资源状况(如可用CPU、内存、节点标签等)来决定Pod部署在哪个节点上。

调度已经在前面文章讲解过了,就不详细展开了。下面就详细介绍一下具体的调度策略

2. 调度策略详解

2.1 nodeSelector

nodeSelector 是 Kubernetes 中最简单、最直观的调度机制,它基于节点标签进行 Pod 调度。节点标签是 Kubernetes 用于标识节点属性的键值对,调度器会根据这些标签来决定将 Pod 调度到哪个节点。

工作原理:

每个 Kubernetes 节点可以具有多个标签(labels)。标签是 key: value 的形式,通常表示节点的特征,如硬件类型、地区、环境等。

Pod 的 nodeSelector 字段指定一组标签,调度器会筛选出具有这些标签的节点,然后将 Pod 调度到这些节点。

使用场景:

  • 环境隔离:比如,你有一些节点专门用于生产环境,其他节点用于测试环境,使用 nodeSelector 来确保 Pod 只在生产节点上运行。

  • 硬件要求:例如,某些应用需要 SSD 磁盘或特定的 CPU 类型,你可以使用 nodeSelector 来确保 Pod 调度到符合这些硬件要求的节点。

实战操作:

1、给节点打上标签

# 给k8s-node2节点打上ssd标签
kubectl label node  k8s-node2 disktype=ssd

# 查看标签
kubectl get node k8s-node1 --show-labels

2、编写yaml文件

【温馨提示】生产环境不要直接运行pod,这里只是为了演示效果

vim nodeSelector.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  nodeSelector:
    disktype: ssd
  containers:
  - name: nginx
    image: docker.m.daocloud.io/nginx:1.25

运行pod

kubectl apply -f nodeSelector.yaml

3、查看pod调度情况

[root@k8s-master data]# kubectl get pod -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP               NODE        NOMINATED NODE   READINESS GATES
nginx   1/1     Running   0          60s   10.224.169.149   k8s-node2   <none>           <none>

已经根据节点标签将pod调度到node2节点。

nodeSelector的优缺点:

  • 优点:简单高效。

  • 缺点:灵活性差,无法处理复杂的调度需求。

2.2 亲和性与反亲和性

亲和性(Affinity)和反亲和性(Anti-Affinity)是比 nodeSelector 更强大、更灵活的调度策略。它们允许用户根据更多的条件进行节点选择,比如节点的标签、Pod 的存在与否等。

亲和性(Affinity)用于指定 Pod 需要尽量调度到某些节点上,基于节点标签、Pod 与节点的关系等。 

反亲和性(Anti-Affinity)用于指定 Pod 不应该调度到某些节点,或者应该尽量避免和其他 Pod 调度到同一个节点上。

Kubernetes 中有两种亲和性:

  • 节点亲和性(Node Affinity)

  • Pod 亲和性与反亲和性(Pod Affinity & Anti-Affinity)。

节点亲和性

节点亲和性是 nodeSelector 的增强版,允许基于更复杂的规则选择节点。

实战操作

1、编写yaml文件

vim nodeAffinity.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx2
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: disktype
            operator: In
            values:
            - ssd
  containers:
  - name: nginx2
    image: docker.m.daocloud.io/nginx:1.25

确保 Pod 只会调度到具有 disktype=ssd标签的节点。

2、运行pod

kubectl apply -f nodeAffinity.yaml

3、查看pod调度情况

[root@k8s-master data]# kubectl get pod -o wide
NAME     READY   STATUS    RESTARTS   AGE     IP               NODE        NOMINATED NODE   READINESS GATES
nginx    1/1     Running   0          27m     10.224.169.149   k8s-node2   <none>           <none>
nginx2   1/1     Running   0          3m16s   10.224.169.154   k8s-node2   <none>           <none>

已经将pod调度到预期的node上

字段解释:

  • nodeAffinity 是定义节点选择规则的字段。通过 requiredDuringSchedulingIgnoredDuringExecution(必须满足调度时条件)和 preferredDuringSchedulingIgnoredDuringExecution(调度时首选,但不强制)来定义硬性和软性约束。

  • matchExpressions 支持使用 In、NotIn、Exists 等操作符,这些操作符使得你可以做更复杂的条件匹配。

operator 字段操作符说明:

操作符说明
In指定值必须在给定的列表中
NotIn指定值不在给定的列表中
Exists指定键存在,不关心值
DoesNotExist指定键不存在

Pod 亲和性

Pod 亲和性允许你指定 Pod 希望与其他 Pod 一起调度的偏好,而反亲和性则表示 Pod 希望避免与某些 Pod 一起调度。

1、给前面创建的pod打上app=nginx1的标签

# 给使用nodeSelector创建的nginx打上标签
kubectl label pod nginx app=nginx1

2、编写yaml文件

vim podAffinity.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx3
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:   # 满足条件才调度
      - labelSelector:
          matchExpressions:
            - key: app
              operator: In
              values:
                - nginx1
        topologyKey: "kubernetes.io/hostname"
  containers:
  - name: nginx3
    image: docker.m.daocloud.io/nginx:1.25

3、运行pod

kubectl apply -f podAffinity.yaml

4、查看调度情况

[root@k8s-master data]# kubectl get pod  -o wide
NAME     READY   STATUS    RESTARTS   AGE     IP               NODE        NOMINATED NODE   READINESS GATES
nginx    1/1     Running   0          4h32m   10.224.169.149   k8s-node2   <none>           <none>
nginx2   1/1     Running   0          4h8m    10.224.169.154   k8s-node2   <none>           <none>
nginx3   1/1     Running   0          14s     10.224.169.153   k8s-node2   <none>           <none>

可见pod已经调度到node2上,现在3个都运行在node2上,接下来测试一下反亲和性

Pod 反亲和性

要求 Pod 不与特定的 Pod 调度到同一节点上,通常用于防止某些类型的 Pod 集中到同一节点上,避免单点故障。

1、编写yaml文件

vim podAntiAffinity.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx4
spec:
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:   # 不要和具有app=nginx1标签的Pod在同一节点
            - key: app
              operator: In
              values:
                - nginx1
        topologyKey: "kubernetes.io/hostname"
  containers:
  - name: app
    image: docker.m.daocloud.io/nginx:1.25

2、运行pod

kubectl apply -f podAntiAffinity.yaml

3、查看调度情况

[root@k8s-master data]# kubectl get pod -o wide
NAME     READY   STATUS    RESTARTS   AGE     IP               NODE        NOMINATED NODE   READINESS GATES
nginx    1/1     Running   0          4h37m   10.224.169.149   k8s-node2   <none>           <none>
nginx2   1/1     Running   0          4h13m   10.224.169.154   k8s-node2   <none>           <none>
nginx3   1/1     Running   0          5m26s   10.224.169.153   k8s-node2   <none>           <none>
nginx4   1/1     Running   0          10s     10.224.36.69     k8s-node1   <none>           <none>

可以看到新建的nginx4避免与标签为 app=nginx1的 Pod 调度到同一节点上,所以被调度到node1上,验证了pod的反亲和性

亲和性和反亲和性优缺点:

优点:

  • 灵活性强:支持多条件、复杂的调度规则,可以基于节点标签、Pod 标签、拓扑结构等进行细粒度控制。

  • 支持跨节点调度:可以控制 Pod 在集群中的分布,增强应用的可用性和容错性。

缺点:

  • 配置复杂:调度规则更加复杂,理解和配置起来需要更多的时间。

  • 可能影响调度效率:当使用大量的亲和性和反亲和性规则时,调度器需要更多时间来评估每个节点的匹配情况。

2.3 nodeName

nodeName 是 Kubernetes 中一种最简单且强制性的调度方式,它允许你直接指定一个节点来运行 Pod,而无需依赖调度器的调度决策。nodeName 适用于一些特殊场景,比如需要将 Pod 调度到特定的节点(例如硬件节点,或特定的节点上有特定设备,如 GPU)。

实战操作:

1、编写yaml

vim nodeName.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx5
spec:
  nodeName: k8s-node1
  containers:
  - name: nginx5
    image: docker.m.daocloud.io/nginx:1.25

2、运行pod

kubectl apply -f nodeName.yaml

3、查看调度情况

[root@k8s-master data]# kubectl get pod nginx5 -o wide
NAME     READY   STATUS    RESTARTS   AGE   IP             NODE        NOMINATED NODE   READINESS GATES
nginx5   1/1     Running   0          47s   10.224.36.70   k8s-node1   <none>           <none>

可以看到Pod nginx5 会被直接调度到 node1节点上。

nodeName优缺点:

  • 优点:简单、直观,适用于需要特定硬件或设备的场景。

  • 缺点:失去调度器的灵活性,不适用于动态环境。

2.4 Pod 拓扑分布约束

Pod 拓扑分布约束用于保证 Pod 在多个节点、区域或故障域中的均衡分布。通过设置 topologySpreadConstraints,可以确保 Pod 在集群中分布更加均衡,避免 Pod 集中到某个节点或某个区域,从而增强集群的高可用性和容灾能力。

apiVersion: v1
kind: Pod
metadata:
  name: nginx6
spec:
  topologySpreadConstraints:
  - maxSkew: 1
    topologyKey: kubernetes.io/hostname
    whenUnsatisfiable: DoNotSchedule
    labelSelector:
      matchLabels:
        app: nginx
  containers:
  - name: nginx6
    image: docker.m.daocloud.io/nginx:1.25
[root@k8s-master data]# kubectl get pod nginx6 -o wide
NAME     READY   STATUS    RESTARTS   AGE   IP             NODE        NOMINATED NODE   READINESS GATES
nginx6   1/1     Running   0          37s   10.224.36.71   k8s-node1   <none>           <none>

使用deployment来演示可能效果更明显

topologySpreadConstraints 保证 nginx Pod 在不同的主机上均匀分布。maxSkew 控制 Pod 在各个节点之间的最大不平衡度,而 topologyKey 是表示分布维度的关键字段,kubernetes.io/hostname 表示按主机名进行分布。

优缺点:

  • 优点:保证 Pod 在多个节点、区域的均衡分布,提高高可用性。

  • 缺点:配置较复杂,可能对调度性能产生影响。

2.5 污点与容忍性

污点(Taints)和容忍性(Tolerations)是 Kubernetes 的一对调度机制,用于控制 Pod 是否能调度到带有某些特定条件的节点。节点可以加上污点,只有设置了相应容忍性的 Pod 才能调度到这些节点。

污点(Taints) 是对节点的标记,表示该节点不希望接受不符合条件的 Pod。容忍(Tolerations) 是 Pod 上的标记,表示 Pod 能够“容忍”某些污点。

实战操作:

1、给节点加污点:

# 在节点1上添加污点
kubectl taint nodes k8s-node1 key=value:NoSchedule

【温馨提示】设置污点后,新建的pod如果没有设置容忍,都无法调度到该节点,已存在的pod不受影响。

2、Pod 上设置容忍性:

vim tolerations.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx7
spec:
  tolerations:   # 配置容忍规则,需要完全匹配才可以调度到有污点的节点
  - key: "key"
    operator: "Equal"
    value: "value"
    effect: "NoSchedule"
  containers:
  - name: nginx7
    image: docker.m.daocloud.io/nginx:1.25

3、查看调度情况

[root@k8s-master data]# kubectl get pod nginx7 -o wide
NAME     READY   STATUS    RESTARTS   AGE   IP             NODE        NOMINATED NODE   READINESS GATES
nginx7   1/1     Running   0          32s   10.224.36.72   k8s-node1   <none>           <none>

nginx7被调度到设置了污点的节点,说明tolerations生效了,容忍了污点。

4、去除污点(taint)

kubectl taint node k8s-node1 key-

优缺点:

  • 优点:提供了灵活的节点隔离和调度控制,适用于隔离特定类型的工作负载或维护节点。

  • 缺点:配置复杂,滥用污点可能导致资源浪费或 Pod 调度错误。

总结

Kubernetes 提供了多种调度策略,可以根据不同的需求灵活选择:

  • nodeSelector:简单的节点标签匹配调度。

  • 亲和性与反亲和性:更灵活的调度控制,基于节点和 Pod 之间的关系进行调度。

  • nodeName:直接指定节点进行调度。

  • Pod 拓扑分布约束:确保 Pod 在集群中的均衡分布,增强高可用性。

  • 污点与容忍性:通过污点和容忍性控制哪些 Pod 可以调度到哪些节点。

通过合理组合这些调度策略,你可以优化 Pod 的资源分配、提升集群的可靠性和性能。

To interpret the set of individual think-aloud results, you would typically follow a systematic process that involves the following steps: 1. Transcription: The first step is to transcribe the think-aloud sessions into a written format that can be easily analyzed. This involves listening to the recorded sessions and writing down the participant's verbalizations as accurately as possible. 2. Coding: The next step is to code the transcriptions by identifying themes or categories that represent the different aspects of the participant's performance. The coding scheme should be developed based on the research questions or objectives of the study. 3. Analysis: Once the coding scheme has been established, the transcriptions can be analyzed by reviewing each instance of a particular code and identifying patterns or trends. For example, if one of the codes is "comprehension," the analysis would involve reviewing all instances where the participant demonstrated good or poor comprehension skills. 4. Interpretation: The final step is to interpret the analysis by drawing conclusions from the data. This involves identifying the strengths and weaknesses of the participants based on the patterns observed in the data. For example, if the research question is to evaluate the effectiveness of a new educational software program, the coding scheme might include categories such as "correctness of responses," "time to complete tasks," and "ease of use." The analysis would involve reviewing each instance of these categories and identifying patterns in the data. The interpretation would then involve drawing conclusions about the strengths and weaknesses of the software program based on the patterns observed in the data. Overall, interpreting think-aloud results requires a careful and systematic approach that involves transcription, coding, analysis, and interpretation. By following this process, researchers can gain valuable insights into the cognitive processes of participants and identify areas for improvement in educational or training programs.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linux运维老纪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值