/ AI Infra
[Infra-5] K8s and Infra
A practical walkthrough of where Kubernetes fits in AI infrastructure: deployment, scheduling, scaling, recovery, and its relationship with Docker, Ray, Slurm, and LLM serving engines.
我一开始理解 K8s 时,很容易把它想成一个“更复杂的 Docker”:Docker 能跑容器,K8s 也能跑容器,所以 K8s 只是把 docker run 包了一层。
这个理解不算完全错,但它漏掉了最重要的一点:K8s 不是为了让一台机器更方便地跑容器,而是为了让一批机器像一个统一平台一样运行服务。
所以我现在更愿意这样理解 K8s:
Docker 负责把应用打包成容器。
K8s 负责把大量容器稳定地跑在一整个集群上。如果再放到 AI Infra 里,K8s 的位置就更清楚了:
K8s 不直接让模型算得更快,
但它决定模型服务能不能被稳定、自动化、可扩展地部署和管理。对于 vLLM、SGLang、Ray Serve、TGI、TensorRT-LLM 这类模型服务来说,能在单机上跑起来只是第一步。真正进入生产系统以后,问题会变成:资源怎么分配、实例怎么调度、服务怎么暴露、挂了怎么恢复、流量怎么切、多个团队怎么共享集群。
这些就是 K8s 和 Infra 的交汇处。
1. K8s 到底解决什么问题#
假设我们只有一台机器,要启动一个推理服务,可能就是一句命令:
docker run -p 8000:8000 my-llm-server这在 demo 阶段很自然。问题是,真实 infra 场景通常不是一台机器、一个容器、一个服务。
你可能有:
- 100 台服务器;
- 800 张 GPU 或其他加速卡;
- 多个在线推理服务;
- 多个离线 batch 推理任务;
- 训练任务和数据处理任务;
- 网关、监控、日志、存储、权限系统;
- 多个团队共用同一个资源池。
这时候,真正麻烦的问题会出现:
- 哪个服务应该跑在哪台机器上?
- 某台机器宕机以后,上面的服务怎么办?
- 某个容器 OOM 以后,要不要自动重启?
- 用户请求怎么路由到正确的服务实例?
- 请求量上涨时,怎么扩更多副本?
- GPU、CPU、内存、网络资源怎么分配?
- 不同团队怎么隔离资源和权限?
- 配置、密钥、日志、指标怎么统一管理?
K8s 解决的不是“如何启动一个容器”,而是:
如何把一堆机器抽象成一个统一资源池,
并在这个资源池上自动化地运行大量容器化服务。这就是为什么 K8s 常被称为云原生时代的“集群操作系统”。它不是传统意义上的 Linux kernel,但它确实在集群维度上做了类似操作系统的事情:资源抽象、任务调度、状态维护、故障恢复和服务发现。
2. K8s 和 Docker 的区别#
Docker 更偏向单机容器能力。它关心的是:
这个镜像怎么构建?
这个容器怎么启动?
这个容器怎么挂载目录、映射端口、设置环境变量?比如:
docker run nginx这句话的含义是:
在当前这台机器上启动一个 nginx 容器。K8s 关心的是集群编排。你通常不会只说“启动一个容器”,而是声明一个期望状态。例如:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-demo
spec:
replicas: 3
selector:
matchLabels:
app: nginx-demo
template:
metadata:
labels:
app: nginx-demo
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80这份 YAML 的含义不是“现在启动三个 nginx,然后结束”,而是:
请让整个集群一直维持 3 个 nginx 副本。
如果少了,就补回来。
如果要升级镜像,就滚动更新。
如果某个节点不可用,就把实例迁走或重建。这里有一个关键差异:K8s 是声明式系统。
你告诉 K8s “我希望系统最终是什么状态”,K8s 里的控制器会不断观察真实状态,并尝试把真实状态拉回期望状态。
所以 Docker 更像“容器运行工具”,K8s 更像“容器调度和集群管理系统”。
3. K8s 的核心抽象#
K8s 概念很多,但如果先从 AI Infra 和服务部署角度看,最重要的是下面几类。
3.1 Cluster:一组被统一管理的机器#
K8s 管理的一组机器叫 Cluster。
一个集群通常分成两类节点:
- Control Plane:管理面,负责 API、调度、状态存储和控制循环;
- Worker Node:工作节点,真正运行业务 Pod。
在 AI Infra 里,Worker Node 往往就是 GPU 服务器或其他加速卡服务器,例如 A100、H100、H20、L20、MLU、Ascend 等节点。
业务方通常不应该关心“我要 SSH 到哪台机器上启动进程”,而是把需求提交给 K8s:我要多少 CPU、多少内存、多少 GPU、用什么镜像、跑几个副本。
3.2 Pod:最小调度单位#
K8s 不直接调度单个 Docker 容器,而是调度 Pod。
一个 Pod 可以包含一个或多个容器,这些容器共享一部分网络和存储上下文。
例如一个 LLM 推理 Pod 里可能包含:
- vLLM 主服务容器;
- metrics exporter 容器;
- 日志 sidecar 容器;
- 初始化模型权重的 init container。
可以粗略理解为:
Pod 是 K8s 里的一个服务实例。对于在线推理服务,一个 Pod 通常对应一个可接收请求的模型服务实例。这个实例内部可能使用 1 张卡,也可能使用 4 张或 8 张卡做 tensor parallel。
3.3 Deployment:管理无状态服务#
Deployment 用来管理一组相同的 Pod,并维持期望副本数。
例如:
replicas: 4表示希望始终有 4 个副本在运行。
如果某个 Pod 挂了,K8s 会创建新的 Pod 补上;如果你更新镜像版本,K8s 可以滚动替换旧 Pod。
对于 FastAPI、网关、embedding 服务、reranker 服务、部分推理服务来说,Deployment 是很常见的部署方式。
3.4 Service:稳定入口和服务发现#
Pod 是会变化的。它可能被重启、迁移、扩容或缩容,因此 Pod IP 不能作为长期稳定入口。
K8s 用 Service 给一组 Pod 提供稳定访问方式。
例如集群内其他服务可以访问:
llm-service.default.svc.cluster.local而不用关心背后现在有几个 Pod、每个 Pod 的 IP 是什么。
Service 做的是服务发现和负载均衡。它让上层调用方看到一个稳定名字,背后实例变化由 K8s 处理。
3.5 Ingress / Gateway:外部流量入口#
Service 更偏集群内部入口。如果外部用户要访问模型 API,通常还需要:
- Ingress;
- API Gateway;
- Load Balancer;
- Nginx;
- Envoy / Istio。
一个典型路径可能是:
https://api.example.com/v1/chat/completions
-> API Gateway / Ingress
-> K8s Service
-> 推理服务 Pod
-> GPU 上的模型实例在大模型服务里,网关层往往还会做鉴权、限流、路由、灰度、审计和 tracing。
3.6 ConfigMap / Secret:配置和密钥#
镜像应该尽量保持环境无关,配置则由运行环境注入。
ConfigMap 常用于普通配置:
MODEL_PATH=/models/qwen
MAX_BATCH_SIZE=64
LOG_LEVEL=INFOSecret 用于敏感信息:
API_KEY
DB_PASSWORD
ACCESS_TOKEN这样,同一个镜像可以部署到 dev、staging、prod 等不同环境,只需要换配置,不需要重新构建镜像。
4. Scheduler:AI Infra 里最关键的一层#
K8s Scheduler 负责决定一个 Pod 放在哪台机器上。
普通 Web 服务可能只需要 CPU 和内存:
resources:
requests:
cpu: "2"
memory: "4Gi"LLM 推理服务则经常需要 GPU:
resources:
limits:
nvidia.com/gpu: 4这表示这个 Pod 需要 4 张 NVIDIA GPU。
在 AI Infra 里,调度问题会比普通 Web 服务复杂很多。因为 GPU 不是一个完全同质的资源,调度器可能需要考虑:
- GPU 类型:A100、H100、H20、L20、A800 等;
- 显存大小:40GB、80GB、96GB 等;
- 单机 GPU 数量;
- NVLink / PCIe 拓扑;
- NUMA 亲和性;
- RDMA 和跨机网络;
- 本地模型权重缓存;
- 多租户隔离;
- 作业优先级和抢占策略;
- 在线推理和离线任务的干扰。
例如同样是 4 张 GPU,如果它们在同一台机器上并且 NVLink 互联,和跨机器通过网络连接,推理性能可能完全不同。对于 tensor parallel 推理,这种拓扑差异会直接影响通信成本。
所以在 AI Infra 中,K8s 的原生调度能力通常还会结合:
- node label / node selector;
- taint / toleration;
- affinity / anti-affinity;
- device plugin;
- 自定义 scheduler;
- queueing system;
- GPU sharing 或 MIG;
- gang scheduling。
K8s 给出了通用框架,但大模型场景往往需要在这个框架上继续做资源和拓扑感知调度。
5. K8s 在 Infra 里的位置#
Infra 是 Infrastructure,也就是基础设施。它不是某一个组件,而是一整套让业务稳定运行的底层能力。
在 AI 或软件系统里,Infra 通常包括:
- 计算资源:CPU、GPU、MLU、NPU;
- 存储资源:本地盘、NAS、对象存储、模型仓库;
- 网络资源:VPC、交换机、RDMA、负载均衡;
- 容器系统:Docker、containerd;
- 集群编排:K8s、Slurm;
- 分布式计算:Ray、Spark、MPI;
- 模型服务:vLLM、SGLang、TGI、TensorRT-LLM;
- 监控系统:Prometheus、Grafana;
- 日志系统:Loki、ELK;
- CI/CD:GitHub Actions、GitLab CI、ArgoCD;
- 权限安全:RBAC、IAM、Secret 管理;
- 服务治理:网关、限流、熔断、灰度发布。
K8s 不是 Infra 的全部。它更像现代云原生 Infra 的中间底座:
向下管理机器、容器、网络、存储和加速卡资源;
向上承载模型服务、后端服务、数据任务和平台组件。如果没有 K8s,很多事情也能做,但往往会变成脚本、SSH、手工运维和平台碎片化。K8s 的价值在于把这些操作标准化、声明式化、自动化。
6. 在 AI Infra 里的典型链路#
一个大模型在线推理系统可以粗略写成:
用户请求
-> API Gateway / Ingress
-> K8s Service
-> 推理服务 Pod:vLLM / SGLang / TGI / TensorRT-LLM
-> GPU / MLU / NPU
-> 模型权重 / KV Cache / 存储系统K8s 在这里主要负责七件事。
第一,部署推理服务。
例如把 Qwen、DeepSeek、GLM 或其他模型服务部署成若干个 Pod。
第二,调度 GPU 资源。
例如指定一个 Pod 使用 4 张 GPU,或者只调度到带有特定型号 GPU 的节点。
第三,维持服务副本。
如果希望服务有 2 个实例,K8s 会持续检查实际状态,并在实例缺失时补齐。
第四,故障恢复。
如果推理进程崩溃、Pod 异常退出或节点不可用,K8s 可以尝试重启或重建实例。
第五,服务发现和流量入口。
调用方访问 Service 或 Gateway,而不是直接访问 Pod IP。
第六,灰度发布。
新版本镜像可以先发布少量副本,或者通过网关只导入一部分流量。
第七,多租户管理。
不同团队、项目、环境可以通过 Namespace、ResourceQuota、RBAC 等机制隔离。
这些能力本身不会改变模型的 attention 计算,也不会让单次 matmul 更快。但它们会显著影响生产系统的稳定性、扩展性和资源利用率。
7. K8s 和 Ray / Slurm / vLLM 的关系#
大模型 Infra 里经常会同时出现这些名字:
K8s
Ray
Slurm
Docker
vLLM
SGLang
Triton
Prometheus
Grafana它们不是同一层的东西。可以粗略分成:
硬件层:
GPU / MLU / NPU / CPU / 网络 / 存储
容器层:
Docker / containerd
集群编排层:
K8s / Slurm
分布式计算层:
Ray / Spark / MPI
模型服务层:
vLLM / SGLang / TGI / TensorRT-LLM / Triton
应用层:
Chat API / Agent / RAG / Web App
可观测性层:
Prometheus / Grafana / Loki / ELK / tracing其中:
- K8s 管服务、容器、资源和期望状态;
- Docker 或 containerd 负责容器镜像和容器运行;
- Ray 管分布式 Python 任务、actor 和任务图;
- Slurm 更常见于 HPC 和训练集群的批作业调度;
- vLLM / SGLang 负责模型推理执行;
- Prometheus / Grafana 负责指标采集和可视化。
很多系统会把这些层组合起来。例如:
K8s 管机器和容器
Ray 管分布式任务和 actor
vLLM 管单个或多个模型推理 worker
Gateway 管外部请求和路由
Prometheus 管指标采集所以不要问“K8s 和 vLLM 谁替代谁”。它们不是替代关系,而是上下游关系。K8s 负责把 vLLM 这样的服务部署、调度和管理起来;vLLM 负责真正执行模型推理。
8. 一个具体例子:部署 vLLM 推理服务#
假设我们要上线一个 Qwen 模型服务。没有 K8s 时,可能会变成:
ssh gpu-node-1
docker run ...
ssh gpu-node-2
docker run ...
ssh gpu-node-3
docker run ...然后还要手动处理:
- 端口冲突;
- 进程挂掉;
- 日志查看;
- 机器故障;
- 服务升级;
- 流量转发;
- 扩缩容。
有 K8s 后,我们可以声明一个 Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: qwen-inference
spec:
replicas: 2
selector:
matchLabels:
app: qwen-inference
template:
metadata:
labels:
app: qwen-inference
spec:
containers:
- name: vllm
image: vllm/vllm-openai:latest
args:
- "--model"
- "/models/qwen"
- "--tensor-parallel-size"
- "4"
ports:
- containerPort: 8000
resources:
limits:
nvidia.com/gpu: 4这表示:
部署 2 个 vLLM 推理实例,每个实例需要 4 张 GPU。再配一个 Service:
apiVersion: v1
kind: Service
metadata:
name: qwen-inference
spec:
selector:
app: qwen-inference
ports:
- port: 8000
targetPort: 8000这样集群内其他服务就可以通过稳定的 Service 名称访问它,而不用关心具体 Pod 在哪台机器上。
当然,真实生产部署还会更复杂:模型权重挂载、健康检查、启动探针、显存预热、日志采集、metrics 暴露、优雅下线、灰度策略、拓扑约束都要补齐。但最核心的思想就是:
把“手动在机器上跑进程”,变成“向集群声明服务期望状态”。9. 为什么 AI Infra 工程师需要懂 K8s#
大模型服务不是 python serve.py 跑起来就结束了。
生产环境真正关心的是:
- 服务能不能长期稳定运行;
- GPU 利用率是否足够高;
- 请求峰值来了能不能扩容;
- 某个节点挂了是否影响用户;
- 模型版本如何灰度发布和回滚;
- 多个团队如何共享 GPU 集群;
- 日志、指标、trace 如何采集;
- 权限、网络和密钥如何控制;
- 在线推理和离线任务如何共存;
- 故障发生后如何快速定位。
这些都不是单个模型框架能完全解决的问题,而是 Infra 问题。
K8s 的价值在于,它提供了一套标准控制面,让服务部署、资源调度、状态维护、故障恢复、服务发现和配置管理都有统一入口。
对 AI Infra 工程师来说,懂 K8s 不等于只会写 YAML。更重要的是理解:
一个模型服务从代码到线上请求,中间经过了哪些系统层;
每一层负责什么;
瓶颈和故障可能出现在哪里。这也是为什么在分析大模型系统时,不能只看模型和推理引擎,还要看它们运行在哪个集群平台上。
10. 一句话总结#
K8s 是现代云原生 Infra 的核心调度和编排系统。它把服务器、GPU、网络、存储和容器组织成一个统一平台,让模型服务、后端服务和数据任务能够自动化、可扩展、可恢复地运行。
对于 AI Infra 来说:
K8s 不负责让单次模型计算更快,
但它负责让模型服务以生产系统的方式稳定运行。如果说 vLLM、SGLang、TensorRT-LLM 解决的是“模型怎么推理”,那么 K8s 解决的是“这些推理服务怎么在一整个集群里被部署、调度、暴露、扩缩容和恢复”。