[應用] GPU Operator -- (Driver, NVIDIA Container Runtime, NVIDIA Device Plugin, node labels) === ###### tags: `K8s / app` ###### tags: `Kubernetes`, `k8s`, `app`, `GPU Operator`, `NVIDIA GPU Feature Discovery`, `GFD`, `Driver`, `NVIDIA container runtime`, `NVIDIA device plugin`, `node labels` <br> [TOC] <br> ## [總覽] 安裝 NVIDIA GPU Operator - Install Helm ```bash curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 \ && chmod 700 get_helm.sh \ && ./get_helm.sh # add the NVIDIA Helm repository helm repo add nvidia https://helm.ngc.nvidia.com/nvidia \ && helm repo update ``` - Install the GPU Operator ``` helm install --wait --generate-name \ -n gpu-operator --create-namespace \ nvidia/gpu-operator ``` <br> ## [詳解] 安裝 NVIDIA GPU Operator(依系統狀況動態決定參數) NVIDIA GPU Operator 可協助在 Kubernetes 節點上自動部署以下 GPU 相關元件: | 元件 | 說明 | |-----------------------------|--------------------------------------------| | **Driver** | 安裝 NVIDIA 驅動(選擇性) | | **Container Toolkit** | 安裝 `nvidia-container-toolkit` 並設定 runtime | | **Device Plugin** | 提供 GPU 資訊給 kubelet 進行排程與掛載 | | **DCGM Exporter** | 匯出 GPU 健康狀況與使用率 metrics(Prometheus) | | **GPU Feature Discovery** | 偵測節點上的 GPU 功能與型號 | - ### [總覽] 使用 helm 安裝 gpu-operator,參數設定可依據「**系統狀態**」決定 ```bash= helm repo add nvidia https://nvidia.github.io/gpu-operator helm repo update kubectl create namespace gpu-operator helm install --wait --generate-name \ nvidia/gpu-operator \ --namespace gpu-operator \ --set driver.enabled=false \ --set toolkit.enabled=true ``` | 狀況 | 參數設定 | 說明 | |----------------------------------|--------|-----| | ❌ GPU 驅動未裝 (`nvidia-smi`) | `--set driver.enabled=true` | 由 gpu-operator 幫忙裝 | | ✅ GPU 驅動已裝 (`nvidia-smi`) | `--set driver.enabled=false` | 不用幫忙 | | ❌ containerd 尚未設定支援 nvidia | `--set toolkit.enabled=true` | 由 gpu-operator 幫忙裝 | | ✅ containerd 已經設定支援 nvidia | `--set toolkit.enabled=false` | 不用幫忙 | - ### 📌 7.1 檢查當前系統狀態 > 情境:**(A)** K8s重建, **(B)** 全新安裝 > 使用下表逐項檢查主機狀態: | 項目 | 指令範例 | 狀態評估 | |------------------------------|----------------------------------------|-----------------------| | ✅ GPU 驅動是否已安裝 | `nvidia-smi` | 有輸出表示已安裝 | | ✅ containerd 是否已安裝 | `containerd --version` | 有版本輸出表示已安裝 | | ✅ containerd 是否支援 nvidia | `cat /etc/containerd/config.toml \| grep nvidia` | 有 nvidia 條目表示已設定 | --- - ### 📌 7.2 根據狀態選擇 Helm 安裝參數 請根據你的實際狀況選擇安裝方式: - #### 🔧 **情境 A:已手動安裝 GPU 驅動,但尚未設定 container runtime** > 適用於:K8s 重建 | 狀況 | 是否符合 | |----------------------------------|----------| | ✅ GPU 驅動已裝 (`nvidia-smi`) | 是 | | ❌ containerd 尚未設定支援 nvidia | 是 | 👉 推薦設定: ``` --set driver.enabled=false \ --set toolkit.enabled=true ``` - 🟢 GPU 驅動由你自行管理,不讓 Operator 干預 - 🟢 讓 Operator 幫你設定 containerd 的 GPU runtime(自動加上 `nvidia` runtime 到 config.toml) --- - #### 🔧 **情境 B:都還沒裝,完全交由 GPU Operator 處理** > 適用於:全新安裝 | 狀況 | 是否符合 | |------------------|----------| | ❌ GPU 驅動未裝 | 是 | | ❌ containerd 尚未設定 | 是 | 👉 推薦設定: ``` --set driver.enabled=true \ --set toolkit.enabled=true ``` - 🟢 由 GPU Operator 全權處理驅動與 runtime 安裝 - 📌 需注意需搭配支援的 OS(如 RHEL/CentOS/Ubuntu),否則驅動安裝可能失敗 --- - #### 🔧 **情境 C:你所有東西都已手動設定好** > 適用於:有客製化需求的進階管理者 | 狀況 | 是否符合 | |----------------------------------|----------| | ✅ GPU 驅動 (`nvidia-smi`) 已裝 | 是 | | ✅ containerd 已設定支援 nvidia | 是 | 👉 推薦設定: ``` --set driver.enabled=false \ --set toolkit.enabled=false ``` - 🟢 完全不讓 GPU Operator 修改系統 - 適用於企業/空氣隔離環境,已手動管理所有 runtime - 手動註冊 nvidia runtime - 向 containerd 註冊 nvidia runtime ```bash # nvidia-ctk: Tools to configure the NVIDIA Container Toolkit sudo nvidia-ctk runtime configure --runtime=containerd ``` - 驗證方式: ``` cat /etc/containerd/config.toml | grep nvidia ``` ![](https://hackmd.io/_uploads/r1Knnammge.png) --- - ### 📦 7.3 安裝 GPU Operator(以情境 A 為例)(K8s重建) ```bash= helm repo add nvidia https://nvidia.github.io/gpu-operator helm repo update kubectl create namespace gpu-operator helm install --wait --generate-name \ nvidia/gpu-operator \ --namespace gpu-operator \ --set driver.enabled=false \ --set toolkit.enabled=true ``` --- - ### ✅ 7.4 驗證 GPU Operator 運作 ``` kubectl get pods -n gpu-operator ``` 應看到以下元件皆為 `Running`: | 元件 Pod 名稱 | 說明 | |-----------------------------|-------------------------| | `nvidia-device-plugin-*` | 掛載 GPU 給 Pod 使用 | | `nvidia-container-toolkit-*` | 設定 containerd runtime | | `gpu-feature-discovery-*` | 掃描 GPU 特性 | | `nvidia-dcgm-exporter-*` | 匯出 metrics(Prometheus)| ![image](https://hackmd.io/_uploads/B1A86TXQel.png) --- - ### 🔬 7.5 測試 GPU 是否可用 - #### 測試能否要到指定的 GPU 張數 ```yaml= # gpu-test.yaml apiVersion: v1 kind: Pod metadata: name: gpu-test spec: restartPolicy: OnFailure containers: - name: cuda-container image: nvidia/cuda:12.2.0-base-ubuntu22.04 resources: limits: nvidia.com/gpu: 1 command: ["nvidia-smi"] ``` ``` kubectl apply -f gpu-test.yaml kubectl logs gpu-test ``` - #### 測試能否能跑 cuda 程式 (執行向量相加) ```yaml= # cuda-sample-vectoradd.yaml apiVersion: v1 kind: Pod metadata: name: cuda-sample-vectoradd spec: restartPolicy: Never containers: - name: cuda-container image: nvcr.io/nvidia/k8s/cuda-sample:vectoradd-cuda11.7.1-ubuntu20.04 resources: limits: nvidia.com/gpu: 1 # requesting 1 GPU ``` --- - ### ✅ 7.6 小結 | 項目 | 狀態 | |---------------------------|------| | GPU 驅動 (`nvidia-smi`) | ✅ 已安裝 | | Containerd + systemd | ✅ 已安裝 | | containerd 設定 nvidia runtime | ✅ 已由 Operator 自動完成 | | GPU Operator 安裝 | ✅ 成功部署 | | 測試 Pod 使用 GPU | ✅ 成功執行 | <br> --- <br> ## 手動安裝 `nvidia-container-runtime` ### 安裝 NVIDIA Container Toolkit 方式 ```bash # 加入套件庫金鑰與來源 distribution=$(. /etc/os-release;echo $ID$VERSION_ID) # 例如 ubuntu20.04 curl -s -L https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | \ sed 's#https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#' | \ sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list # 安裝 runtime sudo apt update sudo apt install -y nvidia-container-toolkit ``` 接著修改 containerd 設定來啟用 NVIDIA runtime: ``` sudo nvidia-ctk runtime configure --runtime=containerd ``` 重啟 containerd: ``` sudo systemctl restart containerd ``` **驗證方式**:可執行底下 image 測試 container 是否能成功使用 GPU。 ``` $ sudo ctr image pull docker.io/nvidia/cuda:12.2.0-base-ubuntu22.04 $ sudo ctr run --rm --gpus 0 docker.io/nvidia/cuda:12.2.0-base-ubuntu22.04 test-nvidia nvidia-smi Mon Jun 9 03:22:08 2025 +---------------------------------------------------------------------------------------+ | NVIDIA-SMI 535.54.03 Driver Version: 535.54.03 CUDA Version: 12.2 | |-----------------------------------------+----------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+======================+======================| | 0 NVIDIA GeForce GTX 1080 Ti On | 00000000:02:00.0 Off | N/A | | 27% 33C P8 9W / 250W | 6MiB / 11264MiB | 0% Default | | | | N/A | +-----------------------------------------+----------------------+----------------------+ +---------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=======================================================================================| +---------------------------------------------------------------------------------------+ ``` - containerd 使用 `ctr` 指令時,不會像 Docker CLI 那樣隱式地將 `nvidia/cuda` 解析為 `docker.io/nvidia/cuda`,因此你**必須自己加上完整路徑** `docker.io/`。 <br> --- <br> ## NVIDIA GPU feature discovery > https://github.com/NVIDIA/k8s-device-plugin/blob/main/docs/gpu-feature-discovery/README.md - ### [Node Feature Discovery (NFD)](https://github.com/NVIDIA/k8s-device-plugin/blob/main/docs/gpu-feature-discovery/README.md#node-feature-discovery-nfd) ``` kubectl apply -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.16.2/deployments/static/nfd.yaml ``` - ### k8s 正常狀態 ``` $ kubectl get all -n node-feature-discovery NAME READY STATUS RESTARTS AGE pod/nfd-26fbg 2/2 Running 0 16m NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE daemonset.apps/nfd 1 1 1 1 1 <none> 16m ``` - ### node 資訊,新增差異如下: ```yaml apiVersion: v1 kind: Node metadata: annotations: nfd.node.kubernetes.io/feature-labels: cpu-cpuid.ADX,cpu-cpuid.AESNI,cpu-cpuid.AVX,cpu-cpuid.AVX2,cpu-cpuid.FMA3,cpu-cpuid.HLE,cpu-cpuid.IBPB,cpu-cpuid.RTM,cpu-cpuid.STIBP,cpu-cpuid.VMX,cpu-hardware_multithreading,cpu-pstate.turbo,cpu-rdt.RDTCMT,cpu-rdt.RDTL3CA,cpu-rdt.RDTMBM,cpu-rdt.RDTMON,iommu-enabled,kernel-config.NO_HZ,kernel-config.NO_HZ_IDLE,kernel-version.full,kernel-version.major,kernel-version.minor,kernel-version.revision,memory-numa,network-sriov.capable,pci-10de.present,pci-1a03.present,system-os_release.ID,system-os_release.VERSION_ID,system-os_release.VERSION_ID.major,system-os_release.VERSION_ID.minor nfd.node.kubernetes.io/master.version: v0.6.0 nfd.node.kubernetes.io/worker.version: v0.6.0 node.alpha.kubernetes.io/ttl: "0" labels: feature.node.kubernetes.io/cpu-cpuid.ADX: "true" feature.node.kubernetes.io/cpu-cpuid.AESNI: "true" feature.node.kubernetes.io/cpu-cpuid.AVX: "true" feature.node.kubernetes.io/cpu-cpuid.AVX2: "true" feature.node.kubernetes.io/cpu-cpuid.FMA3: "true" feature.node.kubernetes.io/cpu-cpuid.HLE: "true" feature.node.kubernetes.io/cpu-cpuid.IBPB: "true" feature.node.kubernetes.io/cpu-cpuid.RTM: "true" feature.node.kubernetes.io/cpu-cpuid.STIBP: "true" feature.node.kubernetes.io/cpu-cpuid.VMX: "true" feature.node.kubernetes.io/cpu-hardware_multithreading: "true" feature.node.kubernetes.io/cpu-pstate.turbo: "true" feature.node.kubernetes.io/cpu-rdt.RDTCMT: "true" feature.node.kubernetes.io/cpu-rdt.RDTL3CA: "true" feature.node.kubernetes.io/cpu-rdt.RDTMBM: "true" feature.node.kubernetes.io/cpu-rdt.RDTMON: "true" feature.node.kubernetes.io/iommu-enabled: "true" feature.node.kubernetes.io/kernel-config.NO_HZ: "true" feature.node.kubernetes.io/kernel-config.NO_HZ_IDLE: "true" feature.node.kubernetes.io/kernel-version.full: 5.4.0-137-generic feature.node.kubernetes.io/kernel-version.major: "5" feature.node.kubernetes.io/kernel-version.minor: "4" feature.node.kubernetes.io/kernel-version.revision: "0" feature.node.kubernetes.io/memory-numa: "true" feature.node.kubernetes.io/network-sriov.capable: "true" feature.node.kubernetes.io/pci-10de.present: "true" feature.node.kubernetes.io/pci-1a03.present: "true" feature.node.kubernetes.io/system-os_release.ID: ubuntu feature.node.kubernetes.io/system-os_release.VERSION_ID: "20.04" feature.node.kubernetes.io/system-os_release.VERSION_ID.major: "20" feature.node.kubernetes.io/system-os_release.VERSION_ID.minor: "04" status: images: - names: - quay.io/kubernetes_incubator/node-feature-discovery@sha256:a1e72dbc35a16cbdcf0007fc4fb207bce723ff67c61853d2d8d8051558ce6de7 - quay.io/kubernetes_incubator/node-feature-discovery:v0.6.0 sizeBytes: 35343350 ``` - ### [Deploy NVIDIA GPU Feature Discovery (GFD)](https://github.com/NVIDIA/k8s-device-plugin/blob/main/docs/gpu-feature-discovery/README.md#deploy-nvidia-gpu-feature-discovery-gfd) > for staging - ### 安裝方式 ``` kubectl apply -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.16.2/deployments/static/gpu-feature-discovery-daemonset.yaml ``` - [gpu-feature-discovery-daemonset.yaml](https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.16.2/deployments/static/gpu-feature-discovery-daemonset.yaml) - ### k8s 正常狀態 ``` NAME READY STATUS RESTARTS AGE pod/gpu-feature-discovery-qv6pn 1/1 Running 0 2m13s NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE daemonset.apps/gpu-feature-discovery 1 1 1 1 1 <none> 2m13s ``` - ### node 資訊,新增差異如下: ```yaml apiVersion: v1 kind: Node metadata: labels: nvidia.com/cuda.driver-version.full: 535.54.03 nvidia.com/cuda.driver-version.major: "535" nvidia.com/cuda.driver-version.minor: "54" nvidia.com/cuda.driver-version.revision: "03" nvidia.com/cuda.driver.major: "535" nvidia.com/cuda.driver.minor: "54" nvidia.com/cuda.driver.rev: "03" nvidia.com/cuda.runtime-version.full: "12.2" nvidia.com/cuda.runtime-version.major: "12" nvidia.com/cuda.runtime-version.minor: "2" nvidia.com/cuda.runtime.major: "12" nvidia.com/cuda.runtime.minor: "2" nvidia.com/gfd.timestamp: "1748336208" nvidia.com/gpu.compute.major: "6" nvidia.com/gpu.compute.minor: "1" nvidia.com/gpu.count: "4" nvidia.com/gpu.family: pascal nvidia.com/gpu.machine: ESC4000-G3-Series nvidia.com/gpu.memory: "11264" nvidia.com/gpu.mode: graphics nvidia.com/gpu.product: NVIDIA-GeForce-GTX-1080-Ti nvidia.com/gpu.replicas: "1" nvidia.com/gpu.sharing-strategy: none nvidia.com/mig.capable: "false" nvidia.com/mps.capable: "false" nvidia.com/vgpu.present: "false" status: images: - names: - nvcr.io/nvidia/k8s-device-plugin@sha256:ed39e22c8b71343fb996737741a99da88ce6c75dd83b5c520e0b3d8e8a884c47 - nvcr.io/nvidia/k8s-device-plugin:v0.16.2 sizeBytes: 126081487 ``` - [Deployment via helm](https://github.com/NVIDIA/k8s-device-plugin/blob/main/docs/gpu-feature-discovery/README.md#deployment-via-helm) - ### 安裝方式 ``` $ helm repo add nvdp https://nvidia.github.io/k8s-device-plugin $ helm repo update ``` ``` $ helm search repo nvdp --devel NAME CHART VERSION APP VERSION DESCRIPTION nvdp/gpu-feature-discovery 0.17.1 0.17.1 A Helm chart for gpu-feature-discovery on Kuber... nvdp/nvidia-device-plugin 0.17.1 0.17.1 A Helm chart for the nvidia-device-plugin on Ku... ``` ``` helm upgrade -i nvdp nvdp/nvidia-device-plugin \ --namespace gpu-feature-discovery \ --create-namespace \ --set devicePlugin.enabled=false \ --set gfd.enabled=true ``` ``` helm uninstall nvdp --namespace gpu-feature-discovery ``` - ### k8s 正常狀態 ``` $ kubectl get all -n gpu-feature-discovery NAME READY STATUS RESTARTS AGE pod/nvdp-node-feature-discovery-master-77f5fd5bb-cnczb 1/1 Running 0 3m36s pod/nvdp-node-feature-discovery-worker-xcbh6 1/1 Running 1 (3m15s ago) 3m36s pod/nvdp-nvidia-device-plugin-gpu-feature-discovery-8jldw 1/1 Running 0 3m36s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/nvdp-node-feature-discovery-master ClusterIP 10.109.36.255 <none> 8080/TCP 3m37s NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE daemonset.apps/nvdp-node-feature-discovery-worker 1 1 1 1 1 <none> 3m37s daemonset.apps/nvdp-nvidia-device-plugin-gpu-feature-discovery 1 1 1 1 1 <none> 3m37s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nvdp-node-feature-discovery-master 1/1 1 1 3m37s NAME DESIRED CURRENT READY AGE replicaset.apps/nvdp-node-feature-discovery-master-77f5fd5bb 1 1 1 3m37s ``` <br> ## 討論 ### 安裝 NVIDIA GPU Operator 步驟 - ### gpt-o4-mini-high (2025/05/21) 以下是在您的 Kubernetes 叢集(假設已安裝 NVIDIA 驅動與 container runtime)上安裝 NVIDIA GPU Operator 的步驟: --- ### 1. 環境與需求確認 1. **已安裝 NVIDIA 驅動** 您的節點上已透過 Docker 驗證 NVIDIA 驅動可用(`nvidia-smi` 正常顯示)。 2. **Container runtime 支援** 叢集需使用 containerd 或 CRI-O 作為 container runtime。 3. **(若啟用 Pod Security Admission)命名空間安全性策略** 如有啟用 PSA,建議將 GPU Operator 所在命名空間標記為 `privileged`。 --- ### 2. 安裝 Helm(若尚未安裝) ```bash # macOS (Homebrew) brew install helm # Linux (腳本方式) curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash ``` --- ### 3. 新增 NVIDIA Helm 倉庫並更新 ```bash helm repo add nvidia-ngc https://helm.ngc.nvidia.com/nvidia \ && helm repo update ``` --- ### 4. 建立並標記命名空間(可選) ```bash kubectl create namespace gpu-operator kubectl label --overwrite ns gpu-operator pod-security.kubernetes.io/enforce=privileged=privileged ``` --- ### 5. 使用 Helm 安裝 GPU Operator NVIDIA 官方最新版本為 v25.3.0(發佈於 2025 年 3 月):contentReference[oaicite:4]{index=4}。以下示範兩種情境: ### 5.1 預設安裝(包含驅動安裝) ```bash helm install --wait --generate-name \ -n gpu-operator --create-namespace \ nvidia-ngc/gpu-operator \ --version=v25.3.0 ``` ### 5.2 節點已預先安裝 NVIDIA 驅動 ```bash helm install --wait --generate-name \ -n gpu-operator --create-namespace \ nvidia/gpu-operator \ --version=v25.3.0 \ --set driver.enabled=false ``` --- ### 6. 檢查部署狀態 ```bash kubectl -n gpu-operator get pods # 確認以下主要 Pod 都已就緒: # - gpu-operator-xxxxxx (Operator 本身) # - driver-daemonset-xxxx # - toolkit-daemonset-xxxx # - device-plugin-daemonset-xxxx # - nfd-daemonset-xxxx # - mig-manager-daemonset-xxxx ``` --- ### 7. 驗證 GPU 功能 1. 於任一工作節點建立測試 Pod,使用 NVIDIA 提供的 CUDA 範例: ```bash kubectl run cuda-vectoradd \ --image=nvidia/samples:vectoradd-cuda11.2-runtime \ --restart=Never \ --limits=nvidia.com/gpu=1 \ -- sleep 30 kubectl logs cuda-vectoradd ``` 2. 若看到類似 `PASSED` 的訊息,即代表 GPU 已正常被叢集調度並能執行 CUDA 程式。:contentReference[oaicite:6]{index=6} --- 完成以上步驟後,您的 Kubernetes 叢集就已成功透過 NVIDIA GPU Operator 管理 GPU 驅動、device plugin、Container Toolkit、Node Feature Discovery (NFD) 與 MIG 管理等元件,並可直接在 Pod spec 中設定 `limits.nvidia.com/gpu` 來使用 GPU 資源。 <br> --- <br> ### `--set toolkit.enabled=true` 用途為何? 怎麼判斷要帶 `true` 或 `false` ? - ### gpt-4o (2025/06/08) ### ✅ `--set toolkit.enabled=true` 用途與使用時機 `--set toolkit.enabled=true` 是安裝 NVIDIA GPU Operator 時的一個關鍵選項,用來控制是否啟用 **NVIDIA Container Toolkit DaemonSet**,這個 DaemonSet 主要是: --- ### ✅ 什麼是 `toolkit.enabled`? 它會部署 `nvidia-container-toolkit` 的 DaemonSet 到每個節點,**讓容器能夠使用 GPU(例如能跑 `nvidia-smi`)**。 當你使用 containerd(或 Docker)做為 runtime,而節點上**尚未安裝 `nvidia-container-toolkit`** 時,你就必須讓 GPU Operator 幫你裝上這個 component,否則 GPU Pod 會出現錯誤(如找不到 GPU device)。 --- ### 🔍 怎麼判斷要設 `true` 還是 `false`? | 狀況 | toolkit.enabled 要設為? | 說明 | |------|----------------------|------| | 節點 **已安裝 `nvidia-container-toolkit`** | `false` | 避免與系統已有安裝衝突(自行安裝者常見) | | 節點 **尚未安裝 `nvidia-container-toolkit`** | `true` | 讓 GPU Operator 自動安裝 | | 節點使用 GPU Operator 自動安裝驅動、toolkit 全套 | `true`(且 driver.enabled=true) | 一般建議實驗環境這樣做 | | 節點已有 GPU Driver、toolkit 全部手動安裝完 | `false` | 專業環境多半自己控管套件版本與相依性 | --- ### 🧪 怎麼檢查系統是否已有 toolkit? 你可以看是否存在 `/usr/bin/nvidia-container-runtime` 或查詢 `nvidia-container-cli`: ```bash which nvidia-container-runtime which nvidia-container-cli dpkg -l | grep nvidia-container ``` 或查 `/etc/containerd/config.toml` 裡是否設定了 `nvidia` runtime: ```toml [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia] runtime_type = "io.containerd.runc.v2" [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia.options] BinaryName = "/usr/bin/nvidia-container-runtime" ``` --- ### ✅ 結論建議 - **你手動安裝過驅動與 toolkit?** - → 設 `toolkit.enabled=false`(避免 GPU Operator 干預) - **你只裝了驅動,但沒安裝 toolkit?** - → 設 `toolkit.enabled=true` - **你什麼都沒裝?** - → 可以都交給 GPU Operator 自動裝(`driver.enabled=true`, `toolkit.enabled=true`) 如果你希望完全由 GPU Operator 管控所有 GPU 相依工具,則兩者都設為 `true`。但這種方式要特別注意驅動與主機內核是否相容。 <br> --- <br> ### `--set driver.enabled=false` 用途為何? 怎麼判斷要帶 `true` 或 `false` ? - ### gpt-4o (2025/06/08) ### ✅ 什麼是 `driver.enabled`? 它控制是否啟用 `nvidia-driver-daemonset`: - 如果 `driver.enabled=true`: - GPU Operator 會在每個節點部署 DaemonSet,自動安裝 NVIDIA 驅動(包含 kernel module、nvidia-smi、libnvidia 等)。 - 如果 `driver.enabled=false`: - 表示你已在每個節點「**手動安裝好驅動**」,Operator 不會干預。 --- ### 📌 什麼情況要設 `true`?什麼情況要設 `false`? | 節點狀況 | driver.enabled 設定 | 原因/建議 | |----------|----------------------|-------------| | 節點未安裝任何驅動 | `true` | 讓 GPU Operator 自動裝驅動,快速部署 | | 節點已手動安裝驅動(e.g. `.run` 安裝版、apt 安裝) | `false` | 避免 Operator 重裝或版本衝突 | | 節點使用自行建構的客製驅動 | `false` | 通常這種情況需要精細控管驅動版本與 kernel 相容性 | | 節點是裸機長期部署,驅動固定由系統維運裝 | `false` | 維運穩定性考量,不讓 GPU Operator 插手 | --- ### 🔍 如何判斷驅動已存在? 執行以下指令查看是否已安裝驅動: ``` nvidia-smi ``` - 有看到顯示卡與 driver version(如 CUDA Version, Driver Version) → 驅動已安裝 - 出現 `command not found` 或 `No devices were found` → 驅動可能沒裝好或裝錯 也可查看驅動模組是否已載入: ``` lsmod | grep nvidia ``` --- ### 🧱 注意事項 如果你的環境是: - 使用 **官方 NVIDIA Driver Installer (`.run`)** - 驅動是公司政策內部套件管理安裝(e.g. 使用 Ansible 或自建 package) 建議設為: ``` --set driver.enabled=false ``` 否則 GPU Operator 有可能會嘗試卸載你的版本、重裝它的驅動,導致不穩定。 --- ### ✅ 總結建議 | 驅動安裝情況 | `driver.enabled` 設定 | |--------------|------------------------| | 沒有任何驅動 | `true` | | 自行手動安裝驅動 | `false` | | 使用特定內部套件管理驅動 | `false` | | 測試機、快速部署開發環境 | `true` | 如仍不確定,也可以先設定為 `false`,並手動裝好驅動、確認 `nvidia-smi` 運作,再安裝 GPU Operator(只讓它裝 toolkit、plugin)。這樣穩定性較高。 <br> --- <br> ### containerd 的 runtime 設定,增加 nvidia device,是由誰負責設定? - ### gpt-4o (2025/06/08) 在使用 NVIDIA GPU Operator 搭配 containerd 時,containerd 的 runtime 設定中是否出現 `nvidia` runtime,**取決於誰負責安裝 `nvidia-container-toolkit`**。以下是詳細說明: --- ### ✅ 誰負責設定 containerd 的 `nvidia` runtime? | 安裝方式 | 負責設定 containerd 的 runtime? | 備註 | |----------|-------------------------------|------| | **你手動安裝 `nvidia-container-toolkit`** | ✅ 你自己要設定 `/etc/containerd/config.toml` | 不會自動幫你加 `nvidia` runtime | | **由 GPU Operator 安裝 toolkit (`toolkit.enabled=true`)** | ✅ GPU Operator 負責自動設定 | 它會 patch containerd 的 config 並 reload service | | **使用 NVIDIA 官方的 `nvidia-container-runtime` 安裝腳本** | ✅ 安裝腳本會幫你設定 | 適用裸機/VM 自行部署的情境 | | **你手動設定 containerd config.toml** | ✅ 自行新增 runtime 配置 | 通常你得自己手動 restart containerd | --- ### 🔧 containerd 的 `nvidia` runtime 設定長什麼樣子? 檔案位置:`/etc/containerd/config.toml` 範例片段如下: ```toml [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia] runtime_type = "io.containerd.runc.v2" [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia.options] BinaryName = "/usr/bin/nvidia-container-runtime" ``` 這段設定是告訴 containerd: - 當使用 runtimeClass 為 `nvidia` 時,要使用 `/usr/bin/nvidia-container-runtime` 來啟動容器。 - 搭配 GPU Operator 或 AI workloads(如 PyTorch/TensorFlow)才能正確掛載 GPU device。 --- ### 📌 小提醒:這段設定什麼時候生效? 設定完 `/etc/containerd/config.toml` 後,**必須重啟 containerd** 才會生效: ``` sudo systemctl restart containerd ``` --- ### ✅ 如何確認你有這段設定? ``` grep -A5 '\[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia\]' /etc/containerd/config.toml ``` 若沒這段,就代表沒有設定成功(不論是你或 Operator 裝 toolkit 都會需要)。 --- ### 🧭 結論 | 誰裝了 `nvidia-container-toolkit` | 是否自動設定 containerd? | |------------------------|------------------------| | 你自己手動 `apt install` | ❌ 否,需要手動編輯 config.toml | | GPU Operator (`toolkit.enabled=true`) | ✅ 會自動 patch containerd 並設定 runtime | | NVIDIA 官方安裝腳本 (`nvidia-container-toolkit`) | ✅ 多半會自動設定 | 因此: > 📌 若你自己裝 toolkit,**你自己負責設定 containerd runtime**。 > 📌 若讓 GPU Operator 裝 toolkit(`toolkit.enabled=true`),**它會幫你自動加好 `nvidia` runtime。** 如需,我也可以幫你產生自動設定 `config.toml` 的 shell script。 <br> ### NVIDIA GPU Operator 是否會幫你裝 `nvidia-container-toolkit`? - ### gpt-4o (2025/06/09) #### ✅ 是,**GPU Operator 會自動安裝 `nvidia-container-toolkit`** GPU Operator 包含多個 DaemonSet 與元件,其中的 `nvidia-container-toolkit-daemonset` 會: - 在每個節點上安裝: - `nvidia-container-toolkit` - `nvidia-ctk`(新版本的 CLI 工具) - 自動配置 containerd 的 runtime 設定(例如 `/etc/containerd/config.toml`) - 搭配其他元件(如 `nvidia-device-plugin`)協助 GPU pod 啟動時掛載正確的 NVIDIA runtime --- ### 那為什麼還需要手動裝 `nvidia-container-toolkit`? 以下是 **什麼情況你「需要或建議」手動安裝的理由**: #### 🔧 1. **你要在 GPU Operator 安裝前先驗證 containerd 能否正確執行 GPU container** - 例如想先手動測試這個指令: ``` sudo ctr run --rm --gpus 0 nvidia/cuda:12.2.0-base-ubuntu22.04 test-nvidia nvidia-smi ``` - 這時你就需要先自行裝好 `nvidia-container-toolkit`。 --- #### 🔒 2. **你希望有更細節的控制權,不讓 GPU Operator 動態裝東西(安全/可預測性)** - 一些企業環境會要求節點內容固定,不希望 DaemonSet 在背景修改 runtime 設定。 - 此時你可以在安裝 GPU Operator 時加上: ``` --set toolkit.enabled=false ``` - 然後 **手動安裝與設定 containerd 的 NVIDIA runtime**。 --- ### 📌 總結:是否需要手動裝 `nvidia-container-toolkit`? | 情境 | 需手動安裝 toolkit? | 說明 | |------|----------------------|------| | 使用 GPU Operator(toolkit.enabled = true) | ❌ 否 | Operator 會自動安裝與設定 | | 使用 GPU Operator(toolkit.enabled = false) | ✅ 是 | 你要自己裝好 toolkit 並設定 containerd | | 想在 Operator 安裝前先測試 GPU 功能 | ✅ 是 | 可先手動裝 toolkit 驗證 runtime 可用性 | | 自定義環境(CI、安全性高要求) | ✅ 是 | 建議你手動控制 toolkit 的版本與行為 | <br> {%hackmd vaaMgNRPS4KGJDSFG0ZE0w %}