Kubernetes控制面组件中,kube-controller-manager和kube-scheduler都采用多副本高可用部署,但同一时刻只能有一个实例作为Leader执行实际工作。如果Leader发生频繁切换,会导致控制循环反复中断、Pod调度延迟增大,严重时可能引起资源状态不一致。要解决这类问题,必须先理解Leader选举的底层实现,再结合命令与日志逐层排查。

Leader选举的工作机制
Kubernetes控制面组件的Leader选举并不依赖外部协调服务,而是直接使用API Server作为仲裁者。kube-controller-manager和kube-scheduler在启动时都会创建或获取一个特定的资源对象,早期版本使用Endpoints,较新版本(v1.14以后稳定)默认使用Lease。这个资源对象中记录了当前Leader的身份、租约获取时间、租约过期时间等信息。
每个候选者会定期尝试更新这个资源对象上的租约。具体流程是:候选者先读取当前Lease,检查持有者是否已经过期。如果已过期或者没有持有者,就尝试将自己设置为Leader,写入自身标识和新的过期时间。写入成功后,该候选者获得Leader角色并开始执行控制循环。其他候选者则进入等待状态,持续监听Lease的变化,并在Leader租约到期前不发起抢占。
租约的过期时间由参数--leader-elect-lease-duration控制,默认值为15秒;续约周期由--leader-elect-renew-deadline控制,默认值为10秒;重试周期由--leader-elect-retry-period控制,默认值为2秒。这三个参数的配合直接决定了在异常情况下多长时间后会发生Leader切换,以及切换过程的稳定性。
频繁切换的常见诱因
最直接的导致切换的原因是当前Leader无法在期望的时间窗口内完成租约续期。续期操作本质上是向API Server发送一个更新Lease的请求,如果这个请求因为网络延迟、API Server过载或者节点资源不足而超时,Leader会被判定为失效,其他候选者就会抢占。
节点时钟漂移是容易被忽视的诱因。Leader选举依赖资源对象中的时间戳与候选者本地时间比较,如果各个控制面节点之间的系统时间不一致,就会出现“误判过期”的情况。例如节点A的时钟比节点B快5秒,即使API Server处理正常,节点B也可能认为A的租约已经到期,从而发起抢占。
控制面节点之间的网络分区也会导致频繁切换。在分区隔离的情况下,旧Leader仍然认为自己是Leader并继续写入更新,但新Leader已经在另一分区产生。网络恢复后,两个Leader实例同时操作控制循环,产生“双主”现象,随后API Server检测到Lease被频繁改写,进一步加剧切换。
此外,如果控制面组件部署在与其他业务负载共享的节点上,CPU节流或内存压力会导致组件线程调度延迟,续期请求无法按时发出。API Server自身的慢查询、etcd写入延迟也会让租约续期失败。
排查方法与命令实践
首先确认当前使用的是Lease还是Endpoint。对于较新版本的Kubernetes,默认使用Lease,可以执行以下命令查看控制面命名空间中的Lease对象:
kubectl get lease -n kube-system kubectl get lease -n kube-node-lease
如果想看到具体的内容,例如kube-controller-manager的Lease,可以使用kubectl describe lease kube-controller-manager -n kube-system。输出中HolderIdentity表示当前Leader的主机标识,LeaseDurationSeconds、AcquireTime、RenewTime可以帮助判断租约是否在正常滚动。
对于使用Endpoint作为选举资源的场景,可以查看kube-system命名空间下名为kube-controller-manager的Endpoint。Endpoint的annotations中有一个control-plane.alpha.kubernetes.io/leader字段,内容为JSON格式,包含holderIdentity、leaseDurationSeconds、acquireTime、renewTime和leaderTransitions。其中leaderTransitions记录了该资源从创建以来Leader切换的总次数,如果数值异常增长,说明切换频繁。
组件日志是另一个重要线索。在kube-controller-manager或kube-scheduler的日志中搜索leader election关键词,可以看到类似attempting to acquire leader lease、successfully acquired lease、failed to renew lease的消息。如果出现failed to renew lease,并且出现频率高,直接指向续期失败。
还可以通过metrics端口获取详细的选举指标。kube-controller-manager默认监听10257端口,kube-scheduler监听10259端口。在集群外部可以使用kubectl proxy或者直接访问组件所在节点的HTTP接口,查看leader_election_master_status指标。该值为1时表示当前节点是Leader,为0表示不是。
调整与加固建议
如果是偶发的网络抖动或API Server压力导致的切换,可以适当调大租约和续期参数。在组件启动参数中设置--leader-elect-lease-duration=30s、--leader-elect-renew-deadline=20s、--leader-elect-retry-period=4s,让Leader在短暂中断时有更充裕的缓冲时间。但需要注意,调大参数会延长真正故障时的切换时间,需要在可用性与切换速度之间权衡。
对于时钟漂移问题,要在所有控制面节点上配置NTP服务,并定期检查timedatectl status输出中NTP synchronized是否为yes。如果集群运行在云平台,优先使用云厂商提供的时钟同步方案,避免跨节点时间偏差超过几百毫秒。
如果切换是由于节点资源竞争引起,建议把控制面组件调度到独立节点,或者设置更高的QoS等级。可以通过kubectl describe pod查看组件的资源请求和限制,避免与业务Pod共享CPU导致节流。同时监控API Server的请求延迟,如果P99延迟持续超过1秒,需要考虑扩容API Server或者优化etcd性能。
最后,建议在集群监控系统中配置Leader切换告警。通过Prometheus采集leader_election_master_status并配置变化检测规则,当该指标在短时间内频繁翻转时及时通知运维人员。同时保留组件日志和Lease资源的历史数据,方便事后分析切换根因。
Kubernetes控制面Leader选举修改时间:2026-08-25 12:14:46