云原生走向 AI 原生:生产级 AI 工程的实战路径

2026-06-02 27 预计阅读时间:1 分钟
来源:cncf.io AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:11 分钟

KubeCon + CloudNativeCon Europe 2025 在阿姆斯特丹期间,CNCF 组织了一场圆桌讨论,AWS 的 Ellis Tarn、Google Cloud 的 Allan Naim、Microsoft 的 Jorge Palma 等人坐在一起,聊了一个越来越硬的事实:云原生已经不只是容器和微服务的故事,它正在变成 AI 原生的基础设施问题。

这意味着什么?不是在 Kubernetes 上随便跑个模型推理脚本就叫 AI 原生。真正的变化是:GPU 调度、模型版本管理、推理弹性伸缩、可观测性——这些过去只在 ML 团队内部讨论的话题,正在变成平台团队的核心职责。

从"能跑"到"能生产":AI 原生的工程差距

圆桌讨论的核心共识很清晰:很多团队在笔记本上训练模型很顺利,但一旦要把推理服务放进生产环境,问题就来了——

  • GPU 是稀缺资源,不像 CPU 可以随便超卖。调度策略必须从"尽力而为"变成"精确匹配"。
  • 模型推理的冷启动远比普通微服务严重。一个 7B 参数的模型加载到 GPU 可能需要 30 秒以上,传统 HPA 的指标驱动伸缩根本来不及。
  • 版本迭代频繁,模型权重文件动辄几 GB,镜像分发和缓存策略需要重新设计。
  • 可观测性维度变了,除了延迟和错误率,你还要盯推理吞吐、GPU 利用率、队列深度、token 消耗。

这些问题不是加一个 Helm chart 就能解决的。它们要求你重新审视整个平台层。

GPU 调度:从争抢到预约

在传统云原生环境里,Pod 争抢 CPU 是常态,kube-scheduler 用相对权重就能搞定。GPU 不行——一张卡只能被一个 Pod 独占(除非用 MPS 或 MIG 分片,但那又是另一层复杂度)。

圆桌中多位专家提到,生产环境里最实际的做法是:用节点标签和资源请求做精确匹配,避免 Pod 调度到没有 GPU 的节点上空等

下面是一个可直接使用的 GPU 推理 Deployment 示例,基于 vLLM(当前社区最活跃的开源推理引擎之一):

# vllm-inference-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: vllm-llama3-8b
  namespace: ai-inference
spec:
  replicas: 2
  selector:
    matchLabels:
      app: vllm-llama3-8b
  template:
    metadata:
      labels:
        app: vllm-llama3-8b
    spec:
      # 关键:指定只调度到有 GPU 的节点
      nodeSelector:
        gpu-type: nvidia-a10g
      tolerations:
        - key: nvidia.com/gpu
          operator: Exists
          effect: NoSchedule
      containers:
        - name: vllm
          image: vllm/vllm-openai:v0.6.6
          command: ["python", "-m", "vllm.entrypoints.openai.api_server"]
          args:
            - "--model"
            - "meta-llama/Meta-Llama-3-8B-Instruct"
            - "--max-model-len"
            - "4096"
            - "--gpu-memory-utilization"
            - "0.90"
            - "--port"
            - "8000"
          ports:
            - containerPort: 8000
          resources:
            limits:
              nvidia.com/gpu: 1  # 独占一张 GPU
            requests:
              nvidia.com/gpu: 1
              cpu: "4"
              memory: "16Gi"
          env:
            - name: HF_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: token
          volumeMounts:
            - name: model-cache
              mountPath: /root/.cache/huggingface
      volumes:
        - name: model-cache
          persistentVolumeClaim:
            claimName: model-cache-pvc

几个值得注意的点:

  1. nodeSelector 把 Pod 锁定到特定 GPU 型号的节点,避免调度到不匹配的机器上浪费等待时间。
  2. gpu-memory-utilization 设为 0.90,给 vLLM 预留 KV cache 空间,同时不把显存撑满导致 OOM。
  3. model-cache 用 PVC 持久化 HuggingFace 下载的权重文件,下次滚动更新不用重新拉几 GB 的模型。

部署命令:

# 创建 namespace 和 PVC
kubectl create namespace ai-inference

# 先创建 PVC(需要集群有支持 PV 的存储类)
kubectl apply -f model-cache-pvc.yaml -n ai-inference

# 部署推理服务
kubectl apply -f vllm-inference-deployment.yaml

# 等待 Pod 就绪(首次部署需要下载模型,可能需要 2-5 分钟)
kubectl rollout status deployment/vllm-llama3-8b -n ai-inference

# 验证推理服务是否正常响应
kubectl port-forward deployment/vllm-llama3-8b 8000:8000 -n ai-inference

curl http://localhost:8000/v1/models

弹性伸缩:冷启动是真正的敌人

圆桌讨论中反复提到一个痛点:传统 HPA 基于 CPU 利用率或 QPS 伸缩,但 AI 推理的瓶颈是 GPU 和模型加载时间。一个新 Pod 从启动到能处理请求,可能要 30-60 秒。如果用请求队列长度做伸缩指标,等新 Pod 就绪时,请求可能已经超时排走了。

目前社区有几个应对方向:

  • 预热池(warm pool):保持一定数量的"空载"Pod,模型已加载但没有请求。用 KEDA 或自定义 scaler 监控队列深度,从预热池直接接管流量,而不是从零启动。
  • 请求排队 + 优先级:用 Gateway API 或推理网关(如 NVIDIA 的 Triton Inference Server 前置代理)做请求缓冲,避免直接打到后端 Pod 导致 OOM。
  • 分时复用:低峰期用 MIG 把一张 A100 切成 7 个实例跑小模型推理,高峰期切换为整卡跑大模型。

下面是用 KEDA 基于 Prometheus 自定义指标做伸缩的配置示例:

# keda-scaler-vllm.yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: vllm-llama3-8b-scaler
  namespace: ai-inference
spec:
  scaleTargetRef:
    name: vllm-llama3-8b
  minReplicaCount: 1   # 最低保留 1 个预热 Pod
  maxReplicaCount: 8
  cooldownPeriod: 120  # 缩容冷却 2 分钟,避免频繁抖动
  triggers:
    - type: prometheus
      metadata:
        serverAddress: http://prometheus.monitoring:9090
        metricName: vllm_num_requests_running
        threshold: "30"      # 运行中的请求超过 30 就扩容
        query: |
          sum(vllm_num_requests_running{model="meta-llama/Meta-Llama-3-8B-Instruct"})

这个配置的核心思路:用 vLLM 暴露的 vllm_num_requests_running 指标(正在处理的请求数)而不是 CPU 利用率来做伸缩决策。minReplicaCount: 1 保证始终有一个预热 Pod 在线。

可观测性:你需要看见 GPU,不只是 Pod

圆桌中来自三大云厂商的专家都强调了:AI 原生环境的可观测性必须深入到 GPU 层面。传统的 CPU/内存指标对推理服务几乎是盲区——Pod 可能 CPU 只用了 10%,但 GPU 显存已经 95% 满载,随时 OOM。

实际需要监控的指标至少包括:

指标类别 具体指标 来源
GPU 硬件 DCGM_FI_DEV_GPU_UTIL, DCGM_FI_DEV_FB_FREE NVIDIA DCGM Exporter
推理引擎 vllm_num_requests_running, vllm_gpu_cache_usage_perc vLLM Prometheus 端点
请求层 请求延迟 P50/P99, token 吞吐量 Gateway / 应用层
节点层 GPU 节点总数、可用数、碎片率 Kubernetes node metrics

部署 DCGM Exporter 的快速命令:

# 使用 Helm 部署 NVIDIA DCGM Exporter(需要 Helm 3)
helm repo add nvidia https://nvidia.github.io/gpu-operator
helm repo update

helm install dcgm-exporter nvidia/gpu-feature-discovery \
  --namespace monitoring \
  --set dcgmExporter.enabled=true \
  --set dcgmExporter.serviceMonitor.enabled=true

# 验证指标是否暴露
kubectl port-forward svc/dcgm-exporter 9400:9400 -n monitoring

curl -s http://localhost:9400/metrics | grep -E "DCGM_FI_DEV_GPU_UTIL|DCGM_FI_DEV_FB_FREE"

有了这些指标,你才能在 Grafana 里画出真正有用的面板:不是"Pod 是否活着",而是"这张 GPU 还能再塞一个模型吗"。

落地前的检查清单

把圆桌讨论的共识和实战经验合并,一个团队从"云原生"过渡到"AI 原生",至少要确认这几件事:

  • GPU 节点池是否独立管理——混在普通节点池里会导致调度混乱和资源浪费。
  • 模型分发策略是否就绪——权重文件几 GB,每次从远端拉取会拖垮启动速度。PVC 缓存或镜像内嵌(适合小模型)必须提前规划。
  • 伸缩指标是否对齐推理引擎——CPU 利用率对 GPU 推理服务基本无效,必须用引擎暴露的请求深度或 GPU 利用率指标。
  • 预热机制是否存在——零冷启动的伸缩在 AI 场景下不现实,预热池或最小副本数是必须的。
  • 可观测性是否覆盖 GPU 层——没有 DCGM 指标,你对推理服务的健康状态就是半盲的。
  • 多租户隔离是否考虑——不同团队争抢 GPU 时,ResourceQuota 和 PriorityClass 要提前配置,否则高优先级任务会被低优先级的长时训练阻塞。

云原生走到今天,容器编排和网络策略已经是成熟基础设施。AI 原生不是推翻这些,而是在同一套体系里加入 GPU 调度、模型生命周期和推理可观测性这三个新维度。圆桌上的厂商专家们虽然各自产品路线不同,但在这一点上高度一致:生产级 AI 的工程问题,本质是平台问题,不是模型问题。


相关推荐