GPUStack
Docker 遷移
NFS 共享快取
GPU 叢集維運筆記
將 GPUStack 從 v0.7.1 遷移至 v2.1.1
在不破壞共享 NFS 模型快取設定的前提下完成升級 #
本文記錄了將以舊版安裝腳本方式運作的 GPUStack 環境,遷移至以 Docker 為基礎的 v2 系列的過程。
在維持管理節點兼作 NFS 的架構下,逐步遷移了 2 台 GPU 工作節點,
並整理了模型快取共享、Worker 重新連線,以及部署時後端/CUDA 一致性驗證等重點。
Ubuntu / Docker / NVIDIA GPU / NFS
對象:GPUStack v0.7.1 → v2.1.1
本文前提 #
在正式環境中,採用 1 台管理節點與 2 台 GPU Worker 的架構,模型快取
統一存放於 /models 並透過 NFS 共享。本文中,實際主機名稱、
私有 IP 及 Worker 權杖等敏感資訊皆已省略,並抽象化至適合公開揭露的程度。
最初的架構很單純:「管理節點整合了 GPUStack Server 與 NFS,GPU 工作節點
則參照共用的 /models」。這種做法的優點是模型檔案只需下載一次,即可在新增 Worker 時降低磁碟用量與
網路傳輸量。即使遷移至 v2 系列,我們也決定保留這個設計理念,
僅針對目前的做法重新調整維運方式。
升級前後的做法 #
升級至 v2 系列前需了解的重點 #
1. 遷移前提為 Docker #
以舊版安裝腳本或 pip 方式部署的環境,若要遷移至 v2 系列,
官方遷移路徑要求採用以 Docker 為基礎的架構。
2. 管理用資料庫也會變更 #
從 v0.7 系列以前預設使用的 SQLite,到了 v2.0 以後會遷移至內建的 PostgreSQL。
換句話說,這並非單純替換執行檔,而是必須意識到資料遷移的維運工作。
3. 釐清內建 Worker 的定位 #
在舊版架構中,管理節點本身也會以 Worker 的形式出現。此次遷移中,
我們決定改採管理節點僅作為 Server 的方針,
讓 Workers 清單中只保留 GPU Worker。
事先完成的正確之舉 #
在動手處理 Server 之前,我們先備份了舊版的資料目錄。
在 v2 系列中,新元件會讀取舊版的資料目錄,因此權限調整與備份非常重要。
實際執行的升級程序 #
確認舊版資料目錄並先行備份 #
我們先確認舊版的 systemd 定義,釐清 Server 與 Worker 各自使用哪個資料目錄,
接著依序執行服務停止 → tar 備份 → 權限調整。
sudo systemctl cat gpustack | sed -n '/ExecStart/p'
sudo systemctl stop gpustack
sudo systemctl disable gpustack
sudo tar -C / -cpf /root/backup/gpustack-server.tar var/lib/gpustack先將管理節點遷移至 v2.1.1 #
由於假設管理節點不會使用 GPU,因此在 Server 啟動指令中省略了 --runtime nvidia。
若保留此參數,unknown or invalid runtime name: nvidia 會導致啟動失敗,
發生於 Docker 中尚未註冊 NVIDIA runtime 的伺服器上。
sudo docker run -d --name gpustack \
--restart=unless-stopped \
--privileged \
--network=host \
--env GPUSTACK_DATA_MIGRATION=true \
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume /var/lib/gpustack:/var/lib/gpustack \
--volume /models:/models \
gpustack/gpustack:v2.1.1 \
--disable-worker \
--cache-dir /models我們刻意指定 --disable-worker,是為了將管理節點
與舊版內建 Worker 的角色徹底分離。這次遷移的主軸就是「管理節點專注於管理」。
逐步將 GPU Worker 切換為以 Docker 為基礎的 Worker #
各 Worker 在繼承既有資料目錄的同時,重新以 Docker 為基礎的 Worker 身分連線。
為了對齊共享快取路徑,容器同樣掛載了 /models:/models,
並在啟動參數中加上 --cache-dir /models。
sudo docker run -d --name gpustack-worker \
--restart=unless-stopped \
--privileged \
--network=host \
--volume /var/lib/gpustack-data:/var/lib/gpustack \
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume /models:/models \
--runtime nvidia \
gpustack/gpustack:v2.1.1 \
--server-url http://<SERVER_IP> \
--token <JOIN_TOKEN> \
--worker-name <WORKER_NAME> \
--worker-ip <WORKER_IP> \
--cache-dir /models重點在於不要把 GUI 上的「Add Worker」單純當作「登錄作業」。
實際上,GUI 只是取得權杖與執行指令的入口;
唯有在 Worker 節點上實際執行該指令後,狀態才會變為 Ready。
驗證 NVIDIA Container Toolkit #
GPU Worker 需要 --runtime nvidia。若 Docker 不認得該 runtime,
可能是 NVIDIA Container Toolkit 的設定尚未反映。請依官方程序,
使用 nvidia-ctk 設定 Docker runtime 並重新啟動 Docker。
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker將 Workers 清單整理為「僅保留實際執行推論的節點」 #
在舊版環境中,管理節點仍以 Worker 身分留在清單中,並顯示為 Not Ready,這一直是造成困惑的原因。
在 2 台 GPU Worker 轉為 Ready 之後,我們便針對管理節點上殘留的過時 Worker 進行清理。
這樣一來,即使是維運團隊也能一目了然地掌握各節點的角色。
這次遇到的痛點 #
管理節點:unknown or invalid runtime name: nvidia #
即使 Server 節點沒有 GPU,或尚未安裝 NVIDIA runtime,我們一開始仍以 --runtime nvidia 啟動。
若管理節點要專職作為 Server,
乾脆移除這個參數會比較妥當。
Worker 已是 Ready,但模型仍為 Pending #
Worker 狀態與模型能否部署是兩個不同的問題。特別是在剛完成 v2 遷移之後,
可能因為沿用舊版的後端版本或 CUDA 世代不一致而出現 Pending。
「Worker 變成 Ready 就結束了」並非終點;實際的遷移還包含部署 1 個模型以進行驗證。
部署階段學到的經驗 #
這次連 Worker 端的作業系統也一併更新,導致 CUDA 相關套件一致對齊至 12.9 世代。
在這種狀態下,我們需要重新檢視 GPUStack 端內建的後端版本與部署設定。
遷移完成後,建議一併檢查 Inference Backends 與 部署所指定的後端/版本
兩者。
檢查清單 #
- 事先了解舊版環境的資料目錄與 systemd 定義
- 在開始遷移前先備份 Server
- 先啟動管理節點,最後才處理 GPU Worker
- 若使用 NFS 共享快取,請在主機/容器/Worker 之間統一
/models - 若為 Server 專用節點,請停用內建 Worker 以簡化 Workers 清單
- Worker 連線完成後,務必部署 1 個模型以驗證後端/CUDA 的一致性
總結 #
這次升級中,帶來最大差異的並非版本本身的提升,
而是「釐清節點角色,讓畫面上顯示的內容更容易理解」。
透過明確的角色分工——管理節點負責 Server + NFS,推論僅在 GPU Worker 上進行——
後續的維運判斷也變得輕鬆許多。
若您同樣正在使用 v0.7 系列以前的版本,並希望在維持共享快取架構的前提下升級至 v2 系列,
我們強烈建議掌握以下 3 個重點:先 Server、後 Worker、部署全面驗證。
不要止步於「已經啟動」;實際確認模型能夠啟動,才能讓遷移品質更加穩定。
使用的官方參考資料 #
- GPUStack Migration Guide
- GPUStack CLI Reference: gpustack start
- GPUStack Release Notes
- NVIDIA Container Toolkit Install Guide
本文為根據特定內部環境整理的實務筆記。實際套用於營運環境時,
請務必依最新官方資訊,重新確認所使用的 GPU、驅動程式、CUDA 世代與後端版本的組合。