[建置] 安裝 K8s / 釐清 GPU Operator, NVIDIA Device Plugin, nvidia-container-runtime, containerd 的關係 === ###### tags: `K8s / Setup` ###### tags: `Kubernetes`, `k8s`, `setup`, `install`, `containerd`, `nvidia-container-runtime` <br> [TOC] <br> ## 術語 | 術語 | 簡易說明 | |------|--------| | **containerd** | Kubernetes 的容器執行引擎,預設不支援 GPU | | **`ctr` 指令** | containerd CLI<br>`$ sudo ctr images list`<br>`$ sudo ctr images pull docker.io/nvidia/cuda:12.2.0-base-ubuntu20.04`<br>`$ sudo ctr run --rm --gpus 1 docker.io/nvidia/cuda:12.2.0-base-ubuntu20.04 nvidia-test nvidia-smi`<br>(查 k8s image,需要 `-n k8s.io` ) | | | **NVIDIA Container Runtime** | 能跑 GPU 的容器。<br>是一個 plugin,讓 `containerd` 可以使用 NVIDIA GPU | | **`nvidia-container-cli`指令** | NVIDIA Container CLI<br>(NVIDIA Container Toolkit CLI)<br>`$ nvidia-container-cli info`<br> - 確認 `nvidia-container-runtime` 是否正確安裝<br> - 應該會看到所有 GPU 被列出 | | | **NVIDIA Device Plugin** | 為 Kubernetes 提供 GPU 資源資訊<br>(自動註冊 `nvidia.com/gpu` 資源,讓 Pod 可以使用 `resources.limits.nvidia.com/gpu` 配置) | | **NVIDIA GPU Operator** | 安裝 Driver, NVIDIA Device Plugin, NVIDIA Container Runtime 和監控工具等,並設定 containerd 。 | <br> ## 參考資料 - [Kubernetes Container Runtimes](https://kubernetes.io/docs/setup/production-environment/container-runtimes/) - [containerd](https://kubernetes.io/docs/setup/production-environment/container-runtimes/#containerd) - [Docker Engine](https://kubernetes.io/docs/setup/production-environment/container-runtimes/#docker) <br> <hr> <br> ## 討論 ### Kubernetes 的 gpu operator ,用途為何? - ### gpt-4o (2025/05/26) > Kubernetes GPU Operator 功能與用途說明 Kubernetes 的 **GPU Operator** 是由 NVIDIA 提供的一套工具,讓你可以**自動安裝並管理 GPU 驅動、CUDA 工具鏈、Container Runtime 和監控工具**等,在 Kubernetes 中順利使用 GPU 執行 AI 或高效能計算工作負載。 --- ## 🎯 GPU Operator 的用途與功能總覽 | 功能 | 說明 | |------|------| | **驅動安裝** | 自動為每個含 GPU 的節點安裝 NVIDIA 驅動(例如 `nvidia-smi` 所需) | | **Container Runtime** | 安裝與設定 `nvidia-container-runtime`,讓容器能正確使用 GPU | | **CUDA 支援** | 安裝 CUDA 驅動與對應的 libraries,供訓練或推論使用 | | **DCGM Exporter** | 安裝 NVIDIA 的監控模組,可輸出 GPU 資訊供 Prometheus/Grafana 使用 | | **Device Plugin** | 自動註冊 `nvidia.com/gpu` 資源,讓 Pod 可以使用 `resources.limits.nvidia.com/gpu` 配置 | | **MIG 支援** | 支援 A100 GPU 的 Multi-Instance GPU 功能,實現更細粒度資源管理 | | **可自動升級與健康檢查** | GPU Operator 提供版本控制、監控、重新安裝能力 | --- ## 🧩 為什麼需要 GPU Operator? 在原生的 K8s 中: - **不會自動偵測或配置 GPU 驅動** - 你得手動安裝驅動、設定 container runtime、配置 device plugin,很容易出錯 透過 GPU Operator,可以: - 一鍵自動完成所有 GPU 節點的驅動、工具安裝與設定 - 節省人力時間,統一管理 GPU 資源 - 快速部署 AI 訓練/推論環境(如 PyTorch、TensorFlow) --- ## 🛠️ 運作方式(內部組件) GPU Operator 是一個 Helm Chart,部署後會創建以下模組: - `nvidia-driver-daemonset` - `nvidia-container-toolkit-daemonset` - `nvidia-device-plugin-daemonset` - `nvidia-dcgm-exporter` - `nvidia-fabricmanager` - `nvidia-operator-validator`(確認安裝成功) 這些 DaemonSet 會自動在有 GPU 的節點啟動對應容器來安裝驅動與 runtime。 --- ## 📌 補充:與 NFD (Node Feature Discovery) 配合 若搭配 NFD 使用,GPU Operator 可根據 GPU 特徵自動打上 label,如: """text nvidia.com/gpu.present: "true" """ 讓你可以使用 nodeSelector 或 affinity 做更靈活的 Pod 調度。 --- ### 想要部署 GPU Operator 嗎?我可以給你具體的安裝指令與 YAML 範例。 <br> <hr> <br> ### GPU Operator 是否跟 containerd 有關係? - ### gpt-4o (2025/05/26) 是的,**GPU Operator 和 containerd 有關係**,因為它需要正確地設定 containerd 才能讓容器使用 GPU。以下是兩者的關係與互動說明: --- ### 🧩 GPU Operator 與 containerd 的關係 #### 1. **containerd 需支援 NVIDIA GPU** containerd 本身不支援 GPU,需要透過 **`nvidia-container-runtime`** 插件讓 containerd 可以使用 NVIDIA GPU。 #### 2. **GPU Operator 會安裝 nvidia-container-runtime** GPU Operator 在部署時會: - 檢查你是否使用 containerd(或 Docker) - 若使用 containerd,就會安裝與設定 `nvidia-container-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" ``` #### 3. **GPU Pod 要求的 runtime 必須是 `nvidia`** 一旦 GPU Operator 設定好 containerd,你的 GPU Pod 就可以透過以下方式使用 GPU: ```yaml resources: limits: nvidia.com/gpu: 1 ``` Kubernetes 會自動選擇 `nvidia` runtime 來啟動該容器(只要 device plugin 有註冊)。 --- ### 🚧 若 containerd 未正確設定,會出現哪些錯誤? - Pod 永遠處於 `CreateContainerConfigError` 或 `RunContainerError` - `nvidia-smi` 在容器內失敗,或找不到 GPU - 查看節點的 kubelet log,會出現: ``` unknown runtime: nvidia ``` --- ### ✅ 怎麼確認 containerd 已正確支援 GPU? 你可以執行以下檢查: ``` # 1. containerd 是否載入 nvidia runtime cat /etc/containerd/config.toml | grep -A4 '\[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia\]' # 2. 驗證 runtime 是否存在 (常見路徑:/usr/bin/nvidia-container-runtime) which nvidia-container-runtime # 3. 驗證 GPU pod 是否成功使用 GPU kubectl exec -it <gpu-pod> -- nvidia-smi ``` --- ### ✍️ 小結 | 組件 | 是否需要 | 用途 | |---------------------|----------|------| | containerd | ✅ | Pod 執行容器的核心 runtime | | nvidia-container-runtime | ✅(GPU 必須) | 讓 containerd 支援 GPU 的關鍵 | | GPU Operator | ✅ | 自動化安裝上述內容與配置 | ### 備註: - ### containerd 是否載入 nvidia runtime `/etc/containerd/config.toml` 完整上下文 ```toml [plugins."io.containerd.grpc.v1.cri".containerd] default_runtime_name = "nvidia" <-- ... [plugins."io.containerd.grpc.v1.cri".containerd.default_runtime] ... [plugins."io.containerd.grpc.v1.cri".containerd.default_runtime.options] [plugins."io.containerd.grpc.v1.cri".containerd.runtimes] [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] ... [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] ... [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia] runtime_type = "io.containerd.runc.v2" privileged_without_host_devices = false [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia.options] BinaryName = "/usr/bin/nvidia-container-runtime" ``` - ### 驗證 runtime 是否存在 ``` $ which nvidia-container-runtime /usr/bin/nvidia-container-runtime ``` - ### 驗證 GPU pod 是否成功使用 GPU ```yaml= # gpu-pod.yaml apiVersion: v1 kind: Pod metadata: name: gpu-pod spec: containers: - name: cuda-container image: nvidia/cuda:12.2.0-base-ubuntu20.04 resources: limits: nvidia.com/gpu: 1 command: ["nvidia-smi"] ``` <br> <hr> <br> ### GPU Operator、NVIDIA Device Plugincontainerd 的關係總整理 - ### gpt-4o (2025/05/26) 這三個元件:**GPU Operator、NVIDIA Device Plugin、containerd**,在 Kubernetes 中扮演不同角色,但密切相關。搞不清楚很正常,因為它們的功能有交集但層次不同。下面我用一張圖和說明來幫你理清: --- ### 🧠 簡化理解:三者的角色分層 #### 🧱 底層:`containerd` - Kubernetes 的容器執行引擎(runtime) - 預設 **不支援 GPU** - 需要整合 `nvidia-container-runtime` 才能讓容器跑出 GPU 功能 --- #### 🧩 中層:`nvidia-container-runtime` - 是一個 plugin,讓 `containerd` 可以啟用 GPU - 你要讓 containerd 知道「遇到 GPU 相關容器要用它來跑」 --- #### 🎯 上層:`NVIDIA Device Plugin` - 為 Kubernetes 提供 **GPU 資源資訊** - 自動在節點上註冊 `nvidia.com/gpu` 資源,Pod 才能宣告要 GPU --- #### 🛠️ 自動化全家桶:`NVIDIA GPU Operator` GPU Operator 是**上面所有東西的自動安裝工具**,幫你: 1. 安裝驅動(Driver) 2. 安裝 `nvidia-container-runtime` 並改 containerd 設定 3. 安裝 `nvidia-device-plugin` 4. 安裝監控工具(如 DCGM exporter) 5. 安裝 MIG 管理員(若使用 A100) --- ### 🧩 三者關係圖(由下而上) ``` +---------------------------+ | GPU Operator | ⬅️ 負責安裝下面所有元件 | - 安裝驅動 | | - 安裝 device plugin | | - 設定 containerd | +-------------▲-------------+ | +-------------|-------------+ | NVIDIA Device Plugin | ⬅️ 讓 K8s 認得 nvidia.com/gpu +-------------▲-------------+ | +-------------|-------------+ | nvidia-container-runtime | ⬅️ containerd 用這個來跑 GPU 容器 +-------------▲-------------+ | +-------------|-------------+ | containerd | ⬅️ Pod 的容器真正由它執行 +---------------------------+ ``` --- ### ✅ 總結比較表 | 元件 | 類型 | 功能 | 誰安裝? | 與 GPU Operator 的關係 | |------|------|------|-----------|--------------------------| | containerd | Container Runtime | 執行容器 | 系統預先裝好 | 需要額外設定才能用 GPU | | nvidia-container-runtime | plugin | 讓 containerd 支援 GPU | GPU Operator 幫你裝 | 必要,Operator 幫你處理 | | NVIDIA Device Plugin | Kubernetes plugin | 對 K8s 暴露 GPU 資源 | GPU Operator 幫你裝 | Operator 自動安裝與配置 | | GPU Operator | Operator | 一鍵部署所有 GPU 組件 | 手動裝 Operator | 管理其他所有組件 | --- ### 🔍 怎麼判斷你的環境有沒有設好? 你可以從節點、Pod、containerd 三層檢查: #### A. 節點是否有 GPU 資源? ``` kubectl describe node <your-node> | grep -A5 "Capacity" # 看有沒有 nvidia.com/gpu ``` #### B. Device Plugin 是否有註冊? ``` kubectl get pods -n nvidia-gpu-operator kubectl logs <nvidia-device-plugin-pod> -n nvidia-gpu-operator ``` #### C. containerd 是否支援 GPU? ``` cat /etc/containerd/config.toml | grep nvidia ``` --- 如需我幫你逐步確認你目前環境設定是否到位,也可以把你目前的節點 label、GPU operator namespace pods、containerd 設定貼上來,我幫你逐一看。 <br> <hr> <br> ### [containerd 資訊] containerd 談到的 cgroup driver 是指什麼? - ### gpt-4o (2025/05/26) > containerd 中的 cgroup driver 是什麼? 在 Kubernetes 和 containerd 等容器運行時(Container Runtime)中,**cgroup driver(控制群組驅動器)** 是指:**容器運行時用來與 Linux 的 cgroups(Control Groups)溝通與管理資源限制的方式**。 --- ### 🧩 什麼是 cgroups? **cgroups(Control Groups)** 是 Linux 的一項功能,用來: - 限制(Limit):CPU、記憶體、IO 等資源 - 監控(Monitor):記錄使用量 - 隔離(Isolate):彼此獨立運作 - 優先權(Prioritize):設置不同等級的資源分配 Kubernetes 會透過 container runtime(如 containerd 或 Docker)來設定這些資源限制。 --- ### 🔧 cgroup driver 的意義是? Linux 上管理 cgroups 的方式有兩種主流: | Driver | 說明 | |--------|------| | **cgroupfs** | 使用 Linux 上的 `/sys/fs/cgroup` 路徑直接操作 cgroups(較原始) | | **systemd** | 使用 `systemd` 的 cgroup 控制介面來管理(較整合,推薦使用) | --- #### containerd 的 cgroup driver 當你安裝 containerd 時,它的預設行為取決於 distro,例如 Ubuntu 常預設為 `systemd`。 設定檔位於 `/etc/containerd/config.toml` 中,相關欄位如下: ```toml [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] SystemdCgroup = true # ✅ true 表示使用 systemd,false 則是 cgroupfs ``` --- ### ✅ 為什麼要關心這個設定? Kubernetes 的 kubelet 也需要設定使用同一個 cgroup driver,例如: ```yaml KUBELET_EXTRA_ARGS=--cgroup-driver=systemd ``` 如果 containerd 用的是 `systemd`,而 kubelet 卻是 `cgroupfs`,就會出現這類錯誤: ```text "failed to start container: systemd cgroup driver mismatch" ``` --- ### 🛠️ 建議:**Kubernetes 與 containerd 一致使用 `systemd`** - 這樣可以與現代 Linux distro(如 Ubuntu 20.04/22.04)系統管理一致 - 更穩定,錯誤較少,整合性佳 --- 需要我幫你查你目前的 containerd 是用哪種 driver 嗎?還是幫你寫個自動檢查腳本? <br> <hr> <br> ### [containerd 資訊] 目前的 containerd 是用哪種 driver - ### gpt-4o (2025/05/26) > 如何確認目前的 containerd 使用哪種 cgroup driver 你可以用下列方法來確認 **containerd 現在使用哪種 cgroup driver**: --- ### ✅ 方法 1:查看 containerd 設定檔 ```bash grep SystemdCgroup /etc/containerd/config.toml ``` #### 🔍 結果解讀: - `SystemdCgroup = true` 👉 表示使用 **systemd** - `SystemdCgroup = false` 👉 表示使用 **cgroupfs** - 如果找不到,可能是預設值(通常為 false),建議用下一步確認實際狀況 --- ### ✅ 方法 2:用 crictl 工具查看實際運作的 container runtime 設定 ```bash sudo crictl info | grep -i "systemdcgroup" ``` 你會看到類似: ```json "SystemdCgroup": true, ``` --- ### ✅ 方法 3:完整看設定與版本(推薦) ```bash containerd config dump | grep SystemdCgroup ``` 如果你看到: ```toml SystemdCgroup = true ``` 就代表正在使用 `systemd`。 --- ### 🧪 延伸確認(若你也用 kubelet) 你也可以確認 kubelet 使用的 driver 是否一致: ```bash # example $ ps aux | grep kubelet root 2238894 4.9 0.0 5822864 120220 ? Ssl May26 63:58 \ /usr/bin/kubelet \ --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf \ --kubeconfig=/etc/kubernetes/kubelet.conf \ --config=/var/lib/kubelet/config.yaml \ --container-runtime-endpoint=unix:///var/run/containerd/containerd.sock \ --pod-infra-container-image=registry.k8s.io/pause:3.10 ``` ```bash ps aux | grep kubelet | grep cgroup-driver ``` 若顯示: ```bash --cgroup-driver=systemd ``` 就代表與 containerd 一致,✅ 無衝突。 <br> {%hackmd vaaMgNRPS4KGJDSFG0ZE0w %}