从Docker到Kubernetes:AI应用服务化与弹性伸缩的落地实践

把AI应用跑起来和把它跑成生产级服务,中间隔着一道巨大的鸿沟。Docker把应用装进了容器,解决了"环境一致性"的问题;但真正让应用能抗住流量洪峰、自动恢复故障、弹性伸缩的,是Kubernetes这套云原生的调度系统。

这篇文章从AI应用的特殊性出发,走一遍从Docker到K8s的完整演进路径,并给出可直接复用的代码和配置示例。

一、AI应用容器化的特殊之处

普通的Web应用打镜像,就是把代码和依赖装进去。但AI应用有几个让人头疼的地方:

依赖复杂 :CUDA版本、Python包、推理引擎(vLLM、Triton等)------这些组合稍有偏差镜像就启动不起来。根据实践,官方推荐的策略是基于vLLM等推理框架的预构建镜像进行二次扩展,例如使用 vllm/vllm-openai:latest-cu124 作为基础镜像。

镜像巨大:模型文件动辄几十GB。如果在每次构建时把模型也打包进镜像,构建和推送都会慢到怀疑人生。因此业界通常采用两种方案:模型挂在PVC(持久卷)上,新Pod直接挂载无需重新下载;或者使用专门优化的Dockerfile分层构建。

GPU资源调度:容器需要明确知道自己能用哪些GPU,不能自己抢资源。

二、Docker阶段:打包AI应用

这是起点。以下是一个基于vLLM的Dockerfile示例,用于封装一个兼容OpenAI API的推理服务:

dockerfile 复制代码
# 基于vLLM官方镜像,CUDA 12.4
FROM vllm/vllm-openai:latest-cu124

WORKDIR /app

# 模型文件通过PVC挂载,不打包进镜像(推荐方式)
# 若需打包小模型,可COPY ./model /app/model

EXPOSE 8000

# 启动vLLM服务
CMD ["python", "-m", "vllm.entrypoints.openai.api_server", \
     "--model", "/app/model", \
     "--tensor-parallel-size", "1", \
     "--max-model-len", "131072", \
     "--gpu-memory-utilization", "0.95"]

关键参数说明

  • --tensor-parallel-size:单卡为1;多卡按实际GPU数调整
  • --max-model-len:受显存限制,24GB显存建议设为128K
  • --gpu-memory-utilization:vLLM内存池占用比例,推荐0.85~0.95

构建与推送:

bash 复制代码
docker build -t my-registry/ai-agent:latest .
docker push my-registry/ai-agent:latest

三、Kubernetes基础部署:让Agent跑在集群里

3.1 GPU调度配置

在K8s里调度GPU,首先需要安装NVIDIA设备插件。Kubernetes通过Device Plugin机制将GPU暴露为可调度资源,如nvidia.com/gpu

GPU Pod示例

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: gpu-test
spec:
  containers:
    - name: cuda-container
      image: nvcr.io/nvidia/cuda:12.0-base
      resources:
        limits:
          nvidia.com/gpu: 1  # 请求1个GPU
      command: ["nvidia-smi"]

重要限制 :GPU资源只能在limits中指定,不能在requests中单独申请------Kubernetes默认将limit值作为request。两者可以同时设置但必须相等。

3.2 部署AI Agent服务

将前述Docker镜像部署为K8s Deployment,并配上Service和探针:

yaml 复制代码
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ai-agent
  labels:
    app: ai-agent
spec:
  replicas: 3
  selector:
    matchLabels:
      app: ai-agent
  template:
    metadata:
      labels:
        app: ai-agent
    spec:
      containers:
        - name: agent
          image: my-registry/ai-agent:latest
          ports:
            - containerPort: 8000
          env:
            - name: OPENAI_API_KEY
              valueFrom:
                secretKeyRef:
                  name: api-secrets
                  key: openai-api-key
          resources:
            limits:
              nvidia.com/gpu: 1
              memory: "32Gi"
              cpu: "8"
            requests:
              memory: "16Gi"
              cpu: "4"
          livenessProbe:
            httpGet:
              path: /health
              port: 8000
            initialDelaySeconds: 30
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /ready
              port: 8000
            initialDelaySeconds: 5
            periodSeconds: 5

探针的作用livenessProbe在容器僵死时触发重启;readinessProbe确保只有健康实例接收流量,二者配合实现服务的自愈能力。

配套Service将Pod暴露为稳定的网络入口:

yaml 复制代码
# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: ai-agent-service
spec:
  type: LoadBalancer
  selector:
    app: ai-agent
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8000

四、弹性伸缩:让Agent能扛住流量洪峰

单靠固定副本数,流量高峰时扛不住,低谷时又浪费资源。Kubernetes提供了HorizontalPodAutoscaler(HPA)实现自动扩缩容。

4.1 基于CPU/内存的HPA

最简单的场景:CPU超过70%就扩容,低于阈值就缩容:

yaml 复制代码
# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: ai-agent-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: ai-agent
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 80

4.2 基于自定义指标的HPA(针对LLM场景)

CPU和内存指标对LLM服务往往不够敏感------模型推理是GPU密集型,CPU可能不高但GPU已满载。针对vLLM等推理框架,更精准的做法是基于队列长度等待请求数做扩缩容。

通过Prometheus采集vLLM暴露的num_requests_waiting指标,再由Prometheus Adapter转换成HPA可用的自定义指标:

yaml 复制代码
# 基于KEDA + Prometheus的自定义扩缩容配置
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: llm-keda
spec:
  scaleTargetRef:
    name: ai-agent
  minReplicaCount: 1
  maxReplicaCount: 10
  triggers:
    - type: prometheus
      metadata:
        serverAddress: http://prometheus:9090
        metricName: llm_queue_length
        threshold: "1000"   # 队列超过1000个请求即扩容

根据vLLM生产堆栈的实践,结合ReadWriteMany(RWX)存储类可以让新Pod启动时无需重新下载模型权重,大幅缩短扩容时间,实现秒级弹性。

4.3 Knative Serverless:缩容到0

如果业务有明显的波峰波谷(如企业下班后几乎无请求),Knative Serving可以实现更激进的弹性:空闲时缩容到0 Pod,请求到来时冷启动拉起,电费和GPU成本降低90%以上。

yaml 复制代码
# Knative Service示例
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: ai-agent
spec:
  template:
    metadata:
      annotations:
        autoscaling.knative.dev/minScale: "0"
        autoscaling.knative.dev/maxScale: "10"
        autoscaling.knative.dev/metric: "concurrency"
        autoscaling.knative.dev/target: "50"
    spec:
      containers:
        - image: my-registry/ai-agent:latest
          resources:
            limits:
              nvidia.com/gpu: 1

核心配置minScale: 0允许缩容到零;target: 50表示每个Pod维持50个并发请求。

五、进阶:Operator模式管理多AI服务

当AI服务规模扩大到数十甚至上百个Agent实例时,手动管理Deployment和HPA变得不可持续。此时引入自定义资源(CRD)+ Operator模式,将Agent的生命周期管理抽象为声明式配置。

yaml 复制代码
apiVersion: ai.io/v1alpha1
kind: Agent
metadata:
  name: hr-assistant
spec:
  image: my-registry/ai-agent:latest
  knowledgeBase:
    s3: "s3://company-kb/hr/"
  resources:
    limits:
      nvidia.com/gpu: 1
  autoscaling:
    maxReplicas: 5
    targetQueueLength: 500

Operator自动监听Agent资源的增删改,创建对应的Deployment、Service、HPA和Ingress。这种模式让AI Agent的部署从"写一堆YAML"变成了"写一个意图声明",是大型企业级部署的最佳实践。

总结

从Docker到Kubernetes,AI应用的部署能力逐级跃升:

阶段 核心技术 解决的问题
Docker容器化 Dockerfile + 镜像仓库 环境一致性、依赖固化
K8s基础部署 Deployment + Service + 探针 高可用、负载均衡、故障自愈
GPU调度 Device Plugin + limits配置 GPU资源管理和隔离
弹性伸缩 HPA / KEDA / Knative 按需扩缩容、成本优化
企业级管理 Operator + CRD 规模化运维、声明式管理

记住:先让应用在Docker里跑通,再一步步往K8s迁移。每一个阶段都有明确的收益,不必一上来就追求最复杂的方案。对于绝大多数AI应用,基础K8s部署 + GPU调度 + HPA弹性伸缩这组合已经能覆盖90%的生产需求。

相关推荐
ZzzZZzzzZZZzzzz…1 小时前
K8S实战:NFS+StorageClass+PV/PVC+Deployment
运维·云原生·容器·kubernetes·storageclass·linux运维·持久卷
程序员cxuan1 小时前
Claude Opus 5 的系统提示词被扒出来了
人工智能·后端·程序员
董员外1 小时前
RAG 系统进化论(十):可运营 RAG,从原型到长期运行的知识系统
人工智能·后端·设计模式
二川bro1 小时前
从零跑通大模型全流程:基于Qwen3‑0.6B微调中医模型并Docker部署
人工智能
网易云信1 小时前
权威认可!网易智企帝王蟹入选信通院《2026 智能体创新实践汇编》
人工智能·agent
吾鳴1 小时前
用一句话需求,做完一张 9:16 的 Skill 发布海报:我把设计生图交给 Agent 试了一次
人工智能·aigc·agent
yuluo_YX1 小时前
什么是 OpenAI Responses API?
人工智能·chatgpt
三言老师1 小时前
CentOS7.9 + Kubernetes 1.18.20 -清理所有 docker / containerd 残留
docker·容器·kubernetes
云浪1 小时前
从 0 到实战:掌握向量数据库 Milvus,构建 AI 应用的核心能力
javascript·数据库·人工智能
tachibana22 小时前
知识库文档上传接口
数据库·人工智能·大模型·llm