HiHuo
首页
博客
手册
工具
首页
博客
手册
工具
  • Kubernetes 进阶

    • /books/k8s/
    • Kubernetes 高阶学习手册
    • 01-架构与核心概念
    • 02-网络体系
    • 03-存储管理
    • 04-调度控制
    • 05-发布与弹性
    • 06-安全与治理
    • 07-观测与SRE
    • 08-可靠性运维
    • 09-成本与容量
    • 10-故障排查
    • 11-运维工具
    • 12-生产清单
    • 13-AI平台集成

04-调度控制

Kubernetes 资源管理、亲和性、污点容忍策略深度解析

学习目标

通过本模块学习,你将掌握:

  • Kubernetes 调度器工作原理
  • 资源请求和限制管理
  • 节点亲和性和 Pod 亲和性
  • 污点和容忍机制
  • 拓扑感知调度
  • 调度故障排查技能

️ 一、调度器架构概览

调度器核心组件

┌─────────────────────────────────────────────────────────────┐
│                    Kubernetes Scheduler                    │
├─────────────────────────────────────────────────────────────┤
│  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐           │
│  │    Queue    │ │  Predicates │ │ Priorities  │           │
│  │   (队列)    │ │   (预选)    │ │   (优选)    │           │
│  └─────────────┘ └─────────────┘ └─────────────┘           │
│  ┌─────────────────────────────────────────────────────────┐ │
│  │                    Bind (绑定)                         │ │
│  └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘

调度流程详解

graph TD
    A[Pod 创建] --> B[加入调度队列]
    B --> C[预选阶段 Filter]
    C --> D[优选阶段 Score]
    D --> E[选择最佳节点]
    E --> F[绑定到节点]
    F --> G[kubelet 启动 Pod]

调度阶段说明

阶段名称功能输出
Queue调度队列管理待调度 Pod有序 Pod 列表
Filter预选阶段过滤不满足条件的节点候选节点列表
Score优选阶段为候选节点打分节点评分排序
Bind绑定阶段选择最高分节点并绑定Pod 调度完成

二、资源管理机制

2.1 资源类型

CPU 资源

resources:
  requests:
    cpu: "500m"      # 0.5 CPU 核心
  limits:
    cpu: "1000m"     # 1 CPU 核心

内存资源

resources:
  requests:
    memory: "512Mi"  # 512 MB
  limits:
    memory: "1Gi"    # 1 GB

存储资源

resources:
  requests:
    ephemeral-storage: "1Gi"
  limits:
    ephemeral-storage: "2Gi"

GPU 资源

resources:
  requests:
    nvidia.com/gpu: 1
  limits:
    nvidia.com/gpu: 1

2.2 QoS 分类

Kubernetes 根据资源设置自动分类 Pod 的 QoS 等级:

QoS 类型条件优先级说明
Guaranteedrequests == limits(CPU+内存都有)最高资源有保障
Burstablerequests < limits中等可突发使用
BestEffort无 requests/limits最低尽力而为

QoS 示例

# Guaranteed QoS
apiVersion: v1
kind: Pod
metadata:
  name: guaranteed-pod
spec:
  containers:
  - name: app
    image: nginx
    resources:
      requests:
        cpu: "100m"
        memory: "128Mi"
      limits:
        cpu: "100m"
        memory: "128Mi"

# Burstable QoS
apiVersion: v1
kind: Pod
metadata:
  name: burstable-pod
spec:
  containers:
  - name: app
    image: nginx
    resources:
      requests:
        cpu: "100m"
        memory: "128Mi"
      limits:
        cpu: "200m"
        memory: "256Mi"

# BestEffort QoS
apiVersion: v1
kind: Pod
metadata:
  name: besteffort-pod
spec:
  containers:
  - name: app
    image: nginx
    # 无 resources 配置

2.3 资源配额管理

ResourceQuota(资源配额)

apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: production
spec:
  hard:
    requests.cpu: "4"
    requests.memory: 8Gi
    limits.cpu: "8"
    limits.memory: 16Gi
    pods: "10"
    persistentvolumeclaims: "4"

LimitRange(资源限制)

apiVersion: v1
kind: LimitRange
metadata:
  name: mem-limit-range
  namespace: production
spec:
  limits:
  - default:
      memory: "512Mi"
    defaultRequest:
      memory: "256Mi"
    type: Container
  - max:
      memory: "1Gi"
    min:
      memory: "128Mi"
    type: Container

三、节点选择策略

3.1 nodeSelector(节点选择器)

特点:精确匹配节点标签

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  nodeSelector:
    disktype: ssd
    zone: us-west-1a
  containers:
  - name: nginx
    image: nginx

设置节点标签

# 添加标签
kubectl label node node1 disktype=ssd
kubectl label node node1 zone=us-west-1a

# 查看标签
kubectl get nodes --show-labels

# 删除标签
kubectl label node node1 disktype-

3.2 nodeAffinity(节点亲和性)

特点:支持复杂表达式匹配

硬约束(必须满足)

apiVersion: v1
kind: Pod
metadata:
  name: node-affinity-hard
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: disktype
            operator: In
            values: ["ssd", "nvme"]
          - key: zone
            operator: NotIn
            values: ["us-west-1c"]
  containers:
  - name: nginx
    image: nginx

软约束(优先考虑)

apiVersion: v1
kind: Pod
metadata:
  name: node-affinity-soft
spec:
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 50
        preference:
          matchExpressions:
          - key: zone
            operator: In
            values: ["us-west-1a"]
      - weight: 30
        preference:
          matchExpressions:
          - key: disktype
            operator: In
            values: ["ssd"]
  containers:
  - name: nginx
    image: nginx

操作符说明

操作符说明示例
In值在列表中values: ["ssd", "nvme"]
NotIn值不在列表中values: ["hdd"]
Exists标签存在无 values
DoesNotExist标签不存在无 values
Gt值大于values: ["100"]
Lt值小于values: ["1000"]

3.3 podAffinity(Pod 亲和性)

Pod 亲和(同节点部署)

apiVersion: v1
kind: Pod
metadata:
  name: web-pod
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values: ["redis"]
        topologyKey: kubernetes.io/hostname
  containers:
  - name: nginx
    image: nginx

Pod 反亲和(不同节点部署)

apiVersion: v1
kind: Pod
metadata:
  name: web-pod
spec:
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values: ["web"]
        topologyKey: kubernetes.io/hostname
  containers:
  - name: nginx
    image: nginx

软亲和示例

apiVersion: v1
kind: Pod
metadata:
  name: web-pod
spec:
  affinity:
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: app
              operator: In
              values: ["web"]
          topologyKey: kubernetes.io/hostname
  containers:
  - name: nginx
    image: nginx

3.4 拓扑键(TopologyKey)

拓扑键说明使用场景
kubernetes.io/hostname节点级别同/不同节点
failure-domain.beta.kubernetes.io/zone可用区级别同/不同可用区
failure-domain.beta.kubernetes.io/region地域级别同/不同地域

四、污点和容忍机制

4.1 污点(Taints)

作用:阻止 Pod 调度到特定节点

设置污点

# 设置污点
kubectl taint nodes node1 key1=value1:NoSchedule
kubectl taint nodes node1 key2=value2:NoExecute
kubectl taint nodes node1 key3=value3:PreferNoSchedule

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

# 删除污点
kubectl taint nodes node1 key1=value1:NoSchedule-

污点效果说明

效果说明影响
NoSchedule不调度新 Pod新 Pod 不会调度到此节点
PreferNoSchedule尽量不调度优先调度到其他节点
NoExecute驱逐现有 Pod驱逐不匹配的现有 Pod

4.2 容忍(Tolerations)

作用:允许 Pod 调度到有污点的节点

基本容忍配置

apiVersion: v1
kind: Pod
metadata:
  name: tolerant-pod
spec:
  tolerations:
  - key: "key1"
    operator: "Equal"
    value: "value1"
    effect: "NoSchedule"
  containers:
  - name: nginx
    image: nginx

高级容忍配置

apiVersion: v1
kind: Pod
metadata:
  name: advanced-tolerant-pod
spec:
  tolerations:
  # 容忍所有污点
  - operator: "Exists"
  # 容忍特定键的所有污点
  - key: "key1"
    operator: "Exists"
  # 容忍特定污点(带时间)
  - key: "key2"
    operator: "Equal"
    value: "value2"
    effect: "NoExecute"
    tolerationSeconds: 300  # 300秒后驱逐
  containers:
  - name: nginx
    image: nginx

4.3 污点容忍实战场景

专用节点池

# 为 GPU 节点设置污点
kubectl taint nodes gpu-node-1 gpu=true:NoSchedule

# GPU Pod 配置容忍
apiVersion: v1
kind: Pod
metadata:
  name: gpu-pod
spec:
  tolerations:
  - key: "gpu"
    operator: "Equal"
    value: "true"
    effect: "NoSchedule"
  nodeSelector:
    gpu: "true"
  containers:
  - name: gpu-app
    image: nvidia/cuda:11.0-base
    resources:
      limits:
        nvidia.com/gpu: 1

维护模式

# 设置维护模式污点
kubectl taint nodes node1 maintenance=true:NoExecute

# 系统 Pod 配置容忍
apiVersion: v1
kind: Pod
metadata:
  name: system-pod
spec:
  tolerations:
  - key: "maintenance"
    operator: "Equal"
    value: "true"
    effect: "NoExecute"
    tolerationSeconds: 3600  # 1小时后驱逐
  containers:
  - name: system-app
    image: nginx

五、拓扑感知调度

5.1 TopologySpreadConstraints

作用:控制 Pod 在拓扑域中的分布

基本配置

apiVersion: v1
kind: Pod
metadata:
  name: topology-pod
spec:
  topologySpreadConstraints:
  - maxSkew: 1
    topologyKey: zone
    whenUnsatisfiable: DoNotSchedule
    labelSelector:
      matchLabels:
        app: web
  containers:
  - name: nginx
    image: nginx

高级配置

apiVersion: v1
kind: Pod
metadata:
  name: advanced-topology-pod
spec:
  topologySpreadConstraints:
  # 按可用区分布
  - maxSkew: 1
    topologyKey: failure-domain.beta.kubernetes.io/zone
    whenUnsatisfiable: DoNotSchedule
    labelSelector:
      matchLabels:
        app: web
  # 按节点分布
  - maxSkew: 2
    topologyKey: kubernetes.io/hostname
    whenUnsatisfiable: ScheduleAnyway
    labelSelector:
      matchLabels:
        app: web
  containers:
  - name: nginx
    image: nginx

5.2 拓扑分布参数

参数说明可选值
maxSkew最大偏差正整数
topologyKey拓扑键节点标签键
whenUnsatisfiable不满足时的行为DoNotSchedule, ScheduleAnyway
labelSelector标签选择器匹配 Pod 标签

5.3 拓扑分布策略

均匀分布策略

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deployment
spec:
  replicas: 6
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      topologySpreadConstraints:
      - maxSkew: 1
        topologyKey: zone
        whenUnsatisfiable: DoNotSchedule
        labelSelector:
          matchLabels:
            app: web
      containers:
      - name: nginx
        image: nginx

️ 六、命令速记

调度相关命令

# 查看节点资源
kubectl top nodes
kubectl describe nodes

# 查看 Pod 调度事件
kubectl get events --sort-by=.lastTimestamp

# 查看节点标签
kubectl get nodes --show-labels

# 设置节点标签
kubectl label node <node-name> <key>=<value>

# 设置节点污点
kubectl taint node <node-name> <key>=<value>:<effect>

资源管理命令

# 查看资源配额
kubectl get resourcequota
kubectl describe resourcequota <name>

# 查看资源限制
kubectl get limitrange
kubectl describe limitrange <name>

# 查看 Pod 资源使用
kubectl top pods
kubectl describe pod <pod-name>

调度调试命令

# 查看调度器日志
kubectl logs -n kube-system kube-scheduler-<node>

# 查看 Pod 调度详情
kubectl describe pod <pod-name> | grep -A 10 "Events"

# 模拟调度分析
kubectl get events --field-selector involvedObject.name=<pod-name>

七、面试核心问答

Q1: Kubernetes 调度器的工作原理?

答案要点:

  • 预选阶段:过滤不满足条件的节点
  • 优选阶段:为候选节点打分排序
  • 绑定阶段:选择最高分节点并绑定
  • 可扩展的调度框架

Q2: 如何实现 Pod 的亲和性调度?

答案要点:

  • nodeAffinity:节点亲和性
  • podAffinity:Pod 亲和性
  • podAntiAffinity:Pod 反亲和性
  • 支持硬约束和软约束

Q3: 污点和容忍的作用是什么?

答案要点:

  • 污点:阻止 Pod 调度到特定节点
  • 容忍:允许 Pod 调度到有污点的节点
  • 三种效果:NoSchedule、PreferNoSchedule、NoExecute
  • 用于专用节点池和维护模式

Q4: 如何实现 Pod 的均匀分布?

答案要点:

  • 使用 TopologySpreadConstraints
  • 配置 maxSkew 控制偏差
  • 选择合适的 topologyKey
  • 支持多级拓扑分布

Q5: QoS 分类的意义是什么?

答案要点:

  • Guaranteed:资源有保障,优先级最高
  • Burstable:可突发使用,优先级中等
  • BestEffort:尽力而为,优先级最低
  • 影响 OOM 杀死顺序和资源分配

八、故障排查

常见调度问题

1. Pod 处于 Pending 状态

# 查看 Pod 详情
kubectl describe pod <pod-name>

# 检查调度事件
kubectl get events --sort-by=.lastTimestamp

# 检查节点资源
kubectl top nodes

# 检查节点污点
kubectl describe node <node-name> | grep Taint

2. 资源不足导致调度失败

# 查看节点资源使用
kubectl top nodes
kubectl describe nodes

# 检查资源配额
kubectl get resourcequota
kubectl describe resourcequota <name>

# 检查 Pod 资源请求
kubectl describe pod <pod-name>

3. 亲和性约束冲突

# 检查节点标签
kubectl get nodes --show-labels

# 检查 Pod 标签
kubectl get pods --show-labels

# 检查亲和性配置
kubectl get pod <pod-name> -o yaml | grep -A 20 affinity

4. 污点容忍配置错误

# 检查节点污点
kubectl describe node <node-name> | grep Taint

# 检查 Pod 容忍配置
kubectl get pod <pod-name> -o yaml | grep -A 10 tolerations

# 验证容忍匹配
kubectl describe pod <pod-name>

九、最佳实践

调度策略建议

  1. 资源管理

    • 合理设置 requests 和 limits
    • 使用 ResourceQuota 限制资源使用
    • 监控资源使用情况
  2. 节点管理

    • 使用标签分类节点
    • 合理设置污点
    • 定期维护节点
  3. 亲和性设计

    • 相关服务使用 Pod 亲和
    • 高可用服务使用 Pod 反亲和
    • 合理使用拓扑分布
  4. 性能优化

    • 避免过度约束
    • 使用软约束替代硬约束
    • 监控调度性能

生产环境建议

  1. 高可用设计

    • 多可用区部署
    • 使用拓扑分布约束
    • 配置 Pod 反亲和
  2. 资源优化

    • 使用 VPA 自动调整资源
    • 实施资源回收策略
    • 监控资源使用效率
  3. 故障处理

    • 配置 Pod 中断预算
    • 使用污点进行维护
    • 建立故障恢复流程

十、总结

通过本模块学习,你已经掌握了:

  • Kubernetes 调度器工作原理
  • 资源管理和 QoS 分类
  • 节点选择和亲和性策略
  • 污点和容忍机制
  • 拓扑感知调度
  • 调度故障排查技能
  • 调度最佳实践

下一步建议:继续学习 05-发布与弹性,深入了解 Kubernetes 应用发布和弹性伸缩机制。

Prev
03-存储管理
Next
05-发布与弹性