夜雨聆风学习资料网

ARTICLE · 1047081

Fluid:让 AI 训练不再“等数据”的 K8s 原生加速器

Fluid:让 AI 训练不再“等数据”的 K8s 原生加速器

Fluid:让 AI 训练不再"等数据"的 K8s 原生加速器

CNCF 孵化项目,把数据集变成 K8s 里的一等公民

💡 你有没有见过这种画面:一排 GPU 亮着灯,风扇呼呼转,可训练日志就是卡在 downloading dataset... 不动。显卡在烧钱,数据还在路上。

AI 训练这件事,卡脖子的往往不是算力,是数据。

今天要聊的 Fluid,就是专门来解决这个问题的。它的定位很直接:让 Kubernetes 上的大数据和 AI 应用,像访问本地磁盘一样访问远端数据

📚 项目简介

一句话说清楚:Fluid 是一个 Kubernetes 原生的分布式数据集编排与加速器,为 Spark、TensorFlow、PyTorch 这类数据密集型应用提供数据抽象、缓存加速和弹性调度能力。它由南京大学与阿里云等团队联合发起,目前由 CNCF 托管,处于 Incubating(孵化) 阶段。

它的思路可以用一个比喻理解。

传统的做法是"把数据搬到家门口"——训练前先花几十分钟甚至几小时下载数据集到本地盘。而 Fluid 的做法更像给数据装了一套城市级的智能物流系统:它不搬运整仓库的货,而是把最常被取用的那部分,就近放到你楼下的分布式前置仓里(缓存),并且自动安排你的计算任务去那个有货的仓(数据亲和调度)。你要用的时候,几乎就是"伸手就有"。

⭐ 核心能力

  • ✅ Dataset 数据抽象:用一套统一的 CRD 描述来自 OSS、HDFS、NFS、CSI PVC 等各种来源的数据集,屏蔽底层存储差异

  • 🔧 可插拔的 Runtime 缓存引擎:Alluxio、JindoFS、JuiceFS、Vineyard、ThinRuntime 多引擎并存,按场景自由选型

  • ⚡ 自动化数据编排:DataLoad(预热)、DataMigrate(迁移)、DataProcess(处理),支持一次性、事件触发、Cron 三种模式,还能用 DataFlow 串成流水线

  • 🚀 弹性与亲和调度:分布式缓存 + 弹性扩缩容 + 数据本地性调度,让 Pod 尽量落到有缓存副本的节点上

  • 🌐 运行环境无关:原生 K8s、边缘、Serverless Kubernetes、多集群环境都能跑

📊 关键数据

  • ⭐ 1,982 Stars

  • 🍴 1,263 Forks

  • 👥 7 位 Maintainer + 17 位 Committer,来自南京大学、阿里云、Alluxio、JuiceData、中国电信、腾讯云、B站、百度、小米、贝壳、华为等

  • 📅 最近提交:2026-09-16

  • 🏷️ 许可:Apache 2.0,厂商中立

  • 🎖️ CNCF 项目状态:Incubating(2026 年 1 月 8 日通过 TOC 投票晋级)

🎯 它到底在解决什么痛点

先说清楚问题,才看得懂 Fluid 的价值。

第一个矛盾:云原生要弹性,数据却沉在远端。

K8s 最大的卖点是"计算在哪里跑都可以"。但数据不是。数据在对象存储里、在 HDFS 里、在 NFS 里,带宽固定、延迟固定。你把训练任务弹性扩到 32 个节点,结果 32 个节点一起挤同一条带宽水管,全都饿着。

第二个矛盾:每次训练都要重新拉一遍数据。

容器是"用完即弃"的。这一轮训练的容器跑完销毁,下一轮重建,缓存没了,数据得重新下载。数据集越大,这个浪费越夸张。

第三个矛盾:多样存储源带来的管理碎片。

一个公司里可能同时有 OSS、HDFS、Ceph、NAS、JuiceFS。每个计算框架对接每种存储都要单独适配一遍。运维和算法同学被这些胶水代码反复折磨。

第四个矛盾:数据准备好了没有,应用并不知道。

训练任务启动了,但数据还没预热完;或者数据已经全部加载好了,但应用还在轮询等待。缺少一个"数据侧"的状态机去和"计算侧"握手。

Fluid 的设计,正好是冲着这四个矛盾来的:统一抽象消灭碎片,分布式缓存解决带宽瓶颈,数据编排解决冷启动,Dataset 状态让计算任务能"看着数据的脸色"启动。

⭐ 核心功能详解

1️⃣ Dataset:让数据成为 K8s 的一等公民

在 Fluid 里,你不再直接操作某个存储路径,而是声明一个 Dataset 对象:

apiVersion:data.fluid.io/v1alpha1
kind:Dataset
metadata:
name:demo
spec:
mounts:
-mountPoint:https://mirrors.bit.edu.cn/apache/spark/
name:spark
江达小记

mountPoint 可以指向 HTTP、S3/OSS、HDFS、NFS,也可以指向一个 pvc://对上层应用来说,它就是一个 PersistentVolumeClaim,挂上去就能用。

走到这一步,Fluid 就把"数据"从"某个存储系统的私事",变成了"K8s 世界里可被调度的公共资源"。它是后面所有能力的支点。

2️⃣ Runtime:缓存引擎的可插拔底座

Dataset 描述了"数据是什么",Runtime 描述"用什么去加速它"。同一个 Dataset,你可以挂 Alluxio、挂 JindoFS、挂 JuiceFS、挂 Vineyard,甚至挂一个自己写的 ThinRuntime。

apiVersion:data.fluid.io/v1alpha1
kind:AlluxioRuntime
metadata:
name:demo
spec:
replicas:1
tieredstore:
levels:
-mediumtype:MEM
path:/dev/shm
quota:2Gi
high:"0.95"
low:"0.7"
江达小记

tieredstore 这块值得多看一眼:它支持内存(MEM)、SSD、HDD 多层缓存介质,还带水位线控制——high: 0.95 以上开始淘汰,low: 0.7 以下停止淘汰。这其实是把缓存管理这件很脏的活,用声明式 API 收敛了。

值得一提的是 ThinRuntime。它是一条"薄适配"路线:只要你的存储系统有 FUSE 客户端或者能挂载,就可以不写控制器代码,直接用 YAML 把它接进 Fluid 体系。v1.0.8 里通过它新接入了 3FS 和 Curvine 两种存储。

3️⃣ 数据操作:DataLoad / DataMigrate / DataProcess

数据不只是被动被读取,还能被主动编排:

  • DataLoad:把远端数据预热进缓存,让第一个训练任务不用当"缓存填充器"

  • DataMigrate:在存储系统之间搬数据,支持并行迁移

  • DataProcess:挂载数据集跑数据处理任务

三种触发模式各有用途:

  • once:一次性执行,适合上线前预热

  • onEvent:事件驱动,适合和大数据平台的调度系统联动

  • Cron:定时执行,适合每天凌晨的例行预热

再往上,DataFlow 把这些操作串成有向无环图,前一步的输出决定后一步的输入。这一层设计的野心很清楚:它想让"数据流水线"和"计算流水线"一样,成为被声明式管理的东西。

4️⃣ 数据亲和调度:让 Pod 去有数据的地方

这是 Fluid 最能体现"K8s 原生"的一点。

Fluid 会把缓存的分布情况同步给 K8s 调度器,训练 Pod 在调度时就能感知"哪个节点上有我这份数据的副本"。计算向数据靠拢,而不是数据向计算靠拢。 这一句听起来简单,但它是整个云原生数据栈效率的关键分野。

5️⃣ CSI 插件与 FUSE 高可用

Fluid 自带 CSI 插件(csi-nodeplugin-fluid),把 Dataset 以标准 PVC 的形式暴露给容器。同时针对 FUSE 客户端容易出现的挂载异常,实现了恢复机制。v1.0.5 起,单个节点的 FUSE 故障被隔离,不再连带影响整个 Dataset 的可用性。

这些是"生产可用"和"Demo 能跑"之间的差距。

🚀 快速开始

前面说再多,不如动手跑一遍。整个安装过程大概三分钟。

前置条件

  • Kubernetes 1.18+,支持 CSI

  • kubectl 1.18+

  • Helm 3

江达小记

官方提示:不太建议用 Minikube 部署 Fluid,功能受限,容易踩坑。

安装 Fluid

# 1. 创建命名空间
kubectl create ns fluid-system
# 2. 添加 Helm 仓库
helm repo add fluid https://fluid-cloudnative.github.io/charts
helm repo update
# 3. 一键安装
helm install fluid fluid/fluid
江达小记

装完确认一下:

kubectl get po -n fluid-system
江达小记

看到 dataset-controlleralluxioruntime-controllercsi-nodeplugin-fluid 都在 Running,就说明控制平面起来了。

创建数据集

# dataset.yaml —— 声明数据从哪来
apiVersion:data.fluid.io/v1alpha1
kind:Dataset
metadata:
name:demo
spec:
mounts:
-mountPoint:https://mirrors.bit.edu.cn/apache/spark/
name:spark
江达小记
kubectl create -f dataset.yaml
江达小记

挂上缓存引擎

# runtime.yaml —— 声明用什么加速,这里用 Alluxio,给 2Gi 内存做缓存
apiVersion:data.fluid.io/v1alpha1
kind:AlluxioRuntime
metadata:
name:demo
spec:
replicas:1
tieredstore:
levels:
-mediumtype:MEM
path:/dev/shm
quota:2Gi
high:"0.95"
low:"0.7"
江达小记
kubectl create -f runtime.yaml
江达小记

应用挂载并使用

# app.yaml —— 注意这里的 claimName 就是 Dataset 的名字
apiVersion:v1
kind:Pod
metadata:
name:demo-app
spec:
containers:
-name:demo
image:nginx
volumeMounts:
-mountPath:/data
name:demo
volumes:
-name:demo
persistentVolumeClaim:
claimName:demo
江达小记

进容器实测一下:

kubectl exec -it demo-app -- bash
time cp /data/spark/spark-3.0.3/spark-3.0.3-bin-without-hadoop.tgz /dev/null
# 第一次:real 0m13.171s(从远端拉)
江达小记

删掉 Pod 重建,再跑同一条命令:

time cp /data/spark/spark-3.0.3/spark-3.0.3-bin-without-hadoop.tgz /dev/null
# 第二次:real 0m0.344s(命中缓存)
江达小记

13 秒到 0.34 秒。 这就是缓存命中与否的差距。

真实场景的收益

官方在 ResNet50 训练场景(V100 x8 四机)做过一组对比测试:NFS 直读、Fluid 冷缓存、Fluid 热缓存三种情况下,训练耗时分别是 2h15m59s、1h43m43s、1h32m22s。

换算一下:

  • 热缓存相比 NFS 直读,训练时间缩短约 31%

  • 第 1000 步的吞吐从 3136 images/s 提到 20859 images/s,接近 7 倍

原因不复杂:4 机 32 卡同时读 NFS 时,NFS 带宽成了瓶颈;而 Fluid 基于 Alluxio 提供了 P2P 式的分布式缓存读取能力,把单点带宽变成了集群带宽。

💡 技术亮点解析

架构:控制面 + 数据面 + CSI 三段式

Fluid 的架构大致分三层:

控制面由一组 Controller 组成——DatasetController 负责数据集生命周期,RuntimeController 驱动具体缓存引擎,ThinRuntimeController 处理薄适配场景,外加 mutating webhook 负责给应用 Pod 注入 FUSE sidecar 和卷。它们都跑在 fluid-system 命名空间里。

数据面是各缓存引擎的实际工作负载——Alluxio 的 master/worker、JindoFS 的 master/worker、JuiceFS 的 worker 等等,由 Runtime 控制器编排成 StatefulSet。

CSI 插件作为 DaemonSet 部署在每个节点上,负责把 Dataset 以标准 PV/PVC 的形式挂进容器。

三段之间靠 K8s 原生的 CRD + Controller 模式解耦,这也是它能做到"Runtime 可插拔"的结构基础。

亮点一:用 mutator 模式重写 sidecar 注入

FUSE 客户端的注入是 Fluid 里最容易出 bug 的地方。v1.0.0 之后,团队把这块逻辑重构成了函数级可组合的 mutator 链:默认注入、非特权注入、Native Sidecar 注入各自是独立的 mutator,按需串联。

这个改造的意义在于——v1.0.8 加入 Kubernetes Native Sidecar 支持时,不需要改动原有注入逻辑,只是新增一个 mutator。新特性以插件的形式长出来,而不是在原有 if-else 里再插一层。

Native Sidecar 解决的是什么问题?传统 Sidecar 容器和主容器的生命周期是解耦的,容易出现"主容器在等挂载,sidecar 还没起来"的竞态。用 K8s 原生的 sidecar(initContainer + restartPolicy: Always)后,启动顺序和生命周期由 K8s 保证,资源隔离也更干净。

亮点二:权限的持续收缩

翻 Fluid 的 CHANGELOG,会发现一条很清楚的主线:一直在减权限

  • v1.0.0:移除所有 Secret 相关权限

  • v1.0.8:收紧核心 Controller 的 ServiceAccount RBAC,剔除多余授权;移除 FUSE 容器中非必需的管理特权;移除缓存引擎中冗余的 SYS_ADMIN capability

对一个需要挂载文件系统、天生就要碰特权操作的组件来说,这种"逆着惯性做减法"其实很难。它不是靠一次重构完成的,而是连续多个版本一点点抠出来的。

亮点三:控制面的可调参设计

v1.0.6 之后,Fluid 把一批原本写死的参数开放给了用户:runtimeWorkers、kubeClient 的 QPS/Burst、work-queue 配置、ThinRuntime 的 maxConcurrentReconciles 等。

v1.0.8 甚至把 ThinRuntime 控制器的默认 Reconcile RateLimit 设为 0,让资源状态更新即时生效。

这种"把内部调度参数变成公开配置"的做法,往往是一个项目从"能用"走向"能扛生产流量"的标志。 因为大规模集群里,性能和稳定性问题最终都会收敛到这些旋钮上。

技术栈

  • 语言:Go

  • 核心依赖:Kubernetes controller-runtime、Helm 3、gRPC

  • CRD 版本data.fluid.io/v1alpha1(Roadmap 中规划升级到 v1alpha2

  • 缓存引擎:Alluxio、JindoFS、JuiceFS、Vineyard、ThinRuntime(3FS、Curvine 等)

✅ 优缺点分析

优点:

  • ✅ 抽象分层干净:Dataset(数据是什么)、Runtime(怎么加速)、DataOps(怎么编排)三层职责清晰,学习成本可控

  • ✅ 不绑定厂商:CNCF 托管、Apache 2.0、厂商中立,Alluxio/JindoFS/JuiceFS 多引擎自由选型,不被单一商业方案锁死

  • ✅ 大厂生产验证充分:ADOPTERS 名单里有阿里云 PAI、微博、B站、360、OPPO、虎牙、小米、同花顺、天翼云、网易互娱、地平线、旷视、得物、liblibai 等数十家,Production 阶段的就有一大批

  • ✅ K8s 原生程度高:全部能力以 CRD + Controller 形式提供,CSI 插件、亲和调度、Native Sidecar 都是顺着 K8s 的规范在做,而不是绕过它

  • ✅ 学术与工程双线:ICDE 2022、IEEE TPDS 2023 两篇论文打底,设计不是拍脑袋来的

⚠️ 注意事项与局限性:

  • ⚠️ 缓存不是免费午餐:分布式缓存要占用节点的内存、SSD 和一部分 CPU。缓存层本身也是要运维的组件,小集群、小数据集场景未必划算

  • ⚠️ 组合复杂度不低:Dataset + Runtime + DataOps + CSI + webhook,概念数量不少。对只想"把数据读快点"的团队,前期理解成本是真实存在的

  • ⚠️ 对宿主环境有要求:需要 CSI 支持,FUSE 挂载在部分受限环境(如某些托管 K8s)里会碰到权限问题。官方也明确不建议用 Minikube 部署

  • ⚠️ API 仍处于 v1alpha1:虽然已经 1.0.x 版本,CRD 版本号还是 alpha,Roadmap 里计划升级到 v1alpha2 并提供转换 webhook。做长期平台建设的话,这个迁移要提前规划

  • ⚠️ 文档以英文为主:中文社区活跃,但一手设计文档还是英文,深度定制时得啃源码

🎯 总结

Fluid 做的事情,本质上是给 K8s 补上了一块缺失的拼图:在"计算"已经被抽象得足够好的云原生世界里,"数据"也应该有同等级别的抽象和调度能力。

它不追求把数据搬到计算旁边,而是让计算主动找到数据;它不绑定任何一种缓存引擎,而是把引擎当成可替换的零件;它不发明新的运行时,而是顺着 K8s 的 CRD、CSI、调度器的规范去做。

2021 年进入 CNCF Sandbox,2026 年 1 月晋级 Incubating。这个五年,正好是 AI 训练规模从单机八卡走向千卡集群的五年。而 Fluid 的 2026 路线图指向了更热的方向:LLM KV Cache 编排、与 Mooncake 的 RDMA 加速集成、跨集群跨区域的数据流动

如果数据正在成为你 AI 基础设施里最贵的那个瓶颈,这个项目值得认真看一眼。

💬 互动环节:你们团队的 AI 训练,数据加载环节花了多少时间?用过缓存方案吗?欢迎在评论区聊聊。

🔗 相关链接

  • GitHub:https://github.com/fluid-cloudnative/fluid

  • 官网:https://fluid-cloudnative.github.io/

  • 中文文档:https://github.com/fluid-cloudnative/fluid/blob/master/docs/zh/TOC.md

本文数据来自 Fluid 仓库 README、CHANGELOG、ROADMAP、ADOPTERS 及官方文档,访问时间 2026 年 9 月 20 日。

相关学习资料