调度器配置
学习目标
- 理解 SchedulerProfile 的概念和作用
- 掌握如何创建自定义调度器配置
- 了解调度框架的插件机制
核心概念
一句话解释
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...