返回博客

/ AI Infra

[Infra-5] k8s和infra

从大模型服务的部署、调度、扩缩容和故障恢复出发,解释 K8s 在 AI Infra 里的位置,以及它和 Docker、Ray、Slurm、vLLM 等系统的关系。

9 minInfra · Kubernetes · K8s · LLM Serving

我一开始理解 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=INFO

Secret 用于敏感信息:

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 解决的是“这些推理服务怎么在一整个集群里被部署、调度、暴露、扩缩容和恢复”。