在 Kubernetes(k8s)中,调度器(Scheduler)选举机制是确保集群中只有一个活跃调度器实例处理 Pod 调度的关键机制。以下是其工作原理的详细解析:
一、核心概念
-
多实例部署
k8s Scheduler 通常以 Deployment 形式部署多个副本(默认 3 个),但同一时间只有一个实例作为Leader处理调度任务,其他实例处于Standby状态。 -
Leader 选举
通过基于 etcd 的租约(Lease)机制实现,确保同一时间只有一个 Leader。当 Leader 故障时,Standby 实例会重新选举新 Leader。
二、选举机制详解
1. 基于 Lease API 的选举
-
Lease 对象:
k8s 在coordination.k8s.io/v1
API 组中定义了 Lease 资源,用于实现分布式锁。Scheduler 使用kube-scheduler
命名空间下的kube-scheduler
Lease 对象。 -
选举流程:
2. 关键参数
-
LeaseDurationSeconds:
Leader 必须每leaseDurationSeconds
(默认 15 秒)更新一次 Lease,否则视为过期。 -
RenewDeadlineSeconds:
Leader 尝试更新 Lease 的超时时间(默认 10 秒)。 -
RetryPeriodSeconds:
Standby 实例尝试获取 Lease 的重试间隔(默认 2 秒)。
三、源码实现分析
1. 选举控制器初始化
// k8s.io/kubernetes/cmd/kube-scheduler/app/server.go
func createSchedulerComponents(...) (*schedulercomponents.Config, error) {
// 创建Leader选举配置
leaderElectionClient := clientset.NewForConfigOrDie(
restclient.AddUserAgent(config, "leader-election"),
)
leaderElectionConfig := leaderelection.LeaderElectionConfig{
Lock: &leaderelection.Resourcelock.ConfigMapLock{
Client: leaderElectionClient.CoreV1(),
LockConfig: resourcelock.ResourceLockConfig{
Name: "kube-scheduler",
Namespace: "kube-system",
},
},
LeaseDuration: 15 * time.Second,
RenewDeadline: 10 * time.Second,
RetryPeriod: 2 * time.Second,
Callbacks: leaderelection.LeaderCallbacks{
OnStartedLeading: sched.startedLeading,
OnStoppedLeading: sched.stoppedLeading,
},
}
}
2. Leader 状态切换
// k8s.io/kubernetes/pkg/scheduler/scheduler.go
func (s *Scheduler) startedLeading(ctx context.Context) {
// 成为Leader后启动调度循环
s.run(ctx)
}
func (s *Scheduler) stoppedLeading() {
// 失去Leader资格后停止调度
s.stopEverything()
}
四、监控与故障排查
1. 查看当前 Leader
kubectl -n kube-system get endpoints kube-scheduler -o yaml
输出示例:
apiVersion: v1
kind: Endpoints
metadata:
annotations:
control-plane.alpha.kubernetes.io/leader: '{"holderIdentity":"...","leaseDurationSeconds":15,...}'
2. 查看 Scheduler 日志
kubectl -n kube-system logs <scheduler-pod-name>
关键日志:
I0601 12:00:00.123456 1 leaderelection.go:243] attempting to acquire leader lease kube-system/kube-scheduler...
I0601 12:00:10.123456 1 leaderelection.go:253] successfully acquired lease kube-system/kube-scheduler
五、高可用设计考虑
-
多实例部署
至少部署 3 个 Scheduler 副本,确保单点故障不影响调度功能。 -
Pod 反亲和性
通过podAntiAffinity
确保 Scheduler 实例分布在不同节点:affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchLabels: component: kube-scheduler topologyKey: kubernetes.io/hostname
-
健康检查
Scheduler 自带 HTTP 健康检查端点:curl -k https://<scheduler-ip>:10259/healthz
六、常见问题与解决方案
问题 | 原因 | 解决方案 |
---|---|---|
无活跃 Leader | etcd 连接问题或 Lease 冲突 | 检查 etcd 状态,手动删除 kube-scheduler Lease |
Leader 频繁切换 | 网络抖动或 Lease 参数配置不合理 | 增加 LeaseDurationSeconds,检查节点网络 |
调度延迟突然增加 | Leader 所在节点资源不足 | 为 Scheduler Pod 分配足够资源 |
七、总结
k8s Scheduler 选举机制通过 etcd Lease 实现了高可用的分布式锁,确保在多实例部署时只有一个活跃调度器。理解其工作原理对排查调度故障、优化集群性能至关重要。在生产环境中,建议:
- 定期监控 Scheduler Leader 状态
- 配置合理的 Lease 参数
- 确保 Scheduler 实例分布在不同 AZ / 节点
- 与集群其他组件(如 API Server、Controller Manager)的高可用方案协同设计