KServe 架构学习笔记:控制平面、数据平面与模型服务 CRD

一、KServe 是什么

KServe 是 Kubernetes 上的模型服务平台。它的核心价值不是单纯帮我们启动一个 Pod,而是把"模型服务"抽象成 Kubernetes 自定义资源,让用户用声明式 YAML 管理模型服务的生命周期。

如果不用 KServe,部署一个模型服务通常需要自己维护很多 Kubernetes 资源,例如:

复制代码
Deployment
Service
Ingress / Gateway
HPA / KEDA
模型下载逻辑
模型运行时容器
监控指标
灰度发布策略

而使用 KServe 后,用户通常只需要声明一个 InferenceService,KServe Controller 会根据这个资源自动创建和维护底层 Kubernetes 资源。可以简单理解为:

复制代码
KServe = Kubernetes 上的模型服务平台层

InferenceService = 模型服务版的 Deployment + Service + Ingress/Gateway + HPA + 模型加载配置

对于运维人员来说,KServe 的意义是:把模型服务从"手写一堆 Kubernetes 资源"变成"声明一个模型服务对象",由控制器自动完成资源编排、网络暴露、模型加载、扩缩容和生命周期管理。


二、KServe 的两大平面

KServe 架构可以分成两大部分:

复制代码
用户提交 YAML
   |
   v
控制平面 Control Plane
   |
   | 负责创建、更新、删除、编排底层 Kubernetes 资源
   v
数据平面 Data Plane
   |
   | 负责真正接收请求、加载模型、执行推理
   v
返回推理结果

1. 控制平面

控制平面负责"管理"。它主要处理这些事情:

复制代码
监听 InferenceService / InferenceGraph 等 CRD
创建 Deployment / Service / Gateway / Ingress / HPA 等底层资源
注入模型下载逻辑
选择 ServingRuntime
维护模型服务生命周期
处理扩缩容配置
处理网络入口配置
处理本地模型缓存

可以理解为:

复制代码
控制平面 = 模型服务的大脑

它不直接跑模型推理,而是负责把模型服务相关资源"管起来"。


2. 数据平面

数据平面负责"干活"。它主要处理这些事情:

复制代码
接收推理请求
加载模型
执行预测 / 生成
做前处理
做后处理
做模型解释
返回结果

可以理解为:

复制代码
数据平面 = 真正跑模型推理请求的部分

在 KServe 中,数据平面主要由 PredictorTransformerExplainer 和流量入口组件组成。


三、控制平面核心资源

3.1 InferenceService:最核心的模型服务资源

InferenceService 是 KServe 最常用、最核心的资源。可以把它理解为:

复制代码
InferenceService = 一个模型服务的总声明

例如部署一个 Hugging Face 模型:

复制代码
apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
metadata:
  name: qwen-llm
  namespace: kserve-demo
spec:
  predictor:
    model:
      modelFormat:
        name: huggingface
      args:
        - --model_name=qwen
      storageUri: "hf://Qwen/Qwen2.5-0.5B-Instruct"
      resources:
        requests:
          cpu: "1"
          memory: 4Gi
          nvidia.com/gpu: "1"
        limits:
          cpu: "2"
          memory: 6Gi
          nvidia.com/gpu: "1"

这段 YAML 的意思是:

复制代码
我要部署一个模型服务
模型格式是 huggingface
模型来源是 Hugging Face
模型名称叫 qwen
运行时需要 1 张 NVIDIA GPU
底层 Deployment、Service、网络入口、模型加载由 KServe 管理

需要注意的是,InferenceService 不是普通 Pod。用户声明的是"模型服务",KServe Controller 会根据这个声明创建和维护底层资源。

在 Standard 模式下,InferenceService 背后通常会关联这些资源:

复制代码
InferenceService
  ├── Deployment
  ├── Service
  ├── Gateway API / Ingress
  ├── HPA / KEDA
  ├── Storage Initializer
  └── Predictor Runtime Container

所以从运维角度看,InferenceService 可以理解为模型服务的上层抽象。


3.2 InferenceGraph:多个模型服务的编排

InferenceGraph 不是用来部署单个模型的,它主要用于多个模型服务之间的编排。

比如一个 OCR 流程可能是:

复制代码
图片输入
  -> 预处理服务
  -> 版面分析服务
  -> OCR 识别服务
  -> 后处理服务
  -> 返回结果

这种多个服务串起来的场景,就可以用 InferenceGraph 表达。

KServe 的 InferenceGraph 支持四种路由类型:

复制代码
Sequence:顺序执行多个步骤
Switch:根据条件选择一个分支
Ensemble:多个模型并行执行并合并结果
Splitter:按权重分发流量

示例:

复制代码
apiVersion: serving.kserve.io/v1alpha1
kind: InferenceGraph
metadata:
  name: ocr-pipeline
spec:
  nodes:
    root:
      routerType: Sequence
      steps:
        - serviceName: preprocess
          name: preprocess
        - serviceName: ocr-model
          name: ocr
          data: $response
        - serviceName: postprocess
          name: postprocess
          data: $response

这个流程表示:

复制代码
请求先进入 preprocess
preprocess 的结果传给 ocr-model
ocr-model 的结果再传给 postprocess
最后返回处理后的结果

这里要注意几个点:

复制代码
入口节点必须叫 root
每个 step 只能指定一个目标:serviceName、serviceUrl 或 nodeName
Splitter 类型下,所有 step 的 weight 总和需要为 100
Sequence 中常见写法是用 data: $response 把上一步结果传给下一步

所以 InferenceGraph 更像是模型服务编排器,适合多模型、多步骤、条件路由、A/B 测试、模型集成等场景。


3.3 ServingRuntime 和 ClusterServingRuntime:模型用什么运行时跑

很多人刚学 KServe 时容易混淆这两个概念:

复制代码
InferenceService:我要部署什么模型
ServingRuntime:这个模型用什么运行时跑

ServingRuntimeClusterServingRuntime 都是用来定义模型运行环境的 CRD。

区别是:

复制代码
ServingRuntime:namespace 级别,只在某个命名空间内可用
ClusterServingRuntime:集群级别,所有命名空间都可用

它们会定义:

复制代码
运行时镜像
支持的模型格式
启动参数
环境变量
资源配置
探针配置

示例:

复制代码
apiVersion: serving.kserve.io/v1alpha1
kind: ServingRuntime
metadata:
  name: example-runtime
spec:
  supportedModelFormats:
    - name: example-format
      version: "1"
      autoSelect: true
  containers:
    - name: kserve-container
      image: examplemodelserver:latest
      args:
        - --model_dir=/mnt/models
        - --http_port=8080

这表示:

复制代码
这个 Runtime 支持 example-format 模型格式
使用 examplemodelserver:latest 镜像启动
模型目录是 /mnt/models
HTTP 端口是 8080

KServe 官方也内置了一些常用的 ClusterServingRuntime,例如:

复制代码
kserve-sklearnserver
kserve-xgbserver
kserve-tensorflow-serving
kserve-tritonserver
kserve-huggingfaceserver

对于 LLM 场景,常见关系可以理解为:

复制代码
InferenceService:
  我要部署 Qwen 模型,模型格式是 huggingface,模型地址是 hf://xxx

ClusterServingRuntime:
  huggingface 这种模型格式,用 kserve-huggingfaceserver 运行

也就是说,InferenceService 声明模型,ServingRuntime / ClusterServingRuntime 定义模型怎么运行。


3.4 LocalModelCache:把大模型缓存到节点本地

大模型经常几十 GB、上百 GB。如果每次 Pod 启动都从 Hugging Face、S3、GCS、对象存储里下载模型,会带来几个问题:

复制代码
冷启动时间长
依赖外部网络
扩容慢
滚动升级慢
重复下载浪费带宽和存储

LocalModelCache 就是为这个问题设计的。它的思路是:

复制代码
提前把模型缓存到节点本地磁盘 / PVC / NVMe
后续模型服务启动时直接从本地加载
减少重复下载
加快模型 Pod 启动速度

相关资源包括:

复制代码
LocalModelCache:定义模型缓存需求和策略
LocalModelNode:节点级缓存状态管理
LocalModelNodeGroup:对缓存节点进行分组

从运维角度看,它解决的是:

复制代码
问题:模型太大,Pod 冷启动慢
方案:提前把模型缓存到 GPU 节点本地
收益:Pod 重建、扩容、滚动升级时更快拉起

对于 LLM 服务来说,LocalModelCache 是非常重要的优化方向。


3.5 模型存储与 Storage Initializer

KServe 支持多种模型来源,例如:

复制代码
Amazon S3
Google Cloud Storage
Azure Blob Storage
HTTP / HTTPS
Git
PVC
Hugging Face
OCI Images

InferenceService 中,传统写法通常是使用 storageUri 指定模型地址:

复制代码
storageUri: "s3://my-bucket/models/qwen"

或者:

复制代码
storageUri: "hf://Qwen/Qwen2.5-0.5B-Instruct"

KServe 还支持 storageUris,用于从多个位置拉取模型文件并挂载到不同路径。需要注意,storageUri 和 storageUris 是互斥的。一个 InferenceService 里要么使用 storageUri,要么使用 storageUris,不能两个同时写。这里有一个关键组件:Storage Initializer。它通常以 initContainer 的形式工作,在模型服务容器启动前先把模型下载到本地目录,常见目录是:

复制代码
/mnt/models

典型流程如下:

复制代码
InferenceService 创建
  |
  v
Storage Initializer 启动
  |
  v
从 S3 / GCS / PVC / Hugging Face / OCI 拉取模型
  |
  v
模型文件放到 /mnt/models
  |
  v
Predictor 容器启动
  |
  v
模型服务开始对外提供推理

四、数据平面核心组件

4.1 Predictor:核心推理组件

Predictor 是 KServe 数据平面最核心的组件,也是唯一必需的组件。它负责:

复制代码
加载模型
启动模型服务进程
接收推理请求
执行预测 / 生成
返回推理结果
管理 CPU / 内存 / GPU 资源
处理推理协议

普通 Kubernetes 部署中,真正跑业务的是 Deployment 里的业务容器。

在 KServe 中,可以这样类比:

复制代码
普通 Kubernetes:
Deployment 里的业务容器

KServe:
InferenceService 里的 Predictor Runtime 容器

例如:

复制代码
spec:
  predictor:
    model:
      modelFormat:
        name: huggingface
      storageUri: "hf://Qwen/Qwen2.5-0.5B-Instruct"
      resources:
        limits:
          nvidia.com/gpu: "1"

这里的 predictor 就是最终提供模型推理能力的部分。


4.2 Transformer:前处理和后处理组件

Transformer 是可选组件,主要用于请求进入模型前、模型返回结果后做加工。

常见场景:

复制代码
请求进入模型前:
  图片 resize
  文本清洗
  JSON 格式转换
  参数校验
  特征补全

模型返回结果后:
  结果格式化
  后处理过滤
  标签映射
  分数排序
  返回业务结构

比如 OCR 场景可以这样理解:

复制代码
用户上传 PDF
  |
  v
Transformer:PDF 转图片、切页、构造模型输入
  |
  v
Predictor:执行 OCR 模型推理
  |
  v
Transformer:整理识别结果,输出业务 JSON
  |
  v
返回用户

所以 Transformer 更像是模型前后的业务适配层。


4.3 Explainer:模型解释组件

Explainer 也是可选组件,用于解释模型为什么做出某个预测。

例如分类模型返回:

复制代码
{
  "class": "cat",
  "score": 0.93
}

业务方可能还想知道:

复制代码
为什么模型认为这是 cat?
哪些特征影响了结果?
图片中哪些区域贡献最大?
文本中哪些词影响最大?

这就是 Explainer 的作用。可以简单理解为:

复制代码
Predictor:给出推理结果
Transformer:对输入输出做加工
Explainer:解释结果为什么是这样

4.4 Gateway:流量入口与协议适配

KServe 的数据平面还需要流量入口组件,例如:

复制代码
Gateway API
Ingress
Knative Gateway
Istio / Envoy Gateway

它们负责:

复制代码
请求路由
负载均衡
流量拆分
协议转换
入口暴露

典型流量路径如下:

复制代码
用户请求
  |
  v
Gateway / Ingress
  |
  v
Kubernetes Service
  |
  v
Predictor Pod
  |
  v
模型推理结果返回

如果 Predictor 有多个副本:

复制代码
Gateway
  |
  v
Service
  |
  |-- predictor pod 1
  |-- predictor pod 2
  |-- predictor pod 3

Gateway / Ingress 负责入口路由,Service 负责把请求分发到后端 Pod。


五、KServe 的推理协议

KServe 同时支持传统预测模型和生成式 AI 模型。

5.1 传统预测模型

传统 ML / DL 模型通常使用:

复制代码
KServe V1 Protocol
Open Inference Protocol V2

V1 常见接口形式:

复制代码
/v1/models/<model-name>:predict
/v1/models/<model-name>:explain

V2 常见接口形式:

复制代码
/v2/models/<model-name>/infer

V2 更偏标准化推理协议,适合和 Triton 等推理服务集成。


5.2 LLM / 生成式 AI 模型

对于 LLM 场景,KServe 支持 OpenAI-compatible API。

常见接口包括:

复制代码
/openai/v1/chat/completions
/openai/v1/completions
/openai/v1/embeddings

例如:

复制代码
curl -H "Content-Type: application/json" \
  -H "Host: qwen-llm.kserve-demo.example.com" \
  http://<INGRESS_HOST>/openai/v1/chat/completions \
  -d '{
    "model": "qwen",
    "messages": [
      {
        "role": "user",
        "content": "你好,请介绍一下 KServe"
      }
    ],
    "max_tokens": 128,
    "stream": false
  }'

这对 LLM 平台非常重要,因为很多上层应用、SDK、网关都已经兼容 OpenAI API 格式。


六、Standard 模式和 Knative 模式

KServe 有两种主要部署模式:

复制代码
Standard Deployment Mode
Knative Mode

6.1 Standard Deployment Mode

Standard 模式使用标准 Kubernetes 资源:

复制代码
Deployment
Service
Gateway API / Ingress
HPA
可选 KEDA

特点:

复制代码
更接近传统 Kubernetes 运维方式
更容易排查问题
更适合长连接、流式输出、GPU 模型、LLM 服务
不支持 HTTP 请求的 scale-from-zero

对于 LLM 场景,Standard 模式通常更适合生产环境。原因是 LLM 服务有这些特点:

复制代码
模型大
启动慢
依赖 GPU
请求可能是长连接
可能需要流式输出
冷启动成本高

如果频繁 scale-to-zero,再从 0 拉起大模型,用户请求会遇到明显冷启动延迟。


6.2 Knative Mode

Knative 模式依赖 Knative Serving,底层会使用:

复制代码
Knative Service
Revision
Queue Proxy
Knative Autoscaler
Knative Gateway

特点:

复制代码
支持按请求自动扩缩容
支持 scale-to-zero
支持 Revision 管理
适合突发流量、低频服务、实验环境
运维复杂度更高
冷启动问题更明显

Knative 模式适合:

复制代码
低频模型服务
成本敏感场景
希望空闲时缩到 0 的服务
实验环境
突发请求场景

6.3 两种模式对比

复制代码
Standard 模式:
  使用 Deployment / Service / HPA / Gateway API
  不支持 HTTP scale-from-zero
  运维更接近原生 Kubernetes
  更适合 LLM 和生产场景

Knative 模式:
  使用 Knative Service / Revision / Queue Proxy
  支持 scale-to-zero
  支持基于 Revision 的流量切分
  更适合低频、突发、成本敏感场景

七、一个完整请求在 KServe 里的流转

以一个 LLM 服务为例,请求流程大致如下:

复制代码
1. 用户提交 InferenceService YAML
        |
2. KServe Controller 监听到 InferenceService
        |
3. Controller 创建 Deployment / Service / Gateway / HPA 等资源
        |
4. Storage Initializer 下载模型到 /mnt/models
        |
5. Predictor Runtime 容器启动
        |
6. Runtime 加载模型,例如 Hugging Face Runtime + vLLM backend
        |
7. 用户请求进入 Gateway / Ingress
        |
8. 请求转发到 Service
        |
9. Service 转发到 Predictor Pod
        |
10. Predictor 执行推理 / 生成
        |
11. 返回 OpenAI-compatible API 响应

如果配置了 Transformer,则流程变成:

复制代码
用户请求
  |
  v
Transformer 前处理
  |
  v
Predictor 推理
  |
  v
Transformer 后处理
  |
  v
返回结果

如果是 explain 请求,则会进入 Explainer 生成解释结果。


八、总结

KServe 可以理解为 Kubernetes 上的模型服务平台层。

它的核心思想是:

复制代码
用户声明模型服务
KServe Controller 编排底层 Kubernetes 资源
ServingRuntime 决定模型怎么运行
Storage Initializer 负责模型下载
Predictor 真正执行推理
Transformer 做前后处理
Explainer 做模型解释
Gateway / Ingress 负责流量入口

一句话总结:

复制代码
KServe 可以简单理解为 Kubernetes 上的模型服务平台层,其中 KServe Controller 负责监听 InferenceService 等 CRD,并编排底层 Kubernetes 资源。

你写 InferenceService,
KServe 帮你创建 Deployment、Service、Gateway、HPA、模型下载和运行时配置;
真正处理请求的是数据平面的 Predictor / Transformer / Explainer;
模型怎么跑由 ServingRuntime 决定;
模型从哪里来由 storageUri / storageUris 和 Storage Initializer 决定;
大模型启动慢可以用 LocalModelCache 优化。
相关推荐
ん贤20 天前
KServe 部署教程(CPU版)
云原生·kserve
一个向上的运维者4 个月前
基于k8s的KServe 控制平面生产级部署最佳实践:基于 Gateway API 的标准化流量管理方案
llm·gateway·istio·kserve