Files
baim0-learn/k8sTrouble/01 数据不一致问题.md
T

48 lines
2.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: APIServer Cache 脏数据导致 Ghost Pod 仍在调度
date: 2026-06-02
tags:
- kubernetes排障
categories:
- kubernetes排障
---
## 问题现象
发现调度器仍在调度已不存在或早已下线的 Pod。Pod 实际已不存在(etcd 中无记录),但 kube-scheduler 组件重启后 list/watch 仍能获取到该 Pod 信息,疑似脏数据导致。
## 问题原因
根因是 **APIServer cache 与 etcd 数据不一致**:
- 部分 APIServer 副本的 watch cache 数据是旧的(stale),导致 scheduler 通过 informer → watch → APIServer cache 这条链路一直能读到旧的 pending Pod 数据。
- 调度器写 binding 走的是 **etcd quorum**(强一致性),所以写的时候拿到的是真值(404,Pod 已不存在)。
- 调度器读 Pod 走的是 **informer → watch → APIServer cache**(最终一致性),所以读到的是 stale 数据。
> **读写两条路径不同步,这是 ghost Pod 的本质。**
### 架构示意
```
调度器 ──读 Pod──→ Informer ──Watch──→ APIServer Cache(stale ❌)
调度器 ──写 Binding──→ APIServer ──→ etcd Quorum(真实 ✅)
```
## 解决方案
### 短期:滚动重启异常 APIServer
滚动重启缓存数据异常的 APIServer 副本即可恢复。重启后 watch cache 重建,与 etcd 数据重新同步。
### 长期:升级集群至 1.34+
Kubernetes 1.34 及以上版本默认开启 `KUBE_WATCHCACHE_CONSISTENCY_CHECKER` 功能,会定期检查 APIServer cache 与 etcd 之间的一致性,并在检测到不一致时自动修复(自愈),从根源上杜绝该类问题。
## 关键要点
| 链路 | 一致性模型 | 结果 |
| ------ | --------------- | -------------- |
| 读 Pod | APIServer Cache | 可能读到 stale |
| 写 Pod | etcd Quorum | 始终为真实值 |
排查此类问题时,核心思路是:**对比 informer 侧拿到的数据与直接查 etcd/APIServer 的结果是否一致**,若不一致,则高度怀疑 watch cache 脏数据。