昨天我把 Driver、Container Toolkit 與 Device Plugin 的責任分開,並定義了 nvidia.com/gpu 出現前後的實機驗證步驟。但即使 Node 上已經看得到這個 resource,Scheduler 掌握的資訊還是比我原本想得更少。
Scheduler 不知道「這張卡還剩多少 VRAM」,也不知道「目前 GPU utilization 高不高」。對傳統 Device Plugin 公告的整數 extended resource,主要在算這件事:
這個 Node 可分配數量 - 已被非終止 Pod 申請的數量
是否還大於或等於新 Pod 的 request?
Node status 會同時出現 capacity 與 allocatable理解是:
Scheduler 在評估 Pod 是否放得進 Node 時,使用的是 allocatable。因此 Day 03 只查 capacity 不夠,我會把兩個值一起列出:
kubectl get nodes \
-o custom-columns='NODE:.metadata.name,CAPACITY:.status.capacity.nvidia\.com/gpu,ALLOCATABLE:.status.allocatable.nvidia\.com/gpu'
公開結果時只保留去識別後的數值,Node 名稱以中性代號取代。
一個 Pod 寫了:
resources:
limits:
nvidia.com/gpu: 1
對 GPU 這類 extended resource,可以只寫 limit,Kubernetes 會把相同數值當成 request;如果 request 和 limit 都寫,兩者必須相等,不允許像 CPU 那樣用小數超額申請整張 GPU。
這也帶出一個很容易誤解的現象:當 Pod 申請了一張 GPU,Node status 裡的 allocatable 不會因此從 1 改成 0。allocatable 是 Node 能供應的上限,「已分配」要從現有 Pod requests 另外加總。
所以我不會用這個式子:
可用 GPU = allocatable 欄位目前顯示的數字
而會用:
可排程 GPU = allocatable - 非終止 Pod 的 GPU requests 加總
k8s/day04-gpu-saturation.yaml 建立一個有兩個 replicas 的 Deployment,每個 Pod 都申請 nvidia.com/gpu: 1,並且只執行有界限的 sleep 600。
這個實驗有很嚴格的前提:測試叢集必須只有一個可分配 GPU,且當下沒有其他 GPU workload。在這個前提下,我預期:
Insufficient nvidia.com/gpu。「預期」不是「已觀察」。目前還沒有可授權操作的 GPU 叢集,所以我不會把這五點寫成實測結果。
一般驗收總希望 Pod 全部 Running,但這個實驗不一樣。如果只有一張可分配 GPU,兩個申請都成功排程,我反而要停下來查清楚:
今天要驗證的正是整數資源不超額分配。所以第二個 Pod 因資源不足而 Pending,是符合假設的證據,不是要用 privileged Pod 或手動綁定 Node 「修好」的錯誤。
就算今天的排程結果完全符合預期,我還是不能從中推論:
Scheduler 完成的是 placement 與 accounting,不是 serving quality 驗證。把這兩層拆開,後面才能正確討論 VRAM、sharing 與 workload interference。
我把 Scheduler 看到的 GPU 現象收斂成一句話:
看到的是 Pod 申請的整數 extended resource 和 Node allocatable 之間的帳,不是 GPU 當下的記憶體與效能狀態。
下一篇會沿著這個限制往下追:既然預設 extended resource 是「一張、兩張」地申請,為什麼不能直接寫成 1 GB、2 GB VRAM?
下一篇:Day 05|GPU Request 的第一個限制:一張卡不是 1GB、2GB 這樣分
本篇的 Kubernetes 實機觀察尚未執行,文中已將官方資源語意、實驗假設與未驗證結果分開。