从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%的生产需求。

相关推荐
冬奇Lab5 小时前
Code Agent 解剖(14):Harness 设计之四——容错与恢复
人工智能·开源
冬奇Lab6 小时前
一天一个开源项目(第202篇):Needle 2 - 14MB 的端侧工具调用模型
人工智能·开源·资讯
林澈在路上6 小时前
AI翻唱软件哪个好 2026国产AI写歌工具对比推荐
大数据·人工智能·深度学习·github·aigc·音视频·音频
咖啡星人k6 小时前
2026 MCP 模型上下文协议:让 AI 自己动手接工具,告别手写接口(MonkeyCode 实战)
人工智能·深度学习·机器学习·语言模型·自然语言处理
yyuuuzz6 小时前
记一次 VPS 性能排查:共享 CPU 突发额度导致的限流
运维·服务器·人工智能
恋猫de小郭6 小时前
看懂大模型架构术语,帮助你理解目前常见的大模型开源架构
前端·人工智能·ai编程
tachibana26 小时前
复杂任务怎么做的任务拆分?
人工智能·ai·大模型·llm·agent
tachibana26 小时前
ReAct、Plan-and-Execute、Reflection 三种范式有什么核心区别
人工智能·ai·大模型·llm·agent
————A6 小时前
Agent 接收用户上传文件
人工智能·笔记·python·状态模式
gx23486 小时前
控制器管理
docker·容器·kubernetes