Kubernetes 已经不是新技术。它的核心对象、调度机制和运维模式相当成熟,也逐渐成为生产软件与 AI 工作负载的重要基础设施。但对许多团队来说,引入 Kubernetes 仍像一次高风险迁移;当 GPU、模型文件、推理延迟和成本控制叠加进来,这种压力会进一步放大。
真正需要回答的问题不是“AI 项目要不要上 Kubernetes”,而是“哪些运行约束已经复杂到值得交给 Kubernetes 管理”。
AI 为什么放大了集群复杂度
传统 Web 服务通常围绕 CPU、内存、请求量和无状态副本扩缩容。AI 推理和训练则增加了几类更难处理的资源:
- GPU 不仅昂贵,而且存在型号、显存和驱动版本差异。
- 模型镜像或权重可能达到数 GB,启动时间不能再被忽略。
- 请求的 token 数和上下文长度不同,单次推理成本差异很大。
- 批处理、在线推理和训练任务具有不同的调度目标。
- 扩容一个 Pod 不等于立即增加容量,因为新实例可能仍在加载模型。
Kubernetes 可以表达这些约束,却不会自动替团队设计资源策略。声明 nvidia.com/gpu: 1 只解决了“需要一张 GPU”的调度条件,并没有解决 GPU 利用率、模型装载、请求排队和成本归属。
这也是 AI 让 Kubernetes 再次显得可怕的原因:平台暴露出的配置项更多了,但真正困难的是工作负载本身变得更不均匀、更昂贵。
先建立边界,再部署模型
团队容易从安装 GPU Operator、服务网格或复杂调度器开始。更稳妥的顺序是先建立几条能被验证的边界:
- 每个团队或环境使用独立 Namespace。
- 所有容器必须声明 CPU 和内存请求及上限。
- 在线服务必须提供启动、就绪和存活探针。
- GPU 节点通过标签、污点和容忍控制用途。
- 模型下载时间、首 token 延迟和队列长度进入监控。
- 扩缩容策略考虑模型预热,而不只观察 CPU。
下面是一个可以直接改造的最小推理服务骨架。示例假设集群已经安装 NVIDIA device plugin,并把 GPU 资源注册为 nvidia.com/gpu。运行前需要把镜像、端口和健康检查路径替换成自己的推理服务;如果只想验证普通集群上的对象结构,可以删除 GPU、nodeSelector 和 tolerations。
apiVersion: v1
kind: Namespace
metadata:
name: ai-serving
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: ai-serving-quota
namespace: ai-serving
spec:
hard:
requests.cpu: "8"
requests.memory: 32Gi
limits.cpu: "16"
limits.memory: 64Gi
requests.nvidia.com/gpu: "2"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: model-server
namespace: ai-serving
spec:
replicas: 1
selector:
matchLabels:
app: model-server
template:
metadata:
labels:
app: model-server
spec:
nodeSelector:
accelerator: nvidia
tolerations:
- key: nvidia.com/gpu
operator: Exists
effect: NoSchedule
containers:
- name: server
image: registry.example.com/team/model-server:1.0.0
ports:
- name: http
containerPort: 8000
resources:
requests:
cpu: "2"
memory: 8Gi
nvidia.com/gpu: "1"
limits:
cpu: "4"
memory: 16Gi
nvidia.com/gpu: "1"
startupProbe:
httpGet:
path: /health/startup
port: http
periodSeconds: 10
failureThreshold: 60
readinessProbe:
httpGet:
path: /health/ready
port: http
periodSeconds: 5
livenessProbe:
httpGet:
path: /health/live
port: http
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: model-server
namespace: ai-serving
spec:
selector:
app: model-server
ports:
- name: http
port: 80
targetPort: http
将内容保存为 model-server.yaml 后,可以这样检查和应用:
kubectl apply --dry-run=server -f model-server.yaml
kubectl apply -f model-server.yaml
kubectl -n ai-serving rollout status deployment/model-server
kubectl -n ai-serving get pods -o wide
kubectl -n ai-serving describe resourcequota ai-serving-quota
startupProbe 在这里尤其重要。大模型加载可能耗时数分钟,如果只配置 livenessProbe,kubelet 可能在模型尚未就绪时反复重启容器。就绪探针则负责阻止流量过早进入实例,两者承担的职责不同。
不要用 CPU 指标猜测推理容量
普通 Horizontal Pod Autoscaler 经常根据 CPU 利用率扩容,但 AI 推理服务可能在 GPU 已经饱和时仍表现出较低 CPU 使用率。更有意义的指标通常包括:
- 等待处理的请求数;
- 排队时间;
- 首 token 延迟和完整响应延迟;
- GPU 利用率与显存占用;
- 每个副本的并发请求或活跃序列数;
- 实例启动和模型加载所需时间。
可以将队列长度或并发量暴露给 Prometheus,再通过指标适配器或事件驱动扩缩容组件使用。这里的关键不是选择某个特定工具,而是让扩容信号对应真正的瓶颈。若模型预热需要五分钟,告警阈值、最小副本数和预测性扩容也必须覆盖这段窗口。
训练任务还需要另一套判断:在线服务重视尾延迟和可用性,训练任务更关心吞吐、检查点和失败恢复。把两者放进相同节点池并使用相同优先级,通常会让资源争抢变得难以解释。至少应通过节点池、污点、优先级或配额明确隔离。
什么时候不该上 Kubernetes
Kubernetes 并不是 AI 项目的入场券。单机实验、低流量内部工具、短期原型以及只使用外部模型 API 的应用,可能用一台虚拟机、托管容器平台或批处理服务更省事。
当团队出现以下需求时,Kubernetes 的价值会更清晰:
- 多个模型服务需要统一部署、回滚和隔离;
- GPU 要在不同团队与任务之间调度;
- 服务存在明确的高可用和弹性要求;
- 平台已经具备监控、镜像治理和集群运维能力;
- 工作负载能够通过声明式资源和健康检查稳定表达。
采用时可以从一个非关键推理服务开始,记录部署耗时、故障恢复时间、GPU 利用率和单位请求成本。只有这些指标得到改善,才继续扩大范围。Kubernetes 能把复杂约束变成可管理对象,但它不会消除复杂性;对 AI 团队而言,最重要的能力仍是理解工作负载,并为资源、延迟和故障建立明确边界。