为每个团队单独运行一套Kubernetes集群,往往会带来超出实际需求的隔离开销。虽然多个团队可以共用同一个集群,但随着团队数量增加,协调成本也会随之上升。常见问题包括:CRD版本冲突、RBAC权限重叠,以及无法将GPU资源按团队维度进行合理划分。发展到一定规模后,各团队往往会要求拥有独立集群,以找回自主权。
本文提供了一种既能保留团队自主权、又无需拆分硬件的方案。该方案由一个具备GPU资源池的控制平面集群、支持按团队配额的GPU共享机制,以及每个团队独立的Kubernetes控制平面(包含API服务器、控制器、数据存储、同步器和调度器)共同构成。整套方案基于两款开源工具实现:KAI Scheduler与vCluster。
按照本教程操作完成后,你将看到三个团队在各自的租户集群中运行真实的GPU Kubernetes Pod,同时共享同一块物理GPU,且每个团队只能看到自己的工作负载。
为了确保资源有限的用户也能复现完整流程,本教程使用的集群配置为一块NVIDIA L40S GPU,由三个团队共享其中的不同份额。这样的设置便于直观地观察和验证各环节的运行机制。相同的方案同样适用于拥有数百个GPU节点和数十个团队的大规模集群,只需按需扩展节点池、队列层级和租户集群数量即可。
KAI Scheduler介绍
KAI Scheduler是一款专为AI工作负载GPU资源调度而设计的高性能、可扩展拓扑感知型Kubernetes调度器,能够管理包含数千个节点的大规模GPU集群,并支持高吞吐量的工作负载调度。它支持GPU资源的动态分配,可与默认的kube-scheduler并行运行。任何设置了schedulerName: kai-scheduler的Pod都由KAI Scheduler负责处理,其余Pod仍走默认的kube-scheduler流程。
vCluster介绍
vCluster Kubernetes平台可在你的基础设施或裸金属上,快速创建完全隔离的租户集群。每个租户集群拥有独立的API服务器、自定义资源定义(CRD)和基于角色的访问控制(RBAC),体验上与独立的Kubernetes集群无异,同时共享底层节点和硬件。虚拟化控制平面对租户完全透明:无共享控制平面节点,无集群内代理Pod,各环境之间也没有横向访问路径。这使得vCluster非常适合GPU基础设施场景——团队可获得独立的集群体验,而无需拆分硬件。
本教程采用vCluster的共享节点模式,各团队共享GPU节点,同时各自拥有独立的隔离控制平面,适合内部可信团队使用。对于需要节点级、网络级和存储级隔离的不可信租户,同样的架构可扩展至vCluster私有节点模式。
场景示例
本示例涉及三个团队:NLP团队、视觉团队和推荐系统团队。NLP团队希望安装自己的CRD;视觉团队需要cluster-admin权限来调试调度问题;推荐系统团队使用不同版本的Kubeflow。没有人愿意共用一个kubectl上下文,并冒着误操作破坏他人环境的风险。
通过vCluster,每个团队拥有独立的控制平面、RBAC、命名空间和CRD,并可各自拥有cluster-admin访问权限。在底层,所有租户集群共享相同的节点和GPU。
环境准备
本示例运行在Nebius提供的NVIDIA Brev GPU实例上,配置如下:
一块NVIDIA L40S GPU,40个vCPU,160 GiB内存,256 GiB磁盘(48 GB显存)
Ubuntu 24.04.4 LTS
MicroK8s v1.36.2(Kubernetes由Brev预配置,内置MicroK8s GPU插件,已将NVIDIA GPU Operator预装至gpu-operator-resources命名空间)
KAI Scheduler v0.16.4
vCluster CLI 0.35.1
注意:对于不同的环境,集群创建和GPU Operator安装步骤在GKE/EKS/AKS/原生k8s/k3s上会有所不同。从第3步(KAI Scheduler)起,只要Kubernetes环境已启用Container Device Interface(CDI)并运行NVIDIA GPU Operator,操作步骤完全一致。
第一步:配置MicroK8s基础环境
安装独立的kubectl和helm,以避免每条命令都需要加microk8s前缀,并配置kubeconfig,同时锁定MicroK8s版本,防止演示期间snap自动升级控制平面。
sudo snap refresh --hold microk8s
sudo snap install kubectl --classic --channel=1.35/stable
sudo snap install helm --classic
mkdir -p ~/.kube
sudo microk8s config > ~/.kube/config
sudo chown $USER:$USER ~/.kube/config
chmod 600 ~/.kube/config
启用所需的MicroK8s插件:
microk8s enable dns
microk8s enable hostpath-storage # vCluster需要PVC支持
验证集群状态:
kubectl get nodes -o wide
kubectl get storageclass
第二步:添加NVIDIA Helm仓库
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
helm repo update
第三步:确认GPU Operator运行状态
kubectl get pods -n gpu-operator-resources
如果使用较旧版本的GPU Operator,可通过以下命令原地升级至26.3.x:
helm upgrade gpu-operator nvidia/gpu-operator \
-n gpu-operator-resources \
--version v26.3.3 \
--reset-then-reuse-values
如需全新安装NVIDIA GPU Operator,可使用以下命令:
helm install gpu-operator nvidia/gpu-operator \
-n gpu-operator-resources --create-namespace \
--version v26.3.3 \
--set driver.enabled=false \
...
第四步:安装KAI Scheduler
helm upgrade -i kai-scheduler \
oci://ghcr.io/kai-scheduler/kai-scheduler/kai-scheduler \
-n kai-scheduler --create-namespace \
--version v0.16.4 \
--set "global.gpuSharing=true"
验证安装结果:
kubectl get pods -n kai-scheduler
第五步:创建队列层级
KAI Scheduler使用Queue CRD来构建组织→团队的层级结构。本步骤创建一个父队列(ml-org,总预算为1块GPU)和三个子队列。每个子队列保底分配0.33块GPU,当其他团队空闲时可使用完整的1块GPU。
将以下内容保存为create-queues.yaml:
apiVersion: scheduling.run.ai/v2
kind: Queue
metadata:
name: ml-org
spec:
resources:
gpu: { quota: 1, limit: -1, overQuotaWeight: 1 }
---
apiVersion: scheduling.run.ai/v2
kind: Queue
metadata:
name: team-nlp
spec:
parentQueue: ml-org
priority: 100
resources:
gpu: { quota: 0.33, limit: 1, overQuotaWeight: 1 }
---
apiVersion: scheduling.run.ai/v2
kind: Queue
metadata:
name: team-vision
spec:
parentQueue: ml-org
priority: 100
resources:
gpu: { quota: 0.33, limit: 1, overQuotaWeight: 1 }
---
apiVersion: scheduling.run.ai/v2
kind: Queue
metadata:
name: team-recommender
spec:
parentQueue: ml-org
priority: 100
resources:
gpu: { quota: 0.33, limit: 1, overQuotaWeight: 1 }
其中,quota为保底最小值,limit为最大允许值,overQuotaWeight控制超配资源的分配比例。
应用配置并查看结果:
kubectl apply -f create-queues.yaml
kubectl get queues
注意:default-parent-queue和default-queue是KAI Scheduler首次安装时自动创建的,作为未指定队列的Pod的默认回退队列。
第六步:创建vCluster租户集群
安装vCluster CLI:
curl -L -o vcluster "https://github.com/loft-sh/vcluster/releases/latest/download/vcluster-linux-amd64"
sudo install -m 755 vcluster /usr/local/bin/vcluster
rm vcluster
vcluster --version
定义vCluster配置文件,关键设置是setOwner: false。KAI Scheduler的pod-grouper会沿着所有权链(Job→Pod,Deployment→ReplicaSet→Pod)自动对工作负载进行分组。禁用vCluster的owner重写功能后,KAI Scheduler即可看到真实的层级结构。
experimental:
syncSettings:
setOwner: false
sync:
fromHost:
nodes:
enabled: true
selector:
all: true
EOF
为每个团队分别创建vCluster:
vcluster create team-nlp --values vcluster.yaml --connect=false
vcluster create team-vision --values vcluster.yaml --connect=false
vcluster create team-recommender --values vcluster.yaml --connect=false
验证三个vCluster均已正常运行:
vcluster list
每个团队都可以看到真实节点,包括GPU节点:
vcluster connect team-nlp -- kubectl get nodes
第七步:部署GPU工作负载
各团队从各自的vCluster中提交GPU工作负载。Pod规格简洁,只需三个关键字段告知KAI Scheduler如何处理:
apiVersion: v1
kind: Pod
metadata:
name: nlp-sentiment-model
labels:
kai.scheduler/queue: team-nlp # 所属团队
annotations:
gpu-fraction: "0.33" # GPU使用份额
spec:
schedulerName: kai-scheduler # 使用KAI而非默认调度器
tolerations:
- key: nvidia.com/gpu
operator: Exists
effect: NoSchedule
containers:
- name: nlp-inference
image: nvidia/cuda:12.4.0-base-ubuntu22.04
command: ["bash", "-c", "nvidia-smi; sleep infinity"]
nodeSelector:
nvidia.com/gpu.present: "true"
EOF
对每个团队重复上述操作,修改对应的队列名称即可。
验证结果可以看到三个Pod分属三个不同的vcluster-team-*命名空间,但全部运行在同一个物理节点上。
从各自的vCluster内部查询,每个团队只能看到自己的Pod:
vcluster connect team-nlp -- kubectl get pods -o wide
vcluster connect team-vision -- kubectl get pods -o wide
vcluster connect team-recommender -- kubectl get pods -o wide
最后,通过队列状态确认资源分配情况:
kubectl describe queue team-nlp | grep -A4 Status
kubectl describe queue team-vision | grep -A4 Status
kubectl describe queue team-recommender | grep -A4 Status
三个团队均可看到相同的分配结果:
Status:
Allocated:
nvidia.com/gpu: 330m
Requested:
nvidia.com/gpu: 330m
关于GPU隔离的说明
需要注意的是,KAI Scheduler负责调度决策——决定哪些Pod使用哪块GPU以及使用比例,但在GPU共享模式下,它并不在硬件层面强制执行GPU内存隔离。应用程序需要自行遵守内存配额(例如在vLLM中设置--gpu-memory-utilization参数)。
在底层实现上,GPU在各Pod的CUDA上下文之间按内核边界进行时间片切换。如需在支持的硬件上实现硬件级内存隔离,可使用NVIDIA多实例GPU(MIG)提供硬件级分区,KAI Scheduler同样支持对MIG资源进行调度。
总结
KAI Scheduler通过GPU共享与DRA驱动支持、带保底配额和超配能力的分层队列、gang调度以及拓扑感知等能力,公平地决定各团队获得的GPU时间片及其调度分组方式。在AI工作负载调度问题得到解决的基础上,vCluster进一步赋予每个团队独立的Kubernetes控制平面,而无需承担独立基础设施的成本。
KAI Scheduler与vCluster的组合,在单块GPU上为三个团队提供了媲美独立集群的使用体验,同时实现了零资源浪费。答案并非总是"更多GPU",而是"更好地利用现有基础设施"。
如需了解更多,可在GitHub上查看KAI Scheduler、vCluster和NVIDIA GPU Operator的相关项目,也可在2026年KubeCon北美峰会(11月9日至12日)上深入了解KAI Scheduler与vCluster的集成方案。
Q&A
Q1:KAI Scheduler是什么?它在GPU共享中起什么作用?
A:KAI Scheduler是一款专为AI工作负载设计的拓扑感知型Kubernetes调度器,核心功能是优化GPU资源分配。它支持分层队列管理,可为每个团队设置保底GPU配额和超配上限,并通过gang调度和时间片机制实现多团队共享同一块物理GPU,同时保证调度公平性。它可与默认kube-scheduler并行运行,只处理指定了schedulerName: kai-scheduler的Pod。
Q2:vCluster如何实现多团队的Kubernetes隔离?
A:vCluster为每个团队创建独立的虚拟控制平面,包含独立的API服务器、CRD、RBAC和命名空间,体验上与独立集群完全一致。各团队可拥有cluster-admin权限,互不干扰。底层所有租户集群共享同一组物理节点和GPU,虚拟控制平面对租户透明,不存在共享控制平面节点或跨租户横向访问路径。
Q3:KAI Scheduler能保证GPU内存隔离吗?
A:KAI Scheduler在GPU共享模式下只负责调度决策,不在硬件层面强制执行GPU内存隔离。各应用需要自行遵守内存限制,例如在vLLM中通过--gpu-memory-utilization参数控制用量。如需硬件级内存隔离,可使用NVIDIA多实例GPU(MIG)功能,KAI Scheduler同样支持对MIG资源进行调度管理。
上一篇:遇最强风雨!陆河县城为何无内涝?