Kubernetes资源调度为什么需要调优
Kubernetes默认调度器基于预选(Predicates)与优选(Priorities)机制决策Pod放置位置,默认策略对通用Web应用足够,但面对GPU密集型AI推理、大规模批处理、数据库有状态服务等场景,默认调度策略会导致资源碎片化、跨节点通信开销大、热点节点过载等问题。SRE稳定性工程的核心目标之一就是让调度决策与业务特征匹配,而非被动接受默认行为。
资源请求与限制的精细化配置
Pod的resources.requests和resources.limits是调度决策的基础数据。配置不当是资源浪费和调度失败的根源:
# 常见错误:requests与limits差距过大,导致节点超卖
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "8"
memory: "32Gi"
# 推荐做法:QoS类Guaranteed,requests等于limits
resources:
requests:
cpu: "4"
memory: "16Gi"
nvidia.com/gpu: "1"
limits:
cpu: "4"
memory: "16Gi"
nvidia.com/gpu: "1"
三种QoS类对调度行为的影响:
- Guaranteed:requests=limits,调度器严格按requests分配,不会被驱逐,适合核心业务
- Burstable:requests < limits,可超用但可能被压制,适合流量波动型服务
- BestEffort:无requests/limits,优先级最低,资源紧张时最先被驱逐
线上环境建议90%以上Pod设为Guaranteed,避免资源竞争引发的延迟抖动。
Node亲和性与拓扑感知调度
AI推理场景中,GPU型号和NVLink拓扑直接影响服务性能。拓扑感知调度确保Pod被分配到合适的节点:
# GPU型号亲和性:将A100推理Pod调度到A100节点
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: gpu-type
operator: In
values: ["a100-80g"]
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values: ["llm-inference"]
topologyKey: kubernetes.io/hostname
Pod反亲和性确保同一应用的多个副本分散到不同节点,单节点故障不影响全部实例。跨可用区部署进一步增强容灾能力。
拓扑管理器与NUMA感知调度
高性能计算场景中,CPU和内存的NUMA拓扑对延迟敏感型应用影响显著。Kubernetes拓扑管理器(Topology Manager)在1.27+版本默认启用:
# 节点级配置:启用拓扑管理器
# /var/lib/kubelet/config.yaml
topologyManagerPolicy: best-effort
topologyManagerScope: pod
# Pod级NUMA绑定(需CPU Manager配合)
resources:
requests:
cpu: "8"
memory: "16Gi"
hugepages-1Gi: "2Gi" # 大页内存减少TLB miss
拓扑管理器的single-numa-node策略要求所有请求资源来自同一NUMA节点,对低延迟场景(如金融交易、实时推理)效果显著,P99延迟可降低30%-50%。
优先级与抢占机制实战
集群资源紧张时,调度器通过优先级和抢占机制保证高优任务运行:
# 定义PriorityClass
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: critical-inference
value: 1000000
globalDefault: false
preemptionPolicy: PreemptLowerPriority
description: "生产推理服务最高优先级"
---
# 低优先级批处理任务
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: batch-training
value: 100
globalDefault: false
preemptionPolicy: PreemptLowerPriority
description: "离线训练任务,可被抢占"
抢占过程会优雅终止低优先级Pod(发送SIGTERM,等待terminationGracePeriodSeconds),然后调度高优先级Pod。注意抢占不是立即生效的,调度器需要计算最优抢占目标,这个过程可能需要数秒。
Descheduler解决资源碎片化
长期运行的集群会出现资源碎片化:部分节点资源利用率极低但无法调度新的Pod,因为剩余资源不满足任何Pod的requests。Descheduler定期扫描并驱逐低效Pod,触发重新调度:
# Descheduler策略配置
apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
RemoveDuplicates:
enabled: true
params:
removeDuplicates:
numberOfReplicas: 1 # 每节点最多保留1个同名Pod副本
LowNodeUtilization:
enabled: true
params:
nodeResourceUtilizationThresholds:
thresholds:
cpu: 20
memory: 20
pods: 20
targetThresholds:
cpu: 50
memory: 50
pods: 50
RemovePodsViolatingNodeAffinity:
enabled: true
Descheduler以CronJob方式运行,建议每30分钟执行一次。生产环境先以DryRun模式运行观察效果,再开启实际驱逐。
监控告警体系与调度指标
调度相关核心指标需接入Prometheus监控:
# kube-scheduler指标
scheduler_pending_pods # 等待调度的Pod数量
scheduler_schedule_attempts_total # 调度尝试总次数
scheduler_schedule_attempts_total{result="error"} # 调度失败次数
# 节点资源碎片化指标
kube_node_status_allocatable # 节点可分配资源
kube_pod_container_resource_requests # Pod资源请求
# 自定义告警规则
- alert: HighSchedulingFailureRate
expr: rate(scheduler_schedule_attempts_total{result="error"}[5m]) > 0.1
for: 5m
labels:
severity: warning
annotations:
summary: "调度失败率超过10%"
- alert: ResourceFragmentation
expr: count(kube_node_status_allocatable{resource="cpu"} - sum(kube_pod_container_resource_requests{resource="cpu"}) by (node) < 1) > 3
for: 15m
labels:
severity: info
annotations:
summary: "超过3个节点CPU碎片化严重"
调度器的--profiling参数开启后可通过/debug/pprof分析调度延迟瓶颈。若scheduler_pending_pods持续增长,排查是否因节点标签不匹配、PV不可用、GPU资源不足等硬性约束导致。
故障应急响应与混沌工程验证
调度策略上线前应通过混沌工程验证韧性:
- 模拟节点故障(
chaos-mesh注入NodeLoss),验证Pod自动迁移与服务恢复时间 - 模拟CPU压力(stress-ng),验证Burstable Pod的资源压制是否符合预期
- 模拟网络分区,验证跨可用区调度切换
关键验收指标:单节点故障后,Pod在60秒内完成重新调度,服务恢复RTO < 120秒。RPO=0(有状态服务需配合PV自动迁移)。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/kubernetes-zi-yuan-diao-du-ce-lyue-diao-you-shi-zhan-qin-he/