80·调度与资源高级

调度器配置

kubernetesschedulingscheduler-profiles

调度器配置

学习目标

  1. 理解 SchedulerProfile 的概念和作用
  2. 掌握如何创建自定义调度器配置
  3. 了解调度框架的插件机制

核心概念

一句话解释

SchedulerProfile 允许你自定义调度器的行为,创建多个调度配置供不同 Pod 使用。

调度框架

┌─────────────────────────────────────────────────────────┐
│                    调度框架扩展点                        │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  ┌─────────────────────────────────────────┐           │
│  │  PreFilter                              │           │
│  │  - 预处理和检查                         │           │
│  │  - 计算全局状态                         │           │
│  └─────────────────────────────────────────┘           │
│           │                                             │
│           v                                             │
│  ┌─────────────────────────────────────────┐           │
│  │  Filter                                 │           │
│  │  - 过滤不满足条件的节点                 │           │
│  │  - 类似原来的 predicate                 │           │
│  └─────────────────────────────────────────┘           │
│           │                                             │
│           v                                             │
│  ┌─────────────────────────────────────────┐           │
│  │  PostFilter                             │           │
│  │  - 过滤后处理                           │           │
│  │  - 可以实现抢占                         │           │
│  └─────────────────────────────────────────┘           │
│           │                                             │
│           v                                             │
│  ┌─────────────────────────────────────────┐           │
│  │  PreScore                               │           │
│  │  - 打分前预处理                         │           │
│  └─────────────────────────────────────────┘           │
│           │                                             │
│           v                                             │
│  ┌─────────────────────────────────────────┐           │
│  │  Score                                  │           │
│  │  - 对节点打分                           │           │
│  │  - 类似原来的 priority                  │           │
│  └─────────────────────────────────────────┘           │
│           │                                             │
│           v                                             │
│  ┌─────────────────────────────────────────┐           │
│  │  NormalizeScore                         │           │
│  │  - 标准化分数                           │           │
│  └─────────────────────────────────────────┘           │
│           │                                             │
│           v                                             │
│  ┌─────────────────────────────────────────┐           │
│  │  Reserve                                │           │
│  │  - 预留资源(乐观绑定)                 │           │
│  └─────────────────────────────────────────┘           │
│           │                                             │
│           v                                             │
│  ┌─────────────────────────────────────────┐           │
│  │  Permit                                 │           │
│  │  - 准入控制                             │           │
│  │  - 可以等待或拒绝                       │           │
│  └─────────────────────────────────────────┘           │
│           │                                             │
│           v                                             │
│  ┌─────────────────────────────────────────┐           │
│  │  PreBind                                │           │
│  │  - 绑定前操作                           │           │
│  └─────────────────────────────────────────┘           │
│           │                                             │
│           v                                             │
│  ┌─────────────────────────────────────────┐           │
│  │  Bind                                   │           │
│  │  - 执行绑定                             │           │
│  └─────────────────────────────────────────┘           │
│           │                                             │
│           v                                             │
│  ┌─────────────────────────────────────────┐           │
│  │  PostBind                               │           │
│  │  - 绑定后清理                           │           │
│  └─────────────────────────────────────────┘           │
│                                                         │
└─────────────────────────────────────────────────────────┘

内置插件

# Filter 插件
- NodeResourcesFit          # 资源是否满足
- NodePorts                 # 端口是否冲突
- NodeAffinity              # 节点亲和性
- PodTopologySpread         # Pod 拓扑分布
- InterPodAffinity          # Pod 亲和性
- TaintToleration           # 污点容忍

# Score 插件
- NodeResourcesBalancedAllocation  # 资源均衡
- NodeResourcesLeastAllocated      # 资源最少分配
- InterPodAffinity                 # Pod 亲和性
- NodeAffinity                     # 节点亲和性
- TaintToleration                  # 污点容忍
- ImageLocality                    # 镜像本地性

SchedulerProfile 配置

apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
  - schedulerName: default-scheduler
    plugins:
      score:
        enabled:
          - name: NodeResourcesBalancedAllocation
          - name: NodeResourcesLeastAllocated
        disabled:
          - name: ImageLocality

多调度器配置

apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
  # 默认调度器
  - schedulerName: default-scheduler
    plugins:
      score:
        enabled:
          - name: NodeResourcesBalancedAllocation

  # 自定义调度器:优先 GPU
  - schedulerName: gpu-scheduler
    plugins:
      score:
        enabled:
          - name: NodeResourcesBalancedAllocation
          - name: NodeAffinity
        disabled:
          - name: ImageLocality

  # 自定义调度器:低延迟
  - schedulerName: low-latency-scheduler
    plugins:
      score:
        enabled:
          - name: NodeResourcesLeastAllocated
          - name: InterPodAffinity

使用自定义调度器

apiVersion: v1
kind: Pod
metadata:
  name: gpu-pod
spec:
  schedulerName: gpu-scheduler  # 指定调度器
  containers:
  - name: app
    image: nginx

插件配置

apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
  - schedulerName: default-scheduler
    plugins:
      score:
        enabled:
          - name: NodeResourcesBalancedAllocation
            weight: 1  # 权重
          - name: NodeResourcesLeastAllocated
            weight: 2
    pluginConfig:
      - name: NodeResourcesFit
        args:
          ignoredResources:
            - "nvidia.com/gpu"
          ignoredResourceGroups:
            - "example.com/*"

调度器配置文件

# /etc/kubernetes/scheduler-config.yaml
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
leaderElection:
  leaderElect: true
  resourceNamespace: kube-system
  resourceName: kube-scheduler
clientConnection:
  kubeconfig: /etc/kubernetes/scheduler.conf
profiles:
  - schedulerName: default-scheduler
    plugins:
      score:
        enabled:
          - name: NodeResourcesBalancedAllocation
          - name: NodeResourcesLeastAllocated

启动调度器

# 使用配置文件启动
kube-scheduler --config=/etc/kubernetes/scheduler-config.yaml

# 或在 kube-scheduler.yaml 中指定
apiVersion: v1
kind: Pod
metadata:
  name: kube-scheduler
  namespace: kube-system
spec:
  containers:
  - name: kube-scheduler
    command:
    - kube-scheduler
    - --config=/etc/kubernetes/scheduler-config.yaml

实践练习

练习 1:查看默认调度器配置

# 查看调度器配置
kubectl get cm -n kube-system kubeadm-config -o yaml

# 或查看调度器 Pod
kubectl get pod -n kube-system -l component=kube-scheduler -o yaml

练习 2:创建自定义调度器配置

# custom-scheduler-config.yaml
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
  - schedulerName: my-scheduler
    plugins:
      score:
        enabled:
          - name: NodeResourcesLeastAllocated
            weight: 3
          - name: NodeResourcesBalancedAllocation
            weight: 1
        disabled:
          - name: ImageLocality

练习 3:使用自定义调度器

# pod-custom-scheduler.yaml
apiVersion: v1
kind: Pod
metadata:
  name: custom-scheduler-pod
spec:
  schedulerName: my-scheduler
  containers:
  - name: nginx
    image: nginx
kubectl apply -f pod-custom-scheduler.yaml

# 查看 Pod 调度情况
kubectl describe pod custom-scheduler-pod | grep -A 5 Events

练习 4:配置调度器插件

# scheduler-with-plugins.yaml
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
  - schedulerName: balanced-scheduler
    plugins:
      score:
        enabled:
          - name: NodeResourcesBalancedAllocation
            weight: 5
          - name: NodeAffinity
            weight: 3
          - name: TaintToleration
            weight: 2
      filter:
        enabled:
          - name: NodeResourcesFit
          - name: NodeAffinity
          - name: TaintToleration

练习 5:查看调度器指标

# 调度器暴露 Prometheus 指标
# 默认端口:10259

# 查看调度器指标
kubectl exec -n kube-system -it kube-scheduler-<node> -- \
  curl -k https://localhost:10259/metrics

# 常用指标
# - scheduler_schedule_attempts_total
# - scheduler_e2e_scheduling_duration_seconds
# - scheduler_pending_pods
# - scheduler_preemption_attempts_total

调度器扩展点详解

Filter 插件示例

# 自定义 Filter:只调度到有特定标签的节点
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
  - schedulerName: custom-scheduler
    plugins:
      filter:
        enabled:
          - name: NodeResourcesFit
          - name: NodeAffinity
          - name: NodePorts
          - name: TaintToleration

Score 插件示例

# 自定义 Score:优先选择资源均衡的节点
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
  - schedulerName: balanced-scheduler
    plugins:
      score:
        enabled:
          - name: NodeResourcesBalancedAllocation
            weight: 10
          - name: NodeResourcesLeastAllocated
            weight: 5
          - name: InterPodAffinity
            weight: 3

Permit 插件示例

# Permit 插件:实现 Gang Scheduling
# 所有 Pod 都就绪后才一起调度
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
  - schedulerName: gang-scheduler
    plugins:
      permit:
        enabled:
          - name: GangScheduling

最佳实践

1. 不要修改默认调度器
   - 创建自定义调度器 Profile
   - 避免影响系统组件

2. 合理配置权重
   - 根据业务需求调整插件权重
   - 测试不同配置的效果

3. 监控调度器性能
   - 跟踪调度延迟
   - 监控抢占频率

4. 使用多个 Profile
   - 不同工作负载使用不同调度策略
   - 提高调度灵活性

5. 测试配置变更
   - 在测试环境验证
   - 逐步推广到生产环境

常见问题

1. 自定义调度器不工作

# 检查调度器配置
kubectl get cm -n kube-system -o yaml

# 检查调度器日志
kubectl logs -n kube-system -l component=kube-scheduler

# 检查 Pod 是否指定了正确的 schedulerName
kubectl get pod <pod-name> -o yaml | grep schedulerName

2. 如何调试调度器

# 启用详细日志
kube-scheduler --v=5

# 查看调度器指标
kubectl exec -n kube-system -it kube-scheduler-<node> -- \
  curl -k https://localhost:10259/metrics

# 使用 kubectl 模拟调度
kubectl run test-pod --image=nginx --dry-run=server -o yaml

3. 多个调度器如何协调?

多个调度器独立工作:
- 每个调度器有自己的 Profile
- Pod 通过 schedulerName 选择调度器
- 调度器之间不共享状态

注意事项:
- 避免多个调度器调度同一个 Pod
- 合理分配调度器职责
- 监控调度器负载

小结

要点说明
SchedulerProfile自定义调度器行为的配置
调度框架Filter, Score, Bind 等扩展点
内置插件NodeResourcesFit, NodeAffinity 等
多 Profile支持多个调度器配置
使用方式Pod 指定 schedulerName
最佳实践不修改默认配置,创建自定义 Profile

练习编辑器

bash
Loading...

继续学习

完成本课后,建议继续学习下一课「安全概述」 以巩固所学知识。