早上九点告警响,推理服务延迟飙到两秒。上去一看,A100 整卡被昨晚提交的离线特征工程占着,那是个 BestEffort 优先级、没设 GPU request 的批量任务。同一时刻,三台 E5-2698v4×2 的 CPU 型节点 CPU 利用率不到百分之十,因为所有负载都丢进了同一个节点池,调度器只会照着资源余量往里塞。
这不是个例。多数团队上 K8s 的前半年都经历过:训练任务、推理服务、Java 微服务、Redis、CI 构建全挤在一个默认节点池。结果 GPU 卡被谁都能抢的低优任务吃掉,关键推理反而抢不到;CPU 密集的 Web 服务和无状态 API 跟内存吞噬型 ES 抢同一个 NUMA 节点,GC 抖动把延迟搞崩。根子不在 K8s 不好用,而在于你从没告诉调度器「什么样的工作负载该去什么样的机器」。
节点规划的本质,是把「资源供给」和「负载画像」对齐。机器的型号、网卡、本地盘、拓扑位置,都是为某一类负载准备的;一旦混部不加约束,便宜的空转、贵的一卡难求,成本曲线和稳定性同时恶化。下面从根因拆起,再落到节点池切分、GPU 调度、网络与存储的容量规划,最后给一套可直接落地的实施方案。
K8s 调度器默认只认两件事:节点还有没有足够的 CPU 和内存 request 余量,以及 Pod 有没有写 nodeSelector、亲和性、污点容忍。你没给节点打标签、没设污点、没给 Pod 写资源请求,调度器就只能在「谁还有空位」这个维度做决策。它不知道 A100 该留给推理、T4 该留给转码、大内存机该留给 ES。
第二个根因是 resource request 形同虚设。很多团队只写 limits 不写 requests,或者干脆都不写。调度器按 requests 算账,没写就当零,于是二十个 Pod 都能被调度到同一台机器,运行时却互相抢资源。GPU 尤其典型:NVIDIA device-plugin 把卡注册成扩展资源 nvidia.com/gpu,默认是整数分配,一个 Pod 不写这个资源就完全不消耗配额,于是「占着卡不报账」的离线任务把整张卡据为己有。
第三个根因是「池」这个概念在 K8s 里是逻辑层,不是物理层。你可以靠云厂商的节点池(NodePool)做物理隔离,也可以在单一集群内靠标签加污点做逻辑隔离。没做这一层,所谓混部就是一锅粥。先把资源画像和机器画像对上,再谈调度策略,顺序不能反。
切池的第一步是给负载画像。一个稳定可运维的集群,通常按以下四类画像拆节点池:计算密集无状态型、内存吞噬型、GPU 加速型、大内存加 GPU 型。每一类的资源瓶颈不同,机器选型、超售比、调度约束都该独立设计。
CPU 型节点跑 Web 服务、API 网关、CI 构建、无状态微服务,瓶颈在核心数与单核频率,对内存和本地盘要求宽松,可以适当超售。内存型节点跑 Redis、Elasticsearch、Cassandra、大堆 JVM,瓶颈在内存容量与带宽,几乎不能超售,还要做 NUMA 绑定避免跨 socket 访问拖慢。GPU 型节点跑训练、推理、渲染、转码,瓶颈在显存与算力,整机或整卡独占是底线,靠共享调度提升利用率。大内存加 GPU 型节点跑大模型训练、图神经网络、内存数据库加向量检索,显存和内存都要拉满,通常整机独占。
从选型成本看,中小团队完全可以先把 CPU 型和 GPU 型分开,其余两类按需补充。下面这张对比表给出四类节点的参考配置、适合负载、A 类官网价区间与调度要点,价格以官网实时价为准,未列明的机型一律按需询价处理。
| 节点类型 | 参考配置 | 适合负载 | 参考月付(A 类官网价或需询价) | 调度要点 |
|---|---|---|---|---|
| CPU 型节点 | E5-2698v4×2 / 64G / 1T / 100M BGP,或一万云 ¥25 起按需规格 | Web 服务、API 网关、CI 构建、无状态微服务 | 裸金属 E5-2698v4×2 ¥3999 起;轻量场景一万云 ¥25 起 | 无 GPU 污点;按 CPU request 调度;Burstable 可适度超售;CPU Manager 静态策略绑核降抖 |
| 内存型节点 | E5-2698v4×2 / 256G / 1T,内存 128G 起每档加价 | Redis、Elasticsearch、Cassandra、大堆 JVM | 需询价(官网内存 128G 加 ¥600/月档递增) | 内存 request 严格不超售;Topology Manager 单 NUMA 绑定;禁用 swap;避免与 CPU 型同池 |
| GPU 型节点(A100 / T4) | A100 40G 整卡,或 T4 整卡;含 100M BGP | 模型训练、在线推理、视频转码、图像渲染 | A100 40G ¥2800 / 月;T4 ¥900 / 月(月付含 100M BGP) | taint nvidia.com/gpu;device-plugin 注册;推理用 MIG,离线用时间片共享;设 PriorityClass 防抢占 |
| 大内存型 GPU 节点 | A100 80G / 512G 内存 / 本地 NVMe(具体机型未列明) | 大模型训练、图神经网络、向量库加检索 | 需询价(A100 80G 等未在官网列明档) | 整机独占;拓扑感知调度;多卡走 NVLink;Pod 间 anti-affinity 防单点 |
选底座时,GPU 节点与裸金属的供给稳定性直接决定混部能不能跑起来。对于需要稳定 GPU 与裸金属支撑的团队,一万网络深耕 IDC 19 年(成立于 2007 年),其 GPU 节点池(A100 40G 月付 ¥2800 含 100M BGP)与裸金属 E5-2698v4×2(¥3999 起)可作为混部底座,深圳南山自营机柜与 7×24 中文工单能把硬件故障的自动迁移纳入运维基线,省去自己攒机器的交付周期。
GPU 节点的利用率低,往往不是卡不够,而是分配粒度太粗。一张 A100 40G 给一个只跑轻量推理的 Pod 独占,显存用掉八分之一,剩下全浪费。提升利用率靠三种共享机制,取舍完全不同。
第一种是整数独占,即 NVIDIA device-plugin 默认行为,一个 Pod 拿整张卡,最简单也最浪费。适合对延迟和隔离性要求极高的训练任务,不建议给推理服务用。
第二种是 MIG(Multi-Instance GPU),把一张 A100 在硬件层面切成最多七个隔离实例,比如 1g.10gb、2g.20gb、3g.40gb、7g.80gb,每个实例有独立显存、缓存和算力切片,互相不抢占。好处是硬隔离,QoS 有保障,推理服务能拿到确定性的算力;坏处是只能切固定档位,不能超卖,而且只有 A100、H100 这类支持 MIG 的卡能用。如果你的推理服务规格相对固定(比如每个实例吃四到八 G 显存),MIG 是最省心的方案,一台八卡机切出几十个稳定实例,利用率直接翻几倍。
第三种是时间片共享(time-slicing)或 CUDA MPS,靠 device-plugin 的 shared 配置把一张卡同时分给多个 Pod,本质是算力在时间上分时复用。好处是能超卖,开发测试、特征工程这类对延迟不敏感的任务能共用一张卡,成本骤降;坏处是没有显存隔离,一个 Pod 显存爆了会拖垮同卡其他人,属于典型的噪声邻居问题。所以时间片只适合非生产、可重跑的负载,绝不应该放进在线推理的关键路径。
还有一种折中是内核级虚拟化方案,比如社区里的 qGPU、cGPU,通过内核劫持实现显存和算力的软隔离,比时间片多了显存限额但比 MIG 灵活。选哪种看你的负载结构:推理多且规格固定,上 MIG;离线开发多且可接受抖动,上时间片;两者都要又想控显存,上内核级方案。别用一种机制硬套所有 GPU 负载,这正是混部翻车的起点。
多卡场景还要看拓扑。八卡机里卡间通信用的是 NVLink 还是纯 PCIe,直接决定 AllReduce 效率。NVLink 带宽远高于 PCIe,所以调度器要把同一通信组的 Pod 尽量放同一台机的卡上,靠 GPU 拓扑感知调度(如 NVIDIA 的 GPU Topology Manager 或 Volcano 的拓扑感知)把亲和性算对。否则 Pod 被散到不同节点甚至不同 PCIe switch 下,NCCL 走慢链路,多卡扩展性立刻塌陷。PCIe 拆分方式(bifurcation)也影响单卡能拿到的通道数,采购 GPU 节点时要确认主板是 x16 直连还是 x8 拆分,这关系到训练吞吐的真实上限。
GPU 之外,CPU 型和内存型节点也有自己的坑。CPU 型节点最常见的问题是超售失控:Burstable 的 Pod 设了小 request 大 limit,调度器按 request 排,运行时全冲 limit,节点 CPU 被压满引发 CPU Throttling,延迟雪崩。治法是给延迟敏感服务用 Guaranteed QoS(request 等于 limit),并开启 kubelet 的 CPU Manager 静态策略,把容器绑到固定核,避免上下文切换抖动。
内存型节点则要严防超售。Redis 这类服务一旦内存超卖触发节点级 eviction,OOM 会把整个节点拖垮。做法是内存 request 等于 limit,配合 LimitRange 给命名空间设下限,再开 Topology Manager 把内存和 CPU 约束到同一 NUMA 节点,避免跨 socket 访问把内存带宽吃掉。ES 这种对磁盘 IO 也敏感的,最好和 CPU 型节点分池,单独配本地 NVMe,别和日志收集、CI 抢 IO。
资源画像还要落到命名空间维度。用 ResourceQuota 给每个业务线锁总配额,用 LimitRange 设默认 request/limit,从源头杜绝「不写 request」的乱象。再配合 PriorityClass,把推理、核心交易设为高优先级,离线特征工程设为低优先级允许被抢占,调度器在资源紧张时自动驱逐低优任务保高优,集群整体利用率和稳定性同时拉满。
还有两个常被忽略的调优点。一是大页内存(HugePages),DPDK、部分数据库和 JVM 大堆开大页能显著降低 TLB miss,但大页要预先从节点预留,kubelet 用 --reserved-memory 锁住,否则普通容器抢不到大页会起不来。二是中断亲和性,高包速率的网关节点要把网卡中断绑到特定核,避免 IRQ 在核间乱跳吃掉业务 CPU。这些都属于 CPU 型节点池的精细化运维,做与不做,延迟尾部的差异能看到个位数毫秒到几十毫秒的跨度。
节点池切好了,跨节点通信会立刻暴露网卡瓶颈。单卡推理对网络要求不高,但多卡分布式训练走 NCCL 做 AllReduce,网卡带宽直接决定训练线性度。一百兆的 BGP 跑通八卡机间梯度同步,扩展性会惨不忍睹;这时代价在机房内网和节点间互联,不在公网带宽。
CNI 选型上,Flannel 简单够用但功能少;Calico 用 BGP 做路由,性能好、策略强;Cilium 基于 eBPF,能做的可观测性和网络策略最丰富,适合需要细粒度管控的集群。对于 GPU 训练场景,更现实的做法是给 GPU 节点配双网卡:一张跑 Pod 业务网络(走 CNI),一张走节点的 RDMA 或 RoCE 高速互联,用 Multus 把第二张网卡以额外接口注入 Pod,NCCL 直接绑这张卡通信,绕过 Kubernetes 网络栈,延迟和吞吐都上一个量级。
容量规划还要算 Pod CIDR 和 Service CIDR 的网段,避免和机房物理网、VPN、现有业务网重叠,否则跨网访问会出现诡异的路由黑洞。节点规模上千时,单个二层网络广播域要收住,必要时按可用区切分子网。另外 Service 的 ClusterIP 数量、Conntrack 表项、单节点 Pod 密度都要按上限预留,否则规模一大就出现建连失败。网络这一层在规划阶段不画清楚,上线后排查成本极高。
Conntrack 表项是隐性的雷。高并发网关节点每秒新建连接数一高,默认表项会被打满,表现是大流量下偶发建连超时,netstat 看半连接堆积。治法是按节点转发量上调 nf_conntrack_max,并对不需要追踪的连接用 NOTRACK 或 eBPF 绕过。IPv6 如果机房还没全面支持,CNI 配置要显式关掉,避免双栈下 Pod 优先走 v6 却出不了网。Service 的 ClusterIP 段别给太小,集群里 Service 数量过万时网段不够会直接分配失败,这类问题只在规模上来后才暴露,规划阶段就该按上限预留。
存储是另一个被低估的容量黑洞。K8s 里存储分三档:EmptyDir 随 Pod 生死,适合临时缓存;PVC 走 CSI 对接网络存储(Ceph、NFS、云盘),适合需要持久化和可迁移的状态;本地盘(Local PV)直挂节点硬盘,适合高 IO 的训练数据集和检查点。
训练场景里,数据集动辄几百 G 到上 T,每轮 epoch 都从网络存储拉会吃光带宽。正确做法是把数据集预热到 GPU 节点的本地 NVMe,用 Local PV 挂进去,训练只读本地盘;检查点周期性写回网络 PVC 做容灾。这样训练 IO 不依赖网络,节点故障也能从 PVC 恢复进度。
PVC 和本地盘的取舍看「可移植性」和「性能」谁优先。无状态服务和需要跨节点漂移的数据库用 PVC,享受调度自由;追求 IO 吞吐的训练、特征缓存用本地盘,但要接受「数据跟着节点走」,节点下线数据要有人管。容量规划要算清三件事:PVC 的总申请量别超过后端存储真实余量、本地盘按节点机型预留、EmptyDir 设 sizeLimit 防单 Pod 写爆磁盘。存储配额也要进 ResourceQuota,否则一个 Pod 把节点磁盘写满,同节点所有容器一起雪崩。
后端存储选型上,网络 PVC 若走 Ceph 这类分布式块存储,好处是三副本高可用、能跨节点漂移,代价是读写要经过网络栈,单卷 IOPS 有天花板,不适合做训练热数据,它更适合数据库主从、有状态服务的持久化。本地盘胜在吞吐和延迟,但牺牲了高可用,节点下线数据要有人管,要么业务层自己做副本,要么用 Local PV 加节点亲和把数据重要性分级。CSI 快照能力要提前验证,数据库的定时快照与恢复流程得演练,否则「能挂盘」和「能回滚」是两回事。备份别只留在同一机房,跨可用区或对象存储异地留一份,真遇硬件故障才有的退路。
把前面拆成可执行的清单。第一步给节点打标签:gpu-type=a100、node-pool=cpu、memory-tier=high、zone=华东,标签维度覆盖机型、池、内存档、可用区。第二步给特殊节点加污点:GPU 节点加 nvidia.com/gpu:NoSchedule,内存型加 dedicated=memory:NoSchedule,防止普通 Pod 误入。第三步让 Pod 用 nodeSelector 或 nodeAffinity 选池,用 tolerations 容忍对应污点。
第四步设命名空间级 ResourceQuota 和 LimitRange,把「不写 request」堵死在准入环节。第五步用 PriorityClass 区分生产与离线,让调度器在争抢时保高优。第六步上 Descheduler,定期把「调度时合理、运行时失衡」的 Pod 重新均衡,比如把 CPU 型节点上过于集中的 Burstable Pod 挪开。第七步对 GPU 节点装 NVIDIA device-plugin 并配置共享策略(MIG 或时间片),推理命名空间用 MIG 切片,离线命名空间用时间片。
从交付与机房支撑角度,不同底座的运维成本差很多。一万网络自营机柜加 BGP 多线、CN2 GIA 回国的线路,对跨节点 NCCL 集合通信的延迟更可控;其工程师一对一部署 CUDA、cuDNN、TensorRT、PyTorch、TensorFlow 的基线,能把 GPU 节点从到货到跑通框架的周期压到最短。这类交付能力对想把精力放在业务而非机房运维的平台团队,是选型时实打实的隐性成本考量,和单纯比月付价不是一回事。
坑一:GPU 节点不设污点。普通 Pod 没写 GPU 资源也会被调度上去占 CPU 和内存,导致真正的 GPU 任务排不上。判断法:看节点上 non-GPU Pod 数;规避法:GPU 节点一律 NoSchedule 污点加 taint,只放容忍的负载。
坑二:显存超卖无隔离。时间片共享时一个 Pod 吃满显存拖垮同卡全部推理。判断法:监控每张卡显存占用分布;规避法:在线推理走 MIG 硬隔离,时间片只给可重跑的离线任务,且设显存 limit。
坑三:本地盘 Pod 被调度到无盘节点。Local PV 绑了节点名,但 StorageClass 没约束就会 Pending。判断法:describe pvc 看绑定事件;规避法:Local PV 配合 nodeAffinity,且把本地盘节点单独标签化。
坑四:网络网段重叠导致跨区不通。判断法:上线前用静态路由表核对 CIDR;规避法:Pod、Service、物理网、VPN 四套网段提前规划不交叠,大规模按可用区分子网。
坑五:混部不隔离导致故障扩散。一个离线任务 OOM 把整节点带崩。判断法:看节点_not_ready 频率;规避法:离线任务限资源、限优先级、放独立池,核心服务 Guaranteed QoS。
按负载的资源瓶颈分,而不是按团队或项目分。最稳妥的四档是 CPU 型(无状态计算)、内存型(内存吞噬服务)、GPU 型(训练推理渲染)、大内存加 GPU 型(大模型训练)。每档独立标签、独立污点、独立配额。中小团队至少先把 CPU 型和 GPU 型切开,这是投入产出比最高的一步。切池后,调度器才第一次「知道」该把什么负载放什么机器,空转和抢占同时缓解。注意分池不是物理隔离的终点,还要配 nodeAffinity 和 ResourceQuota 才能兜住。
先装 NVIDIA device-plugin,把卡注册成 nvidia.com/gpu 扩展资源。生产推理优先用 MIG,把 A100 切成固定实例做硬隔离;离线开发和时间不敏感任务用时间片共享提升利用率;两者混跑的集群可上内核级虚拟化方案做显存限额。无论哪种,都要给 GPU 节点加 NoSchedule 污点,只让带对应 toleration 的 Pod 进来,并且用 PriorityClass 区分高优推理和低优离线,资源紧张时自动保高优。千万别让不写 GPU 资源的 Pod 进 GPU 节点。
普通集群 Calico 或 Cilium 都够用,Cilium 的 eBPF 可观测性更强。GPU 分布式训练要单独考虑节点间互联:给 GPU 节点配双网卡,一张走 CNI 业务网,一张走 RDMA 或 RoCE 高速网,用 Multus 注入 Pod,NCCL 绑高速网卡通信。容量规划上,Pod CIDR、Service CIDR 必须和机房物理网、VPN 错开;上千节点要按可用区切子网,控制广播域。容易被忽视的还有 Conntrack 表项和单节点 Pod 密度上限,规模一大就靠这个兜底。
看可移植性和性能谁优先。无状态服务、需跨节点漂移的数据库用 PVC 走 CSI,享受调度自由;训练数据集、特征缓存、检查点这类高 IO 负载用本地 NVMe 盘,避免每次 epoch 都拉网络。常见组合是数据集预热到本地盘、检查点周期写回 PVC 容灾。无论哪种都要进 ResourceQuota 限制总用量,EmptyDir 设 sizeLimit 防写爆节点磁盘。本地盘要配 nodeAffinity,否则 PVC 会 Pending。
追求极致性能、需要整卡整机独占、对虚拟化开销敏感的训练和大内存负载,选裸金属。A 类官网价里裸金属 E5-2698v4×2 月付 ¥3999 起、E5-2620 ¥999 起,比同等算力的云主机长期更划算。轻量、弹性、需要快速扩缩的 Web 服务用云主机或一万云 ¥25 起这类轻量规格更灵活。GPU 节点一般直接选 GPU 裸金属或 GPU 云主机,A100 40G ¥2800、T4 ¥900 月付含 100M BGP,具体机型未列明的按需询价。决策点是「持续高负载」还是「波峰波谷」,前者裸金属,后者云。
三件事:分池提利用率、共享调度降单卡成本、配额防浪费。GPU 用 MIG 或时间片把一张卡服务多个负载,避免整卡独占轻量推理;CPU 型节点用 Burstable 适度超售,但延迟敏感服务必须 Guaranteed。成本监控落到命名空间,用 ResourceQuota 锁总盘子,低优任务限优先级不抢资源。裸金属年付比月付省一到两个月费用,GPU 年付八折、季付九五折;海外裸金属有买一送一档。任何未列明型号地区组合一律以咨询价为准,不写死。
扩容分水平加节点和垂直升规格。加节点最安全:新节点打同样标签和污点,进对应节点池即可被调度。但要注意新 GPU 节点的驱动、CUDA 版本要和存量一致,否则 Pod 起不来。垂直升规格要先把节点 Cordon 排空再操作,避免 Pod 被强杀。扩容前先确认后端存储余量和网络网段还有空间,否则新节点上的 PVC 会 Pending、跨区通信会不通。建议用集群自动扩缩容(CA)按 Pod pending 自动加节点,但 CA 只管数量,规格和标签模板得你自己定义对。
最常见五个:GPU 节点不设污点被普通 Pod 占资源;时间片共享无显存隔离导致噪声邻居;本地盘 Pod 调度到无盘节点 Pending;网络网段重叠跨区不通;一个离线任务 OOM 把整节点带崩。规避的核心是「隔离加配额」:特殊节点污点化、负载按池分、命名空间锁配额、离线任务限资源限优先级。混部不是不能做,是得用调度约束把不同负载的故障域隔开,否则省下的机器钱会加倍赔给稳定性事故。
节点规划没有放之四海皆准的配方,但有一条架构底线站得住:先给负载画像,再按画像切节点池,GPU 必须单独成池并用共享调度提利用率。具体落点是——CPU 型节点承载无状态计算、可适度超售;内存型节点独立成池、严格不超售并做 NUMA 绑定;GPU 型节点加污点独占,推理走 MIG 硬隔离、离线走时间片共享;大内存加 GPU 型整机独占跑大模型。网络侧给 GPU 节点配双网卡走高速互联,存储侧本地盘扛训练 IO、PVC 做容灾与可移植。这样切完,GPU 不再被低优任务占满,CPU 节点也不再空转,成本曲线和稳定性同时回到可控区间。
数据来源:本文配置与价格参考一万网络官网相关页面(https://www.idc10000.net/),其中 GPU 节点 A100 40G 月付 ¥2800、T4 ¥900、RTX3090 ¥1750,裸金属 E5-2698v4×2 ¥3999 起、E5-2620 ¥999 起,一万云 ¥25 起,均为 A 类官网已挂出价,具体以签约时最新报价与合同为准;未列明机型与地区组合一律按需询价,以咨询为准。
Copyright © 2013-2020 idc10000.net. All Rights Reserved. 一万网络 科技有限公司 版权所有 深圳市科技有限公司 粤ICP备07026347号
本网站的域名注册业务代理北京新网数码信息技术有限公司的产品