首页 智能穿戴

K8s Pod 调度秘籍:过滤、打分、亲和性与拓扑约束实战

分类:智能穿戴
字数: (3033)
阅读: (4428)
内容摘要:K8s Pod 调度秘籍:过滤、打分、亲和性与拓扑约束实战,

在 Kubernetes (k8s) 集群中,如何确保 Pod 被调度到合适的节点上运行,是保障应用稳定性和性能的关键。本文将深入探讨 k8s 中 Pod 和 Node 的调度故事,重点讲解过滤(Filtering)、打分(Scoring)、亲和性(Affinity)以及拓扑分布约束(Topology Spread Constraints)等核心概念,并结合实际案例进行分析,助你掌握更高级的 Pod 调度策略。

问题场景:Pod 总被调度到资源不足的节点?

假设我们有一个微服务应用,该应用需要大量的 CPU 和内存资源。在默认情况下,k8s 调度器可能会将 Pod 调度到资源相对紧张的节点上,导致应用性能下降甚至崩溃。例如,我们可能配置了 Nginx 作为反向代理,但由于 Pod 被调度到了 CPU 资源不足的节点,导致并发连接数上不去,最终影响整体服务质量。这时就需要我们手动干预 Pod 的调度策略。

底层原理:kube-scheduler 的调度流程

kube-scheduler 是 k8s 的核心组件之一,负责将 Pod 调度到最佳节点上。其主要流程包括:

K8s Pod 调度秘籍:过滤、打分、亲和性与拓扑约束实战
  1. 过滤(Filtering):scheduler 根据 Pod 的调度需求(例如资源需求、节点选择器等)过滤掉不符合条件的节点。
  2. 打分(Scoring):scheduler 对通过过滤的节点进行打分,评估其对 Pod 的亲和度。默认情况下,kube-scheduler 提供多种打分策略,例如 LeastRequestedPriority(选择资源占用最少的节点)和 BalancedResourceAllocation(平衡 CPU 和内存的利用率)。
  3. 选择最优节点:scheduler 选择得分最高的节点,并将 Pod 调度到该节点上。

亲和性(Affinity)与反亲和性(Anti-Affinity)

Node Affinity 允许我们基于节点的标签(Labels)来约束 Pod 的调度。它分为两种类型:

  • requiredDuringSchedulingIgnoredDuringExecution:必须满足亲和性规则才能调度,否则 Pod 将处于 Pending 状态。即使之后节点标签发生变化,Pod 也会继续运行。
  • preferredDuringSchedulingIgnoredDuringExecution:尽量满足亲和性规则,如果没有满足条件的节点,Pod 也可以被调度到其他节点上。同样,即使之后节点标签发生变化,Pod 也会继续运行。

Pod Affinity 允许我们基于其他 Pod 的标签来约束 Pod 的调度。同样分为 requiredDuringSchedulingIgnoredDuringExecutionpreferredDuringSchedulingIgnoredDuringExecution 两种类型。

K8s Pod 调度秘籍:过滤、打分、亲和性与拓扑约束实战

反亲和性(Anti-Affinity) 的作用与亲和性相反,它可以避免将某些 Pod 调度到同一个节点上,从而提高应用的可用性。

代码示例:使用 Node Affinity

apiVersion: v1
kind: Pod
metadata:
  name: node-affinity-example
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/hostname # 节点 hostname 标签
            operator: In # 操作符,可以是 In, NotIn, Exists, DoesNotExist, Gt, Lt
            values:
            - node1 # 节点 hostname
  containers:
  - name: nginx
    image: nginx:latest

上面的 YAML 文件定义了一个 Pod,该 Pod 必须被调度到 kubernetes.io/hostname 标签值为 node1 的节点上。如果集群中没有满足条件的节点,Pod 将一直处于 Pending 状态。在宝塔面板中,我们通常会给不同的节点打上不同的标签,方便进行精细化调度。

K8s Pod 调度秘籍:过滤、打分、亲和性与拓扑约束实战

拓扑分布约束(Topology Spread Constraints)

拓扑分布约束 (Topology Spread Constraints) 提供了一种更灵活的方式来控制 Pod 在不同拓扑域(例如节点、区域、可用区)上的分布。通过它可以实现更均匀的负载分布,提高应用的可用性和容错性。

代码示例:使用 Topology Spread Constraints

apiVersion: apps/v1
kind: Deployment
metadata:
  name: topology-spread-example
spec:
  replicas: 3
  selector:
    matchLabels:
      app: topology-spread-example
  template:
    metadata:
      labels:
        app: topology-spread-example
    spec:
      containers:
      - name: nginx
        image: nginx:latest
      topologySpreadConstraints:
      - maxSkew: 1 # 允许的最大倾斜度,表示在任何给定的拓扑域中,Pod 的数量差异不能超过 1
        topologyKey: kubernetes.io/hostname # 拓扑域,这里使用节点 hostname
        whenUnsatisfiable: DoNotSchedule # 当无法满足约束时,不调度 Pod
        labelSelector:
          matchLabels:
            app: topology-spread-example

上面的 YAML 文件定义了一个 Deployment,该 Deployment 包含 3 个 Pod。topologySpreadConstraints 定义了一个约束,要求 Pod 尽量均匀地分布在不同的节点上。maxSkew: 1 表示在任何节点上,Pod 的数量差异不能超过 1。whenUnsatisfiable: DoNotSchedule 表示当无法满足约束时,不调度 Pod。如果改为 ScheduleAnyway,则表示尽量满足约束,实在无法满足也可以调度。

K8s Pod 调度秘籍:过滤、打分、亲和性与拓扑约束实战

实战避坑经验

  • 仔细评估资源需求:在定义 Pod 的资源需求(CPU、内存)时,要进行充分的测试和评估,避免资源分配不足或过度分配。
  • 监控调度结果:通过监控 k8s 事件和 Pod 的状态,及时发现调度问题并进行调整。
  • 合理使用亲和性和反亲和性:亲和性和反亲和性可以有效控制 Pod 的调度位置,但过度使用也可能导致调度失败。需要根据实际需求进行权衡。
  • 灵活运用拓扑分布约束:拓扑分布约束提供了一种更灵活的调度控制方式,可以根据不同的场景进行配置,例如跨可用区部署、故障隔离等。
  • 注意标签的维护:节点和 Pod 的标签是亲和性和反亲和性的基础,需要确保标签的准确性和一致性。

总结

掌握 k8s 中 Pod 和 Node 的调度策略,可以帮助我们更好地管理和优化应用,提高应用的稳定性和性能。希望本文能够帮助你深入理解 k8s 的调度机制,并在实际应用中灵活运用过滤、打分、亲和性和拓扑分布约束等技术,构建更可靠、更高效的 Kubernetes 集群。

K8s Pod 调度秘籍:过滤、打分、亲和性与拓扑约束实战

转载请注明出处: 程序员DD

本文的链接地址: http://m.acea3.store/article/09949.html

本文最后 发布于2026-04-14 03:24:40,已经过了13天没有更新,若内容或图片 失效,请留言反馈

()
您可能对以下文章感兴趣
评论
  • 键盘侠本侠 3 天前
    学习了,正准备把服务迁移到 K8s,这些知识点太实用了,收藏了!
  • 非酋本酋 5 天前
    请教下,如果 node affinity 和 topology spread constraints 同时使用,优先级是怎样的?
  • 拖延症晚期 2 天前
    拓扑分布约束这个真不错,之前一直用 PodAffinity 做类似的事情,感觉复杂多了。
  • 咕咕咕 4 天前
    学习了,正准备把服务迁移到 K8s,这些知识点太实用了,收藏了!