Kubernetes 可以轻松重建 Pod,却很难移动数据。当应用开始有状态之后,一个被称为“数据重力(Data Gravity)”的问题开始浮出水面。
Kubernetes 集群中的一个 MySQL 节点宕机了。Pod 自动重建,5 秒后新实例在另一台节点上顺利启动——一切看起来如此完美。
然而,15 分钟后,业务依然没有恢复。
因为那个 MySQL Pod 背后,是 800GB的用户订单数据。而这份数据,正以每小时 50GB 的速度,在新旧节点之间艰难地“爬行”。
运维人员盯着进度条,内心只有一个念头:
“Kubernetes 能管好我的 Pod,却管不好我的数据。”
这就是我们今天要聊的——数据重力(Data Gravity)。
在深入技术之前,我们先打个比方。
想象 Kubernetes 是一个外卖平台:
平台调度系统非常智能:骑手 A 的车坏了,立刻派骑手 B 顶上去接单——这对应 Pod 迁移。
但如果“货”本身有 500 公斤重呢?
骑手换得再快也没用,因为货根本搬不动。
Kubernetes 的调度器只负责“派谁去送”,但它不负责“货怎么搬过去”——那是存储系统的事情。这种“调度”与“存储”的分离,正是 Kubernetes 架构优雅之处,却也是“数据重力”问题的根源。
假设我们有这样一个 Pod:
apiVersion: v1
kind:Pod
metadata:
name:mysql
spec:
containers:
-name:mysql
image:mysql:8.0
如果所在节点发生故障:
Node01 → NotReady
Kubernetes 会做什么?答案很简单:
删除旧 Pod → 重新调度 → 在 Node02 上启动
整个过程可能只需要 几秒钟。
这正是 Kubernetes 最擅长的事情。
现实情况往往是这样的:
MySQL Pod
│
▼
PersistentVolume(500GB 数据)
此时节点故障后,Pod 可以迁移,但 500GB 数据怎么办?
如果是 5TB、10TB 甚至 100TB 呢?
问题突然变得复杂起来。
因为 Pod 本质上只是:
nginx:latest只有 200MB)重新创建一个 Pod,几秒钟即可完成。
因此 Kubernetes 天生擅长:
因为数据不会像 Pod 一样凭空出现。
一个 MySQL 运行一年后,轻松积累 500GB数据。如果要迁移到另一台节点,这 500GB 需要先复制过去。
我们来做个定量分析:
数据量 | 1Gbps 网络耗时 | 10Gbps 网络耗时 | 可接受的停机窗口? |
|---|---|---|---|
50GB | ~7 分钟 | ~40 秒 | ✅ 可接受 |
500GB | ~70 分钟 | ~7 分钟 | ⚠️ 勉强支撑 |
5TB | ~12 小时 | ~70 分钟 | ❌ 不可接受 |
50TB | ~5 天 | ~12 小时 | ❌ 几乎不可能 |
当数据量超过 TB 级别, “迁移”这个词已经不适用了,更准确的说法是“搬运”——而搬运意味着长时间的停机、巨大的带宽成本和极高的失败风险。
所谓 Data Gravity(数据重力),可以简单理解为:
数据越大,就越难移动。
就像现实世界里的重力一样:
数据也是如此:
很多人不知道:Kubernetes 最初是为无状态应用设计的。
早期最典型的应用是 Nginx、API 网关、Web 服务。这些应用即使删除,重新创建即可,几乎没有成本。
因此 Kubernetes 早期的设计理念一直是 “宠物 vs 牛群”:
不要养宠物(坏了要抢救),要养牛群(坏了就重建)。
但数据库不一样。
假设 MySQL 存储了 3 年的订单数据,删除重建显然是不可能的。
因此 Kubernetes 后来逐渐增加了:
这些能力,本质上都是在解决一个问题:
如何让有状态应用安全地运行在 Kubernetes 上。
假设公司有一套 Elasticsearch集群,数据量 30TB。
某个节点突然故障(Node03 NotReady)。
理论上,Pod 迁移只需要 5 秒。但实际上,30TB 数据根本不可能在几秒钟内完成迁移。
因此企业通常会采用 多副本策略(例如 3 副本架构)。这样即使某个节点损坏,Pod 重新调度后,数据仍然存在于其它副本上。
但多副本意味着 3 倍的存储成本。这也是有状态应用上云后,成本急剧上升的主要原因之一。
最近两年最火的领域无疑是 AI。
但 AI 的数据量远超传统业务:
这时候,移动数据已经远比 移动 Pod困难得多。
很多时候:
与其把数据搬到计算节点,不如把计算搬到数据旁边。
这也是为什么 对象存储和 数据湖越来越受欢迎——因为它们天生就是为“海量数据不动,计算靠拢”设计的。
既然数据搬不动,我们总不能坐以待毙。以下是几条可落地的应对策略:
当 Kubernetes 原生工具力有不逮时,可以考虑:
过去几年,Kubernetes 存储能力一直在快速增强。
从最早的 PV/PVC,到后来的 CSI 标准化接口,再到如今的 VolumeSnapshot、VolumeGroupSnapshot(v1.36 GA)和 COSI(对象存储接口),社区一直在努力解决备份、恢复、迁移和容灾这些有状态场景的难题。
正如 SIG Storage 联席主席在近期的访谈中所言:
“大家逐渐发现,Kubernetes 最难管理的从来不是 Pod,而是数据。”
Kubernetes 可以让你在几秒钟内重建一个 Pod。
但数据不会消失,它只会以另一种方式提醒你:
编排容器容易,编排数据难。
理解了“数据重力”,你才会真正理解——为什么 StatefulSet 要等 PV 就绪才启动 Pod,为什么 CSI 要花数年时间才趋于成熟,为什么 VolumeGroupSnapshot 会被当作一个里程碑来庆祝。
因为社区花了很长时间才明白一个道理:
Kubernetes 调度的是无状态的 Pod,但它管理的是有状态的世界。