【infra之路】Kubernetes 核心概念详解:AI Infra 视角下的容器编排 前言在 AI Infra 领域Kubernetes简称 K8s已经成为管理 GPU 集群和 AI 训练/推理工作负载的事实标准。无论是训练一个 7B 模型需要调度 8 张 A100还是部署一个 vLLM 推理服务需要自动扩缩容背后都是 K8s 在做资源分配和生命周期管理。但对于非运维背景的同学来说K8s 的概念体系很容易让人晕头转向Pod、Deployment、Service、ConfigMap、DaemonSet……这些东西之间是什么关系为什么需要这么多层抽象这篇文章从 AI Infra 的视角出发把 K8s 的核心概念讲清楚重点放在你需要理解到什么程度才能做好 AI 基础设施的工作。一、Kubernetes 是什么为什么需要它K8s 是一个容器编排系统。你可以把它理解为一个自动化的运维工程师你告诉它我需要 3 个 nginx 实例始终运行它就帮你保证这件事——如果有实例挂了它自动拉起新的如果节点资源不够它把实例调度到更合适的节点上。在 AI 场景下K8s 解决的核心问题是GPU 资源调度集群里有几十张 GPU谁来决定哪个训练任务用哪几张卡工作负载管理训练任务挂了怎么办推理服务需要自动扩缩容怎么办环境一致性不同人的训练环境怎么保证一致容器镜像解决了这个问题。二、集群架构控制平面 工作节点图1K8s 集群架构。左侧是控制平面Control Plane负责决策和状态管理右侧是工作节点Worker Node负责实际运行容器。一个 K8s 集群由两部分组成控制平面Control Plane / Master控制平面是集群的大脑做所有决策。它有四个核心组件kube-apiserver集群的统一入口。你对 K8s 的所有操作kubectl apply、kubectl get都是发给 API Server 的 RESTful 请求。它负责认证、授权和准入控制。etcd集群的唯一状态存储一个高可用的 Key-Value 数据库。集群的所有真相都存在这里——有哪些 Pod、哪些 Node、配置是什么。etcd 挂了整个集群就失去了记忆。kube-scheduler调度器。当一个新 Pod 被创建但还没有分配到节点时调度器根据资源需求CPU、内存、GPU、亲和性规则、节点负载等因素选出一个最合适的节点。kube-controller-manager控制器管理器。运行一系列控制器进程持续把集群的当前状态往期望状态对齐。比如你声明需要 3 个副本但实际只有 2 个控制器就会创建一个新的。工作节点Worker Node工作节点是真正干活的地方每个节点上有三个组件kubelet节点上的代理。接收控制平面的指令Pod Spec确保本节点上的容器按预期运行。它定期向 API Server 汇报节点状态。kube-proxy网络代理。维护节点上的网络规则iptables/IPVS实现 Service 的负载均衡和流量转发。容器运行时实际运行容器的软件如 containerd 或 CRI-O。早期 K8s 用 Docker现在 Docker 已被弃用直接使用 containerd。三、核心资源对象K8s 中的一切都是资源对象用 YAML 文件声明通过kubectl apply -f提交给 API Server。下面按重要性排序讲解。图2K8s 核心资源对象的关系。Deployment 管理 ReplicaSetReplicaSet 管理 PodService 通过标签选择器关联 Pod对外暴露稳定的访问入口。3.1 Pod —— 最小调度单元Pod 是 K8s 中最小的、不可再分的部署单元。一个 Pod 包含一个或多个紧密关联的容器它们共享网络命名空间同一个 IP和存储卷。你可以把 Pod 想象成一台虚拟机——里面有你的应用容器它们可以通过localhost互相通信共享同一个 IP 地址。apiVersion:v1kind:Podmetadata:name:training-joblabels:app:llm-trainspec:containers:-name:trainerimage:pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtimecommand:[python,train.py]resources:limits:nvidia.com/gpu:1# 请求 1 块 GPUmemory:32Gicpu:8重要认知Pod 是临时的随时可能被创建、销毁、重启。永远不要直接依赖 Pod IP——它每次重建都会变。这就是为什么需要 Service。3.2 Deployment —— 管理 Pod 的期望状态你不会手动创建 Pod那太累了。Deployment 帮你管理一组 Pod 的期望状态需要几个副本、用什么镜像、怎么更新。apiVersion:apps/v1kind:Deploymentmetadata:name:llm-inferencespec:replicas:3# 始终保持 3 个 Pod 运行selector:matchLabels:app:llm-inferencetemplate:# Pod 模板metadata:labels:app:llm-inferencespec:containers:-name:vllmimage:vllm/vllm-openai:latestports:-containerPort:8000resources:limits:nvidia.com/gpu:1Deployment 的工作方式是创建 ReplicaSet → ReplicaSet 创建和管理 Pod。当你更新镜像版本时Deployment 会做滚动更新Rolling Update——逐步替换旧 Pod保证服务不中断。3.3 Service —— 稳定的访问入口Pod 有 IP但 IP 会变。Service 给一组 Pod 提供一个稳定的 IP 和 DNS 名称并通过标签选择器Label Selector自动发现后端 Pod。apiVersion:v1kind:Servicemetadata:name:llm-inference-svcspec:selector:app:llm-inference# 关联标签为 appllm-inference 的 Podports:-port:80# Service 暴露的端口targetPort:8000# Pod 上容器的端口type:ClusterIP# 集群内访问Service 有几种类型类型说明场景ClusterIP集群内部 IP外部无法访问内部服务间通信NodePort在每个节点上开一个固定端口30000-32767简单的外部访问LoadBalancer由云厂商提供外部负载均衡器生产环境对外暴露服务3.4 ConfigMap 与 Secret —— 配置与密钥把配置从容器镜像中解耦出来做到一次构建镜像多处使用不同配置。# ConfigMap: 存储非敏感配置apiVersion:v1kind:ConfigMapmetadata:name:training-configdata:learning_rate:0.001batch_size:32model_name:llama-7b---# Secret: 存储敏感信息Base64 编码apiVersion:v1kind:Secretmetadata:name:wandb-secrettype:Opaquedata:api-key:d2FuZGIua2V5Lnh4eA# echo -n wandb.key.xxx | base64在 Pod 中可以通过环境变量或挂载文件的方式使用它们。3.5 Namespace —— 逻辑隔离Namespace 把集群划分成多个逻辑空间不同 Namespace 的资源互相隔离但不完全隔离网络。kubectl create namespace training# 训练任务kubectl create namespace inference# 推理服务kubectl create namespace monitoring# 监控组件在企业环境中Namespace 常用来隔离不同团队或项目配合 ResourceQuota 限制每个空间的资源上限。四、一个完整的 AI 推理服务部署示例把上面的概念串起来看一个部署 LLM 推理服务的完整 YAML# 1. ConfigMap: 推理参数apiVersion:v1kind:ConfigMapmetadata:name:vllm-configdata:model:meta-llama/Llama-2-7b-hfmax-model-len:4096gpu-memory-utilization:0.9---# 2. Secret: HuggingFace TokenapiVersion:v1kind:Secretmetadata:name:hf-tokentype:Opaquedata:token:aGZfeHh4eA---# 3. Deployment: 管理推理 PodapiVersion:apps/v1kind:Deploymentmetadata:name:llama-inferencespec:replicas:2selector:matchLabels:app:llama-inferencetemplate:metadata:labels:app:llama-inferencespec:containers:-name:vllmimage:vllm/vllm-openai:latestargs:---model-$(MODEL_NAME)---max-model-len-$(MAX_LEN)env:-name:MODEL_NAMEvalueFrom:configMapKeyRef:name:vllm-configkey:model-name:MAX_LENvalueFrom:configMapKeyRef:name:vllm-configkey:max-model-len-name:HF_TOKENvalueFrom:secretKeyRef:name:hf-tokenkey:tokenports:-containerPort:8000resources:limits:nvidia.com/gpu:1memory:32Gicpu:8---# 4. Service: 暴露稳定的 API 端点apiVersion:v1kind:Servicemetadata:name:llama-apispec:selector:app:llama-inferenceports:-port:80targetPort:8000type:LoadBalancer部署命令kubectl apply-fllm-inference.yaml kubectl get pods# 查看 Pod 状态kubectl get svc llama-api# 获取外部 IPcurlhttp://EXTERNAL-IP/v1/chat/completions-d...五、GPU 调度AI Infra 的核心话题在 AI 场景中GPU 是最稀缺的资源。K8s 原生不识别 GPU需要通过插件机制来支持。5.1 NVIDIA Device PluginK8s 通过Device Plugin 机制扩展硬件支持。NVIDIA 提供了一个 DaemonSet在每个 GPU 节点上运行向 kubelet 注册nvidia.com/gpu资源图3K8s GPU 管理与 Device Plugin 工作机制。Device Plugin 以 DaemonSet 形式运行在每个 GPU 节点上探测 GPU 资源并向 kubelet 注册kubelet 上报给 API Server调度器据此做调度决策。GPU 节点启动 → NVIDIA Device Plugin Pod 启动DaemonSet 自动部署 → 探测本节点的 GPU 数量和型号 → 向 kubelet 注册扩展资源: nvidia.com/gpu 8 → kubelet 上报给 API Server: 本节点有 8 块 GPU → 调度器就能根据 Pod 的 GPU 请求做调度决策在 Pod 中请求 GPU 只需在resources.limits中声明resources:limits:nvidia.com/gpu:2# 请求 2 块 GPU注意GPU 只能在limits中声明不能只在requests中。K8s 规定扩展资源extended resources必须 limits requests不支持超卖。5.2 节点选择与 GPU 型号集群里可能有不同型号的 GPUA100、H100、V100。通过**节点标签Node Labels**和nodeSelector / nodeAffinity让 Pod 调度到特定 GPU 的节点上# 给节点打标签kubectl label nodes gpu-node-01 gpu-modela100-80g kubectl label nodes gpu-node-02 gpu-modelh100-80g# Pod 中选择节点spec:nodeSelector:gpu-model:a100-80gNVIDIA 的 GPU Feature DiscoveryGFD工具可以自动给节点打上 GPU 型号、显存大小、互联拓扑等标签。5.3 多 GPU 分布式训练分布式训练需要多个 Pod 协同工作每个 Pod 使用若干 GPU。K8s 原生的 Deployment 不适合这种场景Pod 之间没有协调机制通常使用Job或StatefulSet配合 Volcano 等批调度器实现Gang Scheduling# Gang Scheduling: 所有 Pod 要么一起启动要么一起等apiVersion:batch.volcano.sh/v1alpha1kind:Jobmetadata:name:distributed-trainingspec:minAvailable:4# 4 个 Pod 必须同时调度成功才启动tasks:-replicas:4template:spec:containers:-name:trainerimage:my-training-image:latestresources:limits:nvidia.com/gpu:8# 每个 Pod 用 8 卡# 总共 4 Pod × 8 GPU 32 卡分布式训练Gang Scheduling 解决了分布式训练的一个关键问题如果 4 个 Worker 需要同时启动才能做 AllReduce但 K8s 只调度了 3 个那这 3 个就会一直等着——死锁。minAvailable: 4保证 4 个都准备好了才一起启动。5.4 GPU 共享与切分一张 A100 80GB 可能跑多个小推理任务。K8s 支持两种方式在多个 Pod 之间共享一张 GPU时间分片Time SlicingNVIDIA Device Plugin 把一张物理 GPU 虚拟成多份。多个 Pod 轮流使用通过时间片切换。适合推理场景不适合训练性能损耗大。MIGMulti-Instance GPUA100/H100 硬件级支持把一张 GPU 物理切分成多个独立实例如 7 个 5GB 实例每个实例有独立的显存、缓存和计算单元互不干扰。六、存储与网络基础持久化存储PVCAI 训练需要读取大量数据集、保存模型 checkpoint。Pod 重启后本地文件会丢失需要持久化存储。K8s 通过PVPersistentVolume PVCPersistentVolumeClaim模式管理存储# 声明需要 500GB 存储apiVersion:v1kind:PersistentVolumeClaimmetadata:name:dataset-storagespec:accessModes:-ReadWriteMany# 多 Pod 同时读resources:requests:storage:500GistorageClassName:nfs# 使用 NFS 后端然后在 Pod 中挂载volumes:-name:datasetpersistentVolumeClaim:claimName:dataset-storagecontainers:-name:trainervolumeMounts:-name:datasetmountPath:/data# Pod 内 /data 目录对应 PVC常见的存储后端NFS简单通用、Ceph高性能分布式、云厂商 CSI 驱动EBS、GCE PD。网络模型K8s 的网络设计遵循三个原则每个 Pod 有独立 IP——不需要端口映射Docker 的痛点Pod 之间可以直接通信——跨节点也能直连Node 上的代理可以和该 Node 上的所有 Pod 通信网络实现由 CNI 插件负责Calico、Cilium、Flannel 等。对 AI Infra 来说Pod 间通信主要用于分布式训练的梯度同步性能敏感场景通常配合 RDMA 网络。七、常用 kubectl 命令速查# 集群信息kubectl cluster-info# 集群状态kubectl get nodes-owide# 节点列表含 GPU 信息kubectl describenodegpu-node-01# 节点详情GPU 分配情况# 资源管理kubectl apply-fdeployment.yaml# 创建/更新资源kubectl delete-fdeployment.yaml# 删除资源kubectl get pods-owide# Pod 列表含节点和 IPkubectl get svc# Service 列表kubectl get events --sort-by.metadata.creationTimestamp# 集群事件# 调试kubectl logspod-name# 查看容器日志kubectl logs-fpod-name# 实时跟踪日志kubectlexec-itpod-name--bash# 进入容器kubectl describe podpod-name# Pod 详情含事件和调度信息kubectltoppods# Pod 资源使用率# GPU 相关kubectl get nodes-Lnvidia.com/gpu.product# 查看各节点 GPU 型号kubectl get pods-ocustom-columnsNAME:.metadata.name,GPU:.spec.containers[*].resources.limits.nvidia\.com/gpu# 查看各 Pod 的 GPU 请求量八、AI Infra 面试常见 K8s 问题QPod 和容器的区别是什么Pod 是 K8s 的调度单元可以包含多个容器。容器是实际运行的进程。一个 Pod 里的容器共享网络和存储彼此可以通过localhost通信。K8s 不直接管理容器只管理 Pod。QDeployment 的滚动更新是怎么工作的Deployment 创建新的 ReplicaSet逐步增加新 Pod 数量同时减少旧 ReplicaSet 的 Pod 数量。通过maxSurge最多多出的 Pod 数和maxUnavailable最多不可用的 Pod 数控制节奏保证服务不中断。Q如何在 K8s 上调度 GPU 任务通过 NVIDIA Device Plugin 注册nvidia.com/gpu扩展资源Pod 在resources.limits中声明 GPU 需求调度器根据节点可用 GPU 数量做调度。用 nodeSelector 或 nodeAffinity 选择特定 GPU 型号的节点。Q什么是 Gang Scheduling为什么 AI 训练需要它Gang Scheduling 保证一组 Pod 要么全部被调度成功、要么全部等待。分布式训练如 8 卡 AllReduce要求所有 Worker 同时在线才能通信如果只启动了一部分就会死锁。Gang Scheduling 通过minAvailable解决这个问题。QService 的 ClusterIP 和 NodePort 有什么区别ClusterIP 只在集群内部可访问适合服务间内部通信。NodePort 在每个节点上开一个固定端口30000-32767外部可以通过NodeIP:NodePort访问。生产环境通常用 LoadBalancer 类型由云厂商提供外部负载均衡。九、总结K8s 的概念体系虽然庞大但核心逻辑很清晰声明式 API 控制器模式。你声明我要什么YAML控制器持续工作把现实往你的声明对齐。Pod 是最小运行单元Deployment 管理 Pod 的副本和更新Service 提供稳定访问入口ConfigMap/Secret 管理配置。对于 AI Infra 工程师来说最重要的能力是理解 GPU 调度机制Device Plugin、节点标签、Gang Scheduling能写训练/推理的 YAML 配置知道怎么用 PVC 管理数据和模型存储会用 kubectl 排查问题。这些是日常工作中每天都在用的东西。参考资料Kubernetes 官方文档 — PodKubernetes 全景指南从核心概念到云原生未来Kubernetes GPU 调度完全指南从入门到生产实践云原生 AI 平台搭建从集群规划到 GPU 调度的全链路设计实践GPU 感知调度与设备插件机制深度解析