Skip to content

第二部分 高级调度与资源管理

调度是 Kubernetes 的核心能力之一。本部分深入讲解节点亲和性、Pod 亲和性、污点与容忍、优先级抢占、自定义调度器以及资源配额管理。


第 6 章 节点亲和性与 Pod 亲和性

6.1 节点亲和性(Node Affinity)

让 Pod 倾向于或必须调度到满足特定标签的节点。

yaml
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: disktype
            operator: In
            values:
            - ssd
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: zone
            operator: In
            values:
            - zone-a

6.2 Pod 亲和性(Pod Affinity)

让 Pod 与某些 Pod 运行在同一拓扑域(如节点、机架、可用区)。

yaml
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - cache
        topologyKey: kubernetes.io/hostname

6.3 Pod 反亲和性(Pod Anti-Affinity)

让 Pod 避免与某些 Pod 运行在同一拓扑域。

yaml
spec:
  affinity:
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: app
              operator: In
              values:
              - web
          topologyKey: kubernetes.io/hostname

6.4 本章练习

  1. 给节点打标签,使用节点亲和性调度 Pod。
  2. 让两个互相依赖的 Pod 调度到同一节点。
  3. 让同一 Deployment 的 Pod 尽量分散在不同节点。

第 7 章 污点、容忍与节点管理

7.1 污点(Taint)

污点是节点上的属性,用于排斥 Pod。

bash
# 添加污点
kubectl taint nodes node1 dedicated=gpu:NoSchedule

# 查看污点
kubectl describe node node1 | grep Taints

# 删除污点
kubectl taint nodes node1 dedicated=gpu:NoSchedule-

污点效果:

效果说明
NoSchedule不容忍的 Pod 不会被调度
PreferNoSchedule尽量避免调度
NoExecute已运行的 Pod 也会被驱逐

7.2 容忍(Toleration)

Pod 通过容忍来接受节点的污点。

yaml
spec:
  tolerations:
  - key: "dedicated"
    operator: "Equal"
    value: "gpu"
    effect: "NoSchedule"

7.3 节点维护

bash
# 驱逐节点上的 Pod
kubectl drain node1 --ignore-daemonsets --delete-emptydir-data

# 恢复节点可调度
kubectl uncordon node1

# 禁止新 Pod 调度(不驱逐现有 Pod)
kubectl cordon node1

7.4 本章练习

  1. 给节点添加 NoSchedule 污点,创建能容忍的 Pod。
  2. 练习 drain、cordon、uncordon 操作。
  3. 设计一个 GPU 专用节点池方案。

第 8 章 Pod 优先级与抢占

8.1 PriorityClass

PriorityClass 定义 Pod 的优先级。

yaml
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: high-priority
value: 1000000
globalDefault: false
description: "高优先级应用"
preemptionPolicy: PreemptLowerPriority

8.2 使用优先级

yaml
spec:
  priorityClassName: high-priority

8.3 抢占机制

当高优先级 Pod 无法调度时,可以抢占(驱逐)低优先级 Pod。

bash
# 查看抢占事件
kubectl get events --field-selector reason=Preempted

8.4 本章练习

  1. 创建高、中、低三个 PriorityClass。
  2. 创建不同优先级的 Pod,观察抢占行为。
  3. 配置非抢占式 PriorityClass。

第 9 章 自定义调度器

9.1 为什么需要自定义调度器

  • 默认调度器无法满足特殊调度需求
  • 多租户隔离
  • 机器学习任务调度
  • 资源感知调度

9.2 Scheduler Framework

Kubernetes Scheduler Framework 允许通过插件扩展调度器。

扩展点:

  • QueueSort
  • PreFilter、Filter
  • PostFilter
  • PreScore、Score
  • Reserve、Permit
  • Bind

9.3 使用自定义调度器

yaml
spec:
  schedulerName: my-scheduler

9.4 本章练习

  1. 了解 Scheduler Framework 的主要扩展点。
  2. 部署一个自定义调度器(如 kube-scheduler 的多副本 + leader election)。
  3. 让某个 Pod 使用自定义调度器。

第 10 章 资源配额与限制

10.1 ResourceQuota

限制命名空间资源总量。

yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: team-a-quota
  namespace: team-a
spec:
  hard:
    requests.cpu: "20"
    requests.memory: 40Gi
    limits.cpu: "40"
    limits.memory: 80Gi
    pods: "100"
    services: "20"

10.2 LimitRange

设置命名空间内 Pod/Container 的默认资源限制。

yaml
apiVersion: v1
kind: LimitRange
metadata:
  name: default-limits
  namespace: team-a
spec:
  limits:
  - default:
      cpu: "500m"
      memory: "512Mi"
    defaultRequest:
      cpu: "100m"
      memory: "128Mi"
    type: Container

10.3 资源分析

bash
# 查看命名空间资源使用
kubectl describe quota -n team-a

# 查看节点资源分配
kubectl describe node node1

10.4 本章练习

  1. 为某个命名空间设置 ResourceQuota。
  2. 为某个命名空间设置 LimitRange。
  3. 尝试创建超出配额的资源,观察报错。

第二部分总结

完成本阶段学习后,你应该能够:

  • 设计复杂的亲和性和反亲和性策略
  • 使用污点和容忍管理专用节点
  • 配置 Pod 优先级和抢占
  • 了解自定义调度器
  • 使用 ResourceQuota 和 LimitRange 管理多租户资源

进入第三部分:存储与 CSI 进阶