Skip to content

[FEATURES] support app pod using no fuse cache system without dataset volume #6176

Description

@xliuqq

CacheRuntime 支持无 FUSE Client 架构

1. 背景

1.1 当前架构

Fluid 的 CacheRuntime 支持 Master + Worker + Client 三种组件架构,其中 Client 作为 FUSE 守护进程提供数据访问。运行时配置生成在 reconcile 期间,存储在 ConfigMap 中,包含 runtime.json,挂载到各组件 Pod。

1.2 Mooncake 架构

Mooncake 是专为 LLM 推理设计的 KV-cache 存储系统,利用 RDMA 加速,不使用 FUSE 进行数据访问,而是提供原生客户端 SDK 直接读取配置。

与当前 CacheRuntime 架构的不匹配:

  • 不需要 Client 组件(FUSE 守护进程)
  • App Pod 需要通过 webhook 注入运行时配置连接 Master
  • 配置格式需要转换为 Mooncake 客户端可接受的 Shell 脚本格式

1.3 问题陈述

对 Mooncake 等无 FUSE 缓存系统,需要支持:

  1. Client 组件可禁用(已通过 Spec.Client.Disabled: true 支持)
  2. 运行时配置以 runtime.sh 形式额外提供
  3. 通过 webhook 插件将配置注入到 App Pod
  4. runtime 仍创建 PV/PVC(最小化代码改动),但 App Pod 无需指定数据集卷

1.4 关键设计决策

  1. fluid.io/dataset 是注解,标识 Pod 使用的数据集,支持逗号分隔多个
  2. fluid.io/inject: "true" 是通用标签,触发 webhook 注入,不区分 serverful/serverless
  3. webhook 插件是通用的,可处理任意无 FUSE 运行时
  4. 保留 PV/PVC 创建,最小化代码改动
  5. App Pod 只需运行时配置,不需要数据集卷

2. 设计

2.1 概述

两个关键变更:

  1. 双配置文件生成:reconcile 期间在 ConfigMap 中同时生成 runtime.jsonruntime.sh
  2. 通用配置注入插件:新增 webhook 插件,检测 fluid.io/inject: "true" 标签,注入 runtime.sh

2.2 架构图

┌─────────────────────────────────────────────────────────────────────────┐
│                     CacheRuntime Reconcile                              │
│  生成 runtime.json + runtime.sh → ConfigMap {runtime.json, runtime.sh}  │
└─────────────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                        App Pod 创建                                      │
│  标签:fluid.io/inject: "true"                                           │
│  注解:fluid.io/dataset: "ds1,ds2"                                       │
│                              │                                           │
│                              ▼                                           │
│                    Fluid Mutating Webhook                                │
│                              │                                           │
│                              ▼                                           │
│                    RuntimeConfigInjector 插件                            │
│                              │                                           │
│                              ▼                                           │
│                    注入:                                                │
│                    - 卷:fluid-runtime-config-{ds}                       │
│                    - 挂载:/etc/fluid/config/{ds}/                       │
│                    - 环境变量:FLUID_RUNTIME_CONFIG_PATH_{ds}            │
└─────────────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                     组件 Pod(Master/Worker)                            │
│  无需改动 —— 继续使用现有 transform 逻辑挂载 ConfigMap                   │
└─────────────────────────────────────────────────────────────────────────┘

2.3 实现思路

2.3.1 双配置文件生成

generateRuntimeConfigData() 中,除了生成现有的 runtime.json,额外生成 runtime.sh

  • runtime.json:保持现有 JSON 格式,向后兼容
  • runtime.sh:将 JSON 配置扁平化为 Shell 导出变量(export KEY="VALUE" 格式)

命名约定

  • 标量:PREFIX_CASE="value"
  • 数组元素:PREFIX_INDEX_FIELD="value"
  • 嵌套对象:PREFIX_SUBFIELD="value"
  • Map 类型:PREFIX_OPTIONS='{"k":"v"}'

runtime.sh 示例

#!/bin/sh
# 标量
export RUNTIME_TARGETPATH="/runtime-mnt/cache/fluid/cache-fuse"
export MASTER_ENABLED="true"
export MASTER_NAME="mooncake-master"
export MASTER_REPLICAS="1"

# 数组
export MOUNTS_COUNT=1
export MOUNT_0_NAME="default"
export MOUNT_0_PATH="/dataset/default"
export MOUNT_0_MOUNTPOINT="hdfs://..."

# Map 类型(JSON 字符串)
export MASTER_OPTIONS='{}'

2.3.2 无 FUSE Client 支持

  • PV/PVC 创建逻辑不变(最小化改动)
  • Setup 已正确处理 Client.Disabled
  • Client 组件初始化已支持禁用

2.3.3 RuntimeConfigInjector 插件

触发条件fluid.io/inject: "true" 标签 + fluid.io/dataset 注解

注入逻辑

  1. 遍历数据集列表(逗号分隔)
  2. 对每个数据集:
    • 查找对应的 ConfigMap(fluid-runtime-config-{dataset}
    • 创建独立 Volume(fluid-runtime-config-{ds}
    • 挂载到独立路径(/etc/fluid/config/{ds}/
  3. 注入环境变量(使用数据集名称作后缀):
    • FLUID_RUNTIME_CONFIG_PATH_{ds} = 路径到 runtime.sh
  4. 设置 done.sidecar.fluid.io/inject: "true" 标记

多数据集环境变量示例

export FLUID_RUNTIME_CONFIG_PATH_ds1="/etc/fluid/config/ds1/runtime.sh"
export FLUID_RUNTIME_CONFIG_PATH_ds2="/etc/fluid/config/ds2/runtime.sh"

消费者使用

source "$FLUID_RUNTIME_CONFIG_PATH_ds1"
source "$FLUID_RUNTIME_CONFIG_PATH_ds2"

2.3.4 路由逻辑变更

runtimeInfo 收集增强

  • 现有:从 PVC 收集(CollectRuntimeInfosFromPVCs
  • 新增:从 fluid.io/dataset 注解收集(CollectRuntimeInfosFromAnnotations
  • 合并两种来源的 runtimeInfo

新增路由分支

case utils.InjectEnabled(pod.GetLabels()):
    // clientless 场景:必须有 fluid.io/dataset 注解才能注入配置
    if len(runtimeInfos) == 0 {
        return nil  // 无 dataset,跳过注入
    }
    → GetClientlessPodWithDatasetHandler()

2.3.5 插件注册

新增 clientless handler 组,将 RuntimeConfigInjector 注册到该组:

webhook:
  pluginsProfile:
    plugins:
      clientless:
        withDataset:
          - RuntimeConfigInjector
        # withoutDataset 不注册任何插件:无 dataset 注解时无法确定注入哪个 ConfigMap

不复用 serverful/serverless 的原因

  • serverful:与 FUSE CSI 相关,会触发 RequireNodeWithFuseMountPropagationInjector 等插件
  • serverless:与 FUSE sidecar 相关,会触发 FuseSidecar 插件
  • clientless 场景需要独立的 handler 组,避免注入 FUSE 相关逻辑

说明:clientless 场景下,RuntimeConfigInjector 作为独立的 handler 组,统一注入运行时配置,不区分 serverful/serverless。

2.3.6 Webhook 配置

新增 webhook 规则,匹配 fluid.io/inject: "true" 标签的 Pod。

2.4 Pod 突变流程

  1. App Pod 创建,带有 fluid.io/inject: "true" 标签和 fluid.io/dataset 注解
  2. Webhook 接收请求
  3. 收集 runtimeInfo(从 PVC + annotation)
  4. 路由到 clientlessPodWithDatasetHandler
  5. RuntimeConfigInjector.Mutate() 执行:
    • 验证标签和注解
    • 查找 ConfigMap
    • 注入卷、挂载、环境变量
    • 设置完成标记
  6. Pod 完成突变

3. 实现计划

3.1 阶段一:双配置文件生成 + 无 FUSE Client 支持

需修改的文件

  • pkg/ddc/cache/engine/cm.go —— 添加 runtime.sh 生成逻辑
  • pkg/ddc/cache/engine/util.go —— 添加文件名和生成方法
  • pkg/ddc/cache/engine/volume.go/setup.go/client.go —— 验证无改动
  • pkg/ddc/cache/engine/cm_test.go —— 添加测试

步骤

  1. 实现 generateRuntimeSh() 方法
  2. 修改 generateRuntimeConfigData() 包含 runtime.sh
  3. 验证 PV/PVC 创建在 Client 禁用时正常工作
  4. 添加单元测试

3.2 阶段二:端到端测试

需新建/修改的文件

  • pkg/webhook/plugins/runtimeconfiginjector/runtime_config_injector.go —— 新插件
  • pkg/webhook/handler/mutating/mutating_handler.go —— 路由 + annotation 收集
  • pkg/webhook/utils/runtime_info.go —— annotation 收集辅助函数
  • pkg/common/constants.go —— 添加常量
  • pkg/utils/annotations.go —— 添加 InjectEnabled()
  • charts/fluid/fluid/values.yaml —— 插件配置
  • charts/fluid/fluid/templates/webhook/webhookconfiguration.yaml —— 新增规则

步骤

  1. 添加常量和辅助方法
  2. 实现 RuntimeConfigInjector 插件
  3. 新增路由分支和 annotation 收集
  4. 注册插件并配置 webhook
  5. 编写单元测试
  6. 端到端验证

4. API 变更

无需变更。现有 API 已支持:

  • Spec.Client.Disabled: true —— 禁用 FUSE Client
  • fluid.io/dataset 注解 —— 标识数据集
  • fluid.io/inject 标签 —— 触发 webhook

5. 结论

本设计使 Fluid CacheRuntime 支持无 FUSE Client 架构:

  1. 双配置文件:reconcile 生成 runtime.json + runtime.sh
  2. 无 FUSE 支持:保留 PV/PVC 创建,禁用 Client 组件
  3. 通用注入插件RuntimeConfigInjector 通过 fluid.io/inject 标签注入配置

适用于 Mooncake 等任意无 FUSE 缓存运行时。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions