Kubernetes 已经为平台团队提供了一套统一的容器部署、扩缩容和运维方式。现在,越来越多团队又被要求把 AI 工作负载放进同一套平台。问题在于:能稳定运行 Web 服务的 Kubernetes 集群,并不一定已经具备运行训练、推理和 GPU 密集型任务的条件。
AI 转型不只是给现有 Deployment 加一块 GPU。平台团队还需要重新审视资源调度、镜像体积、模型文件、节点池、可观测性、成本控制以及租户隔离。真正的目标,是让开发者能够用熟悉的 Kubernetes 工作流提交 AI 服务,同时让平台团队保留对基础设施和风险的控制力。
从“容器平台”到“AI 平台”,变化在哪里
传统微服务通常围绕 CPU、内存、网络和副本数来设计。AI 工作负载则会引入一组更具体的约束:
- GPU 或其他加速器资源:推理服务可能需要一张 GPU,训练任务可能需要多张 GPU,并且对显存有明确要求。
- 更大的镜像与模型文件:模型权重可能达到数 GB 甚至更大,拉取和挂载策略会直接影响启动时间。
- 不同的工作负载形态:在线推理关心延迟和并发,训练任务关心吞吐、检查点和长时间运行稳定性。
- 更高的资源成本:GPU 节点通常比普通 CPU 节点昂贵,错误的副本数或空闲资源会快速放大成本。
- 更严格的环境一致性:CUDA、驱动、深度学习框架和模型运行时之间需要保持兼容。
因此,平台就绪并不等于“集群里安装了 GPU 驱动”。它至少意味着:团队已经定义了 AI 工作负载如何进入集群、如何获得资源、如何被观测,以及失败后如何恢复。
一份可落地的 Kubernetes 推理服务示例
下面的示例假设集群已经完成 GPU 节点配置,并安装了能够暴露 nvidia.com/gpu 资源的设备插件。它部署一个需要一块 GPU 的推理服务,并通过节点标签把工作负载限制在 GPU 节点上。
运行前请根据实际环境修改镜像地址、端口和节点标签。示例中的镜像名只是占位符,不代表某个特定模型或厂商产品。
apiVersion: apps/v1
kind: Deployment
metadata:
name: model-server
namespace: ai
labels:
app: model-server
spec:
replicas: 1
selector:
matchLabels:
app: model-server
template:
metadata:
labels:
app: model-server
spec:
nodeSelector:
accelerator: nvidia
containers:
- name: inference
image: registry.example.com/ai/model-server:1.0.0
ports:
- name: http
containerPort: 8080
env:
- name: MODEL_ID
value: "example-model"
resources:
requests:
cpu: "2"
memory: "8Gi"
nvidia.com/gpu: "1"
limits:
cpu: "4"
memory: "16Gi"
nvidia.com/gpu: "1"
readinessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 30
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: model-server
namespace: ai
spec:
selector:
app: model-server
ports:
- name: http
port: 80
targetPort: http
可以用下面的命令创建命名空间、检查 GPU 资源,并部署服务:
kubectl create namespace ai --dry-run=client -o yaml | kubectl apply -f -
kubectl get nodes -L accelerator
kubectl describe node <gpu-node-name> | grep -A5 -E 'Allocatable|nvidia.com/gpu'
kubectl apply -f model-server.yaml
kubectl -n ai get pods -o wide
kubectl -n ai describe pod -l app=model-server
这个清单解决了“把一个 GPU 服务调度起来”的最小问题,但它没有自动解决模型下载、滚动升级、流量入口、GPU 利用率和多租户隔离。生产环境需要把这些问题显式纳入平台设计,而不是依赖应用团队各自摸索。
平台团队需要补齐的能力
1. 把 GPU 当作可治理的资源
平台团队应为 GPU 节点建立清晰的节点池和标签,例如区分 GPU 型号、显存大小和可用区域。调度规则不能只依赖“有 GPU 就运行”,还要考虑模型对显存、拓扑和区域的要求。
资源请求和限制也应成为发布规范的一部分。没有明确资源边界的 AI Pod,很容易造成调度失败、节点碎片化或成本失控。对共享集群而言,还应结合 ResourceQuota、LimitRange、优先级和抢占策略,避免单个训练任务挤占在线推理服务。
2. 区分训练、批处理和在线推理
这三类任务不应使用完全相同的运维策略:
- 在线推理:需要健康检查、滚动发布、低延迟扩缩容和稳定的服务入口。
- 批处理或离线推理:更适合 Job、队列或工作流系统,并应支持失败重试与结果落盘。
- 训练任务:通常运行时间更长,需要检查点、任务恢复、数据访问和更严格的资源预约。
如果把训练任务简单包装成长期运行的 Deployment,平台很难准确表达任务完成、失败重试和检查点恢复等语义。
3. 让模型和数据的生命周期可控
把模型权重直接打进应用镜像虽然简单,但会让镜像变大,升级和回滚速度变慢。可以根据模型大小、更新频率和安全要求,选择对象存储、持久卷、节点本地缓存或专用模型仓库。
无论采用哪种方式,都应明确以下问题:模型版本如何固定?Pod 重启时是否需要重新下载?不同租户能否访问同一份模型?模型文件是否经过完整性校验?这些问题比“容器能否启动”更接近生产可用性。
4. 重新定义可观测性
CPU 和内存指标不足以说明 AI 服务是否健康。平台至少应关注:
- GPU 利用率、显存使用率和显存不足错误;
- 请求延迟、吞吐量、并发数和排队时间;
- 模型加载时间、冷启动次数和 Pod 重启次数;
- 每个团队、模型和请求的资源消耗;
- 推理错误率以及模型版本对应的服务质量变化。
可观测性还应与成本关联起来。只有知道一块 GPU 被哪个服务、哪个团队使用,平台团队才能判断是扩容、换型号、降低副本,还是优化模型运行时。
不要把“能调度”误认为“已生产就绪”
AI 平台建设最容易出现的误区,是把一次成功的 GPU Pod 启动当作平台完成的标志。实际上,平台还要回答一系列运营问题:
- GPU 节点不可用时,服务是否有明确的降级或重调度策略?
- 模型下载失败时,Pod 是否会进入可诊断的失败状态?
- 发布新模型时,旧版本如何保留和回滚?
- 高峰期扩容是否会受到 GPU 节点供应和启动时间限制?
- 多个团队共享昂贵节点时,配额、优先级和账单如何划分?
- 敏感数据、模型权重和推理日志是否符合组织的安全要求?
这些问题没有一份通用 YAML 可以全部解决。Kubernetes 提供的是编排基础,平台团队仍需结合组织的模型仓库、数据系统、监控体系、供应商和合规要求做出取舍。
一份采用前检查清单
可以用下面的清单评估现有 Kubernetes 平台是否真的适合承载 AI:
- [ ] GPU 节点、驱动和设备插件已经经过版本兼容性验证。
- [ ] 不同 GPU 型号、显存和区域可以通过标签与调度规则表达。
- [ ] AI 工作负载有明确的 CPU、内存和加速器资源请求。
- [ ] 在线推理、批处理和训练使用了匹配的工作负载控制器。
- [ ] 模型与数据的存储、缓存、版本和访问权限已经定义。
- [ ] 平台能够观测 GPU、模型加载、延迟、吞吐和成本。
- [ ] 团队已经验证失败重试、滚动升级和回滚流程。
- [ ] 多租户配额、优先级和安全边界经过实际演练。
Kubernetes 仍然可以成为 AI 基础设施的重要底座,但“容器平台已经成熟”只是起点。接下来要做的,不是盲目增加更多组件,而是把 AI 工作负载的资源、生命周期和运营约束转化为可重复的开发者体验。这样,平台才不仅能运行容器,也能稳定地承载 AI。