values.yaml 總覽 === ###### tags: `SlinkyProject` ###### tags: `SlinkyProject`, `Kubernetes`, `k8s`, `app`, `slurm`, `SlinkyProject`, `upgrade`, `v1.0.0-rc1` <br> [TOC] <br> # 元件 ## 映像檔用途 ### `ghcr.io/slinkyproject/slurmdbd:25.11-ubuntu24.04` - **用途**: Slurm Database Daemon (slurmdbd) 專用映像檔 - **角色**: 負責 Slurm 會計系統 (accounting),處理作業歷史記錄的儲存 - **主要服務**: `slurmdbd` daemon - **參考**: helm/slurm/README.md:46 - **Q&A** - ### 為什麼 slurmdbd 映像檔沒有這些 scontrol, sacctmgr 等管理操作指令? 根據 Slurm 架構設計: 1. **slurmdbd 是獨立服務** - 它只負責接收來自 slurmctld 的會計資料 - 它**不需要**與使用者互動 - 它**不執行**任何 Slurm 管理命令 - 參考: docs/usage/system-requirements.md:81 2. **容器化設計原則** - 每個容器只包含必要的二進位檔案 - 減少攻擊面和映像檔大小 - 參考: docs/usage/system-requirements.md:55 (distroless base) 3. **正確的操作方式** - 管理操作應在 **login node** 或 **controller node** 執行 - slurmdbd pod 不應該被當作管理介面使用 ### `ghcr.io/slinkyproject/login-pyxis:25.11-ubuntu24.04` - **用途**: Login node 映像檔,包含 Pyxis 容器化作業支援 - **角色**: 使用者登入節點 (submit node/jump host),供使用者提交作業 - **主要功能**: 完整的 Slurm 客戶端工具集 + Pyxis/Enroot 容器支援 - **參考**: docs/usage/pyxis.md:43 <br> --- ## Slurm 三大元件交互作用圖 > - codebase: > by `us.anthropic.claude-sonnet-4-5-20250929-v1:0` (2026/01/20) ### 1. 核心元件與通訊埠 ``` ┌─────────────────────┐ │ slurm-controller │ (pod/slurm-controller-0, 3 containers) │ ┌───────────────┐ │ │ │ slurmctld │ │ ← Port 6817 (Slurm Controller Daemon) │ └───────────────┘ │ │ ┌───────────────┐ │ │ │ reconfigure │ │ ← 配置重載輔助容器 │ └───────────────┘ │ │ ┌───────────────┐ │ │ │ logfile │ │ ← 日誌收集容器 │ └───────────────┘ │ └─────────────────────┘ ↑ ↓ (6817) │ ├─────────────────────────────────┐ ↓ ↓ ┌──────────────────┐ ┌──────────────────┐ │ slurm-login │ │ slurm-accounting │ │ ┌────────────┐ │ │ ┌────────────┐ │ │ │ login │ │ │ │ slurmdbd │ │ ← Port 6819 │ │ (使用者介面) │ │ │ └────────────┘ │ │ └────────────┘ │ └──────────────────┘ └──────────────────┘ ↓ (3306) ┌──────────────────┐ │ MariaDB │ │ (MySQL DB) │ └──────────────────┘ ``` --- ### **2. 詳細通訊流程與職責** #### **A. slurmctld (Controller) - 大腦** - **主要職責**: - **配置管理**: 管理 Slurm 叢集配置 (slurm.conf) - **資源管理**: 管理計算節點 (compute nodes) 的狀態 - **作業監控**: 追蹤執行中的作業狀態 - **作業排程**: 決定作業在哪些節點上執行 - **監聽端口**: `6817` - **參考**: helm/slurm/README.md:57, helm/slurm/values.yaml:130 #### **B. slurmdbd (Accounting Database) - 會計系統** - **主要職責**: - **作業歷史記錄**: 儲存所有已完成作業的資訊 - **資源使用統計**: 記錄用戶/帳號的資源使用情況 - **會計資料代理**: 作為 slurmctld 與 MariaDB 之間的橋樑 - **監聽端口**: `6819` - **資料庫連接**: 連接到 MariaDB (port `3306`) - **參考**: helm/slurm/README.md:32, helm/slurm/README.md:51 #### **C. Login Node - 使用者入口** - **主要職責**: - **SSH 登入**: 提供使用者 SSH 登入點 (jump host) - **作業提交**: 使用者通過此節點提交作業 (`sbatch`, `srun`) - **叢集查詢**: 查詢作業狀態 (`squeue`), 節點狀態 (`sinfo`) - **管理操作**: 執行管理命令 (`sacctmgr`, `scontrol`) - **不監聽端口** (客戶端角色) - **參考**: helm/slurm/README.md:98-99 --- ### **3. 交互作用流程** #### **場景 1: 使用者提交作業** ``` 1. User → Login Node (SSH) $ sbatch myjob.sh 2. Login Node → slurmctld (port 6817) [作業提交請求: JobID=12345, CPUs=4, Nodes=1] 3. slurmctld 處理: - 驗證資源請求 - 檢查使用者權限 (如有啟用會計系統,會查詢 slurmdbd) - 決定排程優先級 - 將作業放入佇列或立即分配資源 4. slurmctld → slurmdbd (port 6819) [記錄作業開始: JobID=12345, User=alice, StartTime=...] 5. slurmdbd → MariaDB (port 3306) [INSERT INTO job_table (...)] 6. slurmctld → slurmd (worker nodes) [啟動作業: JobID=12345, Script=/path/to/myjob.sh] 7. 作業完成後: slurmd → slurmctld → slurmdbd → MariaDB [記錄作業結束: EndTime, ExitCode, CPUTime, ...] ``` #### **場景 2: 使用者查詢作業狀態** ``` 1. User → Login Node $ squeue -u alice 2. Login Node → slurmctld (port 6817) [查詢請求: 列出 alice 的作業] 3. slurmctld 回傳: [JobID=12345, State=RUNNING, Nodes=slurm-worker-0, ...] 4. Login Node → User 顯示作業列表 ``` #### **場景 3: 管理員查詢歷史作業** ``` 1. Admin → Login Node $ sacctmgr show job jobid=12345 2. Login Node → slurmdbd (port 6819) [查詢請求: 作業 12345 的歷史記錄] 3. slurmdbd → MariaDB (port 3306) [SELECT * FROM job_table WHERE job_id=12345] 4. MariaDB → slurmdbd → Login Node → Admin [作業詳細資訊: User, Account, CPUTime, Memory, ...] ``` #### **場景 4: 配置變更** ``` 1. Admin → Login Node $ scontrol update NodeName=worker-0 State=DRAIN 2. Login Node → slurmctld (port 6817) [配置更新請求: 將 worker-0 設為 DRAIN 狀態] 3. slurmctld 處理: - 更新內部狀態 - 停止分配新作業到該節點 - 通知 slurmdbd 記錄節點狀態變更 4. slurmctld → slurmdbd (port 6819) [記錄事件: Node=worker-0, State=DRAIN, Time=...] 5. slurmdbd → MariaDB (port 3306) [INSERT INTO event_table (...)] ``` --- ### **4. 為什麼 slurmdbd Pod 沒有管理工具** 根據 **docs/usage/system-requirements.md:81**,slurmdbd 是一個**獨立的資料庫代理服務**: - **slurmdbd 不需要與使用者互動** - **slurmdbd 只負責接收 slurmctld 的資料並寫入 MariaDB** - **slurmdbd 不執行任何管理命令** 這是**容器化設計的最佳實踐** (Single Responsibility Principle): - 每個容器只包含必要的二進位檔案 - 減少攻擊面和映像檔大小 - 參考: docs/usage/system-requirements.md:55 (distroless base) --- ### **5. 通訊協定與認證** ```yaml # 所有通訊使用 Slurm 內部協定 AuthType: auth/slurm # 基於共享金鑰 (slurm.key) AuthAltTypes: auth/jwt # 備用 JWT 認證 # 金鑰共享方式 - 所有 Slurm 元件必須共享相同的 /etc/slurm/slurm.key - 通過 Kubernetes Secret 掛載到所有 pod - 參考: helm/slurm/values.yaml:165 (slurmKeyRef) ``` --- ### **6. 高可用性設計** ``` Controller (StatefulSet): - replicas: 1 - persistence: enabled (保留排程器狀態) - headless service: slurm-controller Accounting (StatefulSet): - replicas: 1 - 連接到外部或內部 MariaDB Login (Deployment): - replicas: 可擴展 (例如: 3) - LoadBalancer service: 負載均衡 ``` --- ### **總結: 三者關係** | 元件 | 角色 | 通訊方向 | 端口 | 映像檔 | |------|------|----------|------|--------| | **slurmctld** | 排程器/大腦 | 接收來自 login/slurmd 的請求 | 6817 | slurmctld:25.11 | | **slurmdbd** | 會計資料庫代理 | 接收來自 slurmctld 的記錄 | 6819 | slurmdbd:25.11 | | **login** | 使用者入口 | 連接到 slurmctld (客戶端) | 無 | login-pyxis:25.11 | **核心流程**: ``` User → Login → slurmctld (排程) → slurmd (執行) ↓ slurmdbd (記錄) → MariaDB (儲存) ``` 這三個元件構成了完整的 Slurm 叢集運作: - **Login**: 使用者介面 - **slurmctld**: 大腦 (排程與資源管理) - **slurmdbd**: 記憶 (歷史記錄與會計) <br> --- --- <br> # controller ```Yaml # Slurm controller (slurmctld) configuration. controller: slurmctld: # default: # - Liveness: http-get http://:slurmctld/livez delay=0s timeout=1s period=10s #success=1 #failure=6 # - Readiness: http-get http://:slurmctld/readyz delay=0s timeout=1s period=10s #success=1 #failure=3 # - Startup: http-get http://:slurmctld/livez delay=0s timeout=1s period=10s #success=1 #failure=6 # ref: http://10.78.26.44:30000/deepwiki/slurm-operator-v1.0.0-20251125/-/issues/48#note_315586 startupProbe: httpGet: path: /livez port: slurmctld failureThreshold: 60 # 6 -> 60 periodSeconds: 10 timeoutSeconds: 20 # 1 -> 20 initialDelaySeconds: 10 # 0 -> 10 readinessProbe: httpGet: path: /readyz port: slurmctld failureThreshold: 60 # 3 -> 60 periodSeconds: 10 timeoutSeconds: 20 # 1 -> 20 livenessProbe: httpGet: path: /livez port: slurmctld failureThreshold: 60 # 6 -> 60 periodSeconds: 10 timeoutSeconds: 20 # 1 -> 20 # -- (map[string]string \| map[string][]string) Extra Slurm configuration lines appended to `slurm.conf`. # If `extraConf` is not empty, it takes precedence. # Ref: https://slurm.schedmd.com/slurm.conf.html extraConfMap: # DebugFlags: [] # MinJobAge: 2 # SchedulerParameters: [] # SlurmctldDebug: debug2 # SlurmSchedLogLevel: 1 # SlurmdDebug: debug2 AccountingStorageEnforce: associations,limits,safe EnforcePartLimits: ALL # Extend slurmd response timeout (default: 300 seconds) SlurmdTimeout: 600 # Extend message timeout between slurmctld daemons (default: 10 seconds) MessageTimeout: 20 # TCP connection timeout (default: 2 seconds) TCPTimeout: 10 # Time before a node is considered unresponsive (default: 300 seconds) # UnresponsiveTime: 600 # -> connection refused # SideEffect: # [Warning][Unhealthy][kubelet] Startup probe failed: # Get "http://10.244.65.148:6817/livez": # dial tcp 10.244.65.148:6817: connect: connection refused # NAME READY STATUS RESTARTS AGE # pod/slurm-controller-0 2/3 Running 0 7m36s ``` <br> --- --- <br> # loginsets ## `loginsets[].slinky` ### 如何在 Slurm Cluster 中設定固定的 Service Port (例如 32222) - ### `us.anthropic.claude-sonnet-4-5-20250929-v1:0` (2026/01/27) 根據我檢視的程式碼,你有**三種方式**可以設定固定的 Service NodePort: ### 方式 1:直接設定 `nodePort` (推薦) 在 `values.yaml` 中的 `loginsets` 或其他服務設定中,直接指定 `nodePort`: ```yaml loginsets: slinky: enabled: true replicas: 1 # ... 其他設定 ... service: metadata: {} nodePort: 32222 # 固定 NodePort 為 32222 port: 22 # Service port (可選,預設 22) spec: type: LoadBalancer # 或 NodePort ``` ### 方式 2:透過 `spec` 設定更完整的 Service 規格 ```yaml loginsets: slinky: enabled: true replicas: 1 # ... 其他設定 ... service: metadata: {} spec: type: NodePort # 必須是 NodePort 或 LoadBalancer ports: - name: ssh port: 22 targetPort: 22 nodePort: 32222 # 固定 NodePort protocol: TCP ``` ### 方式 3:混合使用 (簡化版) ```yaml loginsets: slinky: enabled: true replicas: 1 # ... 其他設定 ... service: spec: type: NodePort port: 22 nodePort: 32222 ``` --- ### 其他服務的 Port 設定 同樣的方式也適用於其他服務: #### Controller (slurmctld) - 預設 port 6817 ```yaml controller: service: spec: type: NodePort port: 6817 nodePort: 30817 # 固定為 30817 ``` #### REST API (slurmrestd) - 預設 port 6820 ```yaml restapi: service: spec: type: NodePort port: 6820 nodePort: 30820 # 固定為 30820 ``` #### Accounting (slurmdbd) - 預設 port 6819 ```yaml accounting: enabled: true service: spec: type: NodePort port: 6819 nodePort: 30819 # 固定為 30819 ``` --- ### 注意事項 1. **NodePort 範圍限制**: Kubernetes 預設 NodePort 範圍是 `30000-32767`,確保你的 port 在這個範圍內 2. **Port 衝突**: 確保指定的 NodePort 沒有被其他 Service 使用 3. **Service Type**: 只有 `NodePort` 和 `LoadBalancer` 類型的 Service 才能使用 `nodePort` 4. **參考位置**: 設定位於 `helm/slurm/values.yaml` 的第 240-251 行 (controller)、340-351 行 (restapi)、451-463 行 (accounting)、567-578 行 (loginsets) 你想要為哪個服務設定固定的 NodePort?我可以幫你產生完整的 `values.yaml` 設定範例。 <br> --- --- <br> # `nodesets[]` ## 如何從 templates 產生完整的 nss yaml? ``` $> helm template slurm \ oci://ghcr.io/slinkyproject/charts/slurm \ --namespace=slurm \ --version=1.0.1 \ --set nodesets.slinky=null \ -f /tmp/slinky/worker-c8m64gt1-nodeset.yaml \ --show-only templates/nodeset/nodeset-cr.yaml \ > c8m64gt1-nss.yaml $> kubectl -n slurm apply -f c8m64gt1-nss.yaml ``` <br> ## `nodesets[].slurmd` ### Q&A: nodesets.slinky.slurmd.resources 和 nodesets.slinky.podSpec.requests 兩者差在哪裡? <!-- http://10.78.26.44:30000/deepwiki/slurm-operator-v1.0.0-20251125/-/issues/15 nodesets.slinky.slurmd.resources 和 nodesets.slinky.podSpec.requests 兩者差在哪裡? --> - ### Question ```yaml nodesets: slinky: ... slurmd: ... # -- The container resource limits and requests. # Ref: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#resource-requests-and-limits-of-pod-and-container resources: {} # requests: # cpu: 1 # memory: 1Gi ... # -- (corev1.PodSpec) Extend the pod template, and/or override certain configurations. # Ref: https://kubernetes.io/docs/concepts/workloads/pods/#pod-templates podSpec: # -- The pod resource limits and requests. # Ref: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#resource-requests-and-limits-of-pod-and-container resources: {} # requests: # cpu: 1 # memory: 1Gi ``` nodesets.slinky.slurmd.resources 和 nodesets.slinky.podSpec.requests 兩者差在哪裡? - ### Claude Sonnet4.5 (2025/12/10) 這兩個設定的差異如下: **`nodesets.slinky.slurmd.resources`** - 設定 **slurmd container** 的資源限制和請求 - 適用於 Pod 中的 slurmd 容器本身 - 控制該特定容器可以使用的 CPU 和記憶體 **`nodesets.slinky.podSpec.resources`** - 設定 **整個 Pod** 的資源限制和請求 - 適用於 Pod 層級(可能包含多個 containers) - 如果 Pod 有多個容器,這會是所有容器的總和限制 **使用情境:** - 如果 Pod 只有 slurmd 一個容器:兩者效果相似 - 如果 Pod 有多個容器(如 sidecar):`slurmd.resources` 只控制 slurmd,`podSpec.resources` 控制整體 通常應該設定 `slurmd.resources`,除非需要對整個 Pod 進行額外的資源控制。 <br> --- ## `nodesets[].useResourceLimits` - ### commits - [feat: add useResourceLimits option](https://github.com/SlinkyProject/slurm-operator/commit/3e63fef9807c1775db9c3d20efd306069ac13a13), 2025/05/17 ### useResourceLimits 用途、影響與衝擊 - ### Claude Sonnet4 (2025/11/18) ### **一、用途說明** `useResourceLimits` 是 Slurm Helm Chart 中的一項配置選項,用於**自動將 Kubernetes 容器的資源限制 (`resources.limits`) 傳播到 Slurm 守護程序 (slurmd)**。 #### **運作機制** 1. **啟用時** (`useResourceLimits: true`,預設值): - 從 `slurmd` 容器的 `resources.limits.cpu` 提取 CPU 限制 - 從 `slurmd` 容器的 `resources.limits.memory` 提取記憶體限制 - 將這些值轉換為環境變數 `POD_CPUS` 和 `POD_MEMORY` - 注入到 slurmd 容器中,供 Slurm 節點配置使用 2. **停用時** (`useResourceLimits: false`): - 不會自動注入 `POD_CPUS` 和 `POD_MEMORY` 環境變數 - 需要手動配置 Slurm 節點資源 --- ### **二、帶來的影響** #### **正面影響** 1. **自動化資源配置** - 無需手動維護 Slurm 節點的 `CPUs` 和 `RealMemory` 配置 - 減少配置錯誤和不一致的風險 2. **Kubernetes 原生整合** - Slurm 節點資源自動對齊 Kubernetes Pod 資源限制 - 確保資源管理的一致性 3. **簡化部署與維護** - 修改 Pod 資源限制時,Slurm 配置自動更新 - 適合動態調整資源配置的場景 #### **潛在限制** 1. **依賴 resources.limits 設定** - 如果未設定 `resources.limits`,環境變數值為 `0` - 可能導致 Slurm 節點資源配置異常 2. **向上取整策略** - CPU 使用 `ceil` 函數向上取整(如 `1.5` 變成 `2`) - 可能導致 Slurm 配置的資源大於 Kubernetes 實際限制 3. **記憶體單位轉換** - 統一轉換為 Megabytes,可能損失精度 --- ### **三、使用衝擊與建議** #### **衝擊評估** | **面向** | **啟用 (true)** | **停用 (false)** | |---------|----------------|-----------------| | **配置複雜度** | 低(自動化) | 高(需手動配置) | | **資源一致性** | 高 | 取決於手動配置正確性 | | **靈活性** | 受限於 K8s limits | 完全可自訂 | | **錯誤風險** | 低(自動對齊) | 高(人為失誤) | #### **建議場景** - **建議啟用**: - 標準化部署環境 - 需要自動化管理 - Slurm 節點資源與 Pod 資源應保持一致 - **建議停用**: - 需要更細緻的 Slurm 資源配置 - Slurm 節點資源與 Pod 資源需要不同設定 - 有特殊的資源超額配置需求 #### **最佳實踐** ```yaml nodesets: slinky: useResourceLimits: true # 啟用自動資源傳播 slurmd: resources: limits: cpu: "4" # 必須明確設定 memory: "8Gi" # 必須明確設定 ``` --- ### **四、技術實作細節** **相關檔案位置**: - 範本邏輯:`deploy_cluster/slurm-1.0.0-rc1/templates/nodeset/nodeset-cr.yaml:17-21` - Helper 函數:`deploy_cluster/slurm-1.0.0-rc1/templates/nodeset/_helpers.tpl:49-67` - 預設配置:`deploy_cluster/slurm-1.0.0-rc1/values.yaml:646-647` <br> --- ### Q&A: 未設定 podSpec.resources 時,對 `useResourceLimits` 的影響 - ### Question ``` nodesets: <name> podSpec: resources: {} # requests: # cpu: 1 # memory: 1Gi ``` 沒有設定 podSpec.resources 時,預設值為何? - ### Claude Sonnet4 (2025/11/18) 根據 Slurm Helm Chart 的配置結構分析: ### **預設值為空物件 (`{}`)** ```yaml nodesets: <name>: podSpec: resources: {} # 預設為空物件 slurmd: resources: {} # 預設為空物件 ``` --- ### **關鍵行為說明** #### **1. 無資源限制** - Kubernetes 預設行為:當 `resources: {}` 時,Pod **不會設定任何資源請求 (requests) 或限制 (limits)** - Pod 可使用節點上的**所有可用資源**(無上限) #### **2. 與 `useResourceLimits` 的交互影響** 當 `useResourceLimits: true`(預設值)時: ```yaml # 計算邏輯(來自 _helpers.tpl:49-67) POD_CPUS = .resources.limits.cpu # 若未設定 → 0 POD_MEMORY = .resources.limits.memory # 若未設定 → 0 ``` **實際效果**: - `slurmd.resources.limits` 未設定 → `POD_CPUS=0`, `POD_MEMORY=0` - Slurm 節點會註冊為 **0 CPU / 0 MB 記憶體** - 導致 Slurm 無法正確分配任務 --- ### **風險與建議** | **配置情況** | **結果** | **建議** | |------------|---------|---------| | **未設定 resources** | Slurm 節點資源 = 0 | ❌ 不可用於生產環境 | | **僅設定 requests** | Slurm 節點資源 = 0 | ⚠️ 需停用 `useResourceLimits` | | **設定 limits** | Slurm 節點資源 = limits | ✅ 正常運作 | #### **建議配置** ```yaml nodesets: slinky: useResourceLimits: true slurmd: resources: limits: # 必須明確設定 cpu: "4" memory: "8Gi" requests: # 可選,但建議設定 cpu: "2" memory: "4Gi" ``` --- ### **總結** - **預設值**:`resources: {}` (空物件) - **實際效果**:無資源限制 + Slurm 資源為 0 - **必須操作**:**明確設定 `slurmd.resources.limits`** 才能讓 Slurm 節點正常運作 <br> --- <br> ## `nodesets[].updateStrategy` ```yaml= # Update strategy configuration. # Ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies updateStrategy: # -- The strategy type. Can be one of: RollingUpdate; OnDelete. type: RollingUpdate # The RollingUpdate configuration. Ignored unless `type=RollingUpdate`. rollingUpdate: # -- Maximum number of pods that can be unavailable during update. # Can be an absolute number (ex: 5) or a percentage (ex: 25%). maxUnavailable: 25% ``` ### updateStrategy 用途、影響與衝擊 - ### Claude Sonnet4 (2025/11/17) `updateStrategy` 用於控制 Kubernetes StatefulSet 或 Deployment 更新時的行為策略: ### 主要用途 * **控制 Pod 更新方式**:定義當你修改 Pod template(如更新容器映像、環境變數等)時,Kubernetes 如何逐步替換舊的 Pod ### 配置說明 * **`type`**: * `RollingUpdate`:滾動更新,逐步替換 Pod,確保服務持續可用 * `OnDelete`:僅在手動刪除 Pod 時才建立新版本的 Pod * **`rollingUpdate.maxUnavailable`**: * 滾動更新期間**允許同時不可用的最大 Pod 數量** * `25%`:表示最多 25% 的 Pod 可以同時處於更新/不可用狀態 * 可設定為絕對數字(如 `5`)或百分比(如 `25%`) ### 實際效果 以 `maxUnavailable: 25%` 為例,假設有 4 個 Pod: 1. Kubernetes 會先停止 1 個 Pod(25%) 2. 建立新版本的 Pod 3. 等待新 Pod 就緒後,再繼續下一個 4. 循環直到所有 Pod 更新完成 這確保了**更新過程中服務不會完全中斷**。 <br> --- ### RollingUpdate 觸發時機 - ### Claude Sonnet4 (2025/11/17) ### RollingUpdate 觸發時機 當你修改 StatefulSet/Deployment 的 **Pod template** 時,Kubernetes 會自動觸發滾動更新: * 更新容器映像版本(`image: app:v1.0` → `image: app:v2.0`) * 修改環境變數(`env`) * 變更資源限制(`resources.limits/requests`) * 更新 volume mount 配置 * 修改 container ports * 變更 command/args **觸發方式**: ```bash # 直接修改 YAML 後 apply kubectl apply -f deployment.yaml # 或使用 kubectl set image kubectl set image statefulset/myapp myapp=myapp:v2.0 # 或編輯 resource kubectl edit statefulset myapp ``` ### OnDelete 觸發時機 **不會自動更新**,必須**手動刪除 Pod** 才會套用新配置: ```bash # 1. 修改 StatefulSet template(不會立即更新) kubectl apply -f statefulset.yaml # 2. 手動刪除 Pod(此時才會建立使用新 template 的 Pod) kubectl delete pod myapp-0 ``` ### 關鍵差異 | 策略 | 自動更新 | 適用場景 | |------|---------|---------| | **RollingUpdate** | ✅ 是 | 需要自動化、持續部署的服務 | | **OnDelete** | ❌ 否 | 需要精確控制更新時機、避免自動重啟的關鍵服務 | <br> --- <br> ## `nodesets[].taintKubeNodes` ### taintKubeNodes 用途、影響與衝擊 - ### Claude Sonnet4 (2025/11/17) `taintKubeNodes: false` 用於控制是否在執行 Slurm nodeset pods 的 Kubernetes 節點上設置 `NoExecute` taint。 **用途說明:** - **設為 `true`**:會在執行 slurmd pods 的 K8s 節點上添加 `NoExecute` taint,這樣**其他非 Slurm 相關的 pods 會被驅逐**,確保該節點專門用於 Slurm 工作負載 - **設為 `false`** (預設值):不添加 taint,允許其他 pods 與 slurmd pods 共享該節點資源 **適用場景:** - 需要**資源隔離**或**專用節點**時設為 `true` - 希望**混合部署**、充分利用節點資源時保持 `false` <br> --- <br> # `partitions.<partition-name>` ## 案例探討 ### 將 partition 的 `DefMemPerNode` 設成 1048? (DefMemPerNode 預設為 UNLIMITED) - `DefMemPerNode` 預設為 `UNLIMITED` (i.e. 預設要求無限記憶體) - 導致:無法分配資源:請求的節點配置不可用 ``` $ srun --nodelist=c2m4-0 hostname srun: error: Unable to allocate resources: Requested node configuration is not available ``` - **API 定義** - 在 Slurm Operator 中,partition 配置透過 `NodeSetPartition` 結構定義。 - 要設定 `DefMemPerNode=2048`,需要將其添加到 `partition.config` 欄位中。 - **使用方式:** - **[方式一] 在 `nodesets` 中自定義的 `<nodeset-name>` 內設定**: ```yaml nodesets: c2m4: partition: enabled: true config: "DefMemPerNode=4096 MaxTime=24:00:00 State=UP" configMap: {} # DefMemPerNode: 4096 # MaxTime: "24:00:00" # State: UP ``` 這個 `config` 欄位會被添加到 Slurm 配置檔中該 partition 的定義行,參考位置在 `api/v1beta1/nodeset_types.go:112`。 查看設定結果: ```bash $ kubectl -n slurm exec -it pod/slurm-controller-0 -- bash # in controller pod: $ cat /etc/slurm/slurm.conf | grep -i partition ### COMPUTE & PARTITION ### NodeSet=c2m4 Feature=c2m4 PartitionName=c2m4 Nodes=c2m4 DefMemPerNode=4096 MaxTime=24:00:00 State=UP ``` - **[方式二] 在 `partitions` 中自定義的 `<partition-name>` 內設定**: ```yaml= partitions: cpu-set: enabled: true nodesets: - c2m4 config: "DefMemPerNode=4096 MaxTime=24:00:00 State=UP" configMap: {} # DefMemPerNode: 4096 # MaxTime: "24:00:00" # State: UP ``` - **使用注意:`config` vs `configMap`** ```yaml= partitions: cpu-set: enabled: true nodesets: - c2m4 config: "DefMemPerNode=4096 MaxTime=24:00:00 State=UP" # If `config` is not empty, it takes precedence. configMap: {} # DefMemPerNode: 4096 # MaxTime: "24:00:00" # State: UP ``` - 官方註解說明:If `config` is not empty, it takes precedence. - 如果 `config` 不為空值,會用 `config` 做設定,並捨棄 `configMap` - 如果 `config` 為空值,就會採用 `configMap` - 結論:`config` 和 `configMap` 只能擇一 ```yaml= config: "DefMemPerNode=4096 MaxTime=24:00:00 State=UP" configMap: {} # DefMemPerNode: 4096 # MaxTime: "24:00:00" # State: UP ``` 或: ```yaml= config: null configMap: DefMemPerNode: 4096 MaxTime: "24:00:00" State: UP ``` <br> --- --- <br> # 案例探討 ## 如何調整 MemSpecLimit 設定 <!-- http://10.78.26.44:30000/deepwiki/slurm/-/issues/8 DefMemPerCPU 和 DefMemPerNode 配置問題 http://10.78.26.44:30000/deepwiki/slurm-operator-v1.0.0-20251125/-/issues/16 如何調整 MemSpecLimit 設定? --> - ### us.anthropic.claude-sonnet-4-5-20250929-v1:0 (2025/12/10) 根據這個 Slurm Operator 專案的架構,您可以透過以下方式設定 `MemSpecLimit`: ### 方法一:透過 `configFiles` 設定 cgroup.conf(推薦) 在 `helm/slurm/values.yaml` 中使用 `configFiles` 參數來配置 `cgroup.conf`: ```yaml configFiles: cgroup.conf: | CgroupPlugin=cgroup/v2 IgnoreSystemd=yes ConstrainCores=yes ConstrainRAMSpace=yes ConstrainDevices=yes ConstrainSwapSpace=yes # 設定 MemSpecLimit,例如預留 4GB 給系統 # 這樣可以讓更多記憶體給作業使用 MemSpecLimit=4096 ``` **MemSpecLimit 說明:** - `MemSpecLimit` 的單位是 **MB(megabytes)** - 這個參數指定**預留給系統的記憶體量** - **設定較小的值** = 預留較少記憶體給系統 = **作業可用記憶體更多** - 例如: - `MemSpecLimit=4096` → 預留 4GB 給系統 - `MemSpecLimit=2048` → 預留 2GB 給系統(作業可用記憶體更多) - `MemSpecLimit=8192` → 預留 8GB 給系統(作業可用記憶體較少) ### 方法二:透過 extraConf 在 slurm.conf 中設定 在 `controller` 區段使用 `extraConfMap` 來設定: ```yaml controller: extraConfMap: # 其他配置... # 注意:MemSpecLimit 通常在 cgroup.conf 中設定 # 但也可以在 slurm.conf 的 NodeName 行中指定 ``` ### 實際操作步驟 1. **編輯 Helm values 檔案**: ```bash # 編輯您的 values.yaml 或建立一個 override 檔案 nano my-values.yaml ``` 2. **加入 cgroup 配置**: ```yaml configFiles: cgroup.conf: | CgroupPlugin=cgroup/v2 IgnoreSystemd=yes ConstrainCores=yes ConstrainRAMSpace=yes ConstrainDevices=yes ConstrainSwapSpace=yes MemSpecLimit=2048 # 根據您的需求調整 ``` 3. **更新 Helm 部署**: ```bash helm upgrade slurm ./helm/slurm \ --namespace slurm \ -f my-values.yaml ``` ### 建議配置值 - **高負載計算節點**:`MemSpecLimit=2048` (2GB) - 預留較少給系統 - **一般用途節點**:`MemSpecLimit=4096` (4GB) - 平衡配置 - **小型節點**:`MemSpecLimit=1024` (1GB) - 最大化作業可用記憶體 ### 參考文件 - [Slurm cgroup.conf 官方文檔](https://slurm.schedmd.com/cgroup.conf.html) - [Slurm slurm.conf 官方文檔](https://slurm.schedmd.com/slurm.conf.html) **注意事項:** - 調整後需要重啟相關的 Slurm 服務才會生效 - 設定值過小可能導致系統不穩定 - 建議根據實際的節點記憶體大小和工作負載來調整 <br> --- <br> ## DefMemPerCPU 和 DefMemPerNode 的用途各為何?是否會交互影響?(round-1, base: slurm-operator) <!-- http://10.78.26.44:30000/deepwiki/slurm-operator-v1.0.0-20251125/-/issues/17 DefMemPerCPU vs DefMemPerNode --> - ### Question ``` controller: # -- (map[string]string \| map[string][]string) Extra Slurm configuration lines appended to `slurm.conf`. # If `extraConf` is not empty, it takes precedence. # Ref: https://slurm.schedmd.com/slurm.conf.html extraConfMap: GresTypes: gpu DefMemPerCPU: 1024 # 每個 cpu 配置 4GB memory ... partitions: all: null cpu-set: enabled: true nodesets: - c2m4 # -- The Slurm partition configuration options added to the partition line. # Ref: https://slurm.schedmd.com/slurm.conf.html#SECTION_PARTITION-CONFIGURATION config: null # -- (map[string]string \| map[string][]string) The Slurm partition configuration options added to the partition line. # If `config` is not empty, it takes precedence. # Ref: https://slurm.schedmd.com/slurm.conf.html#SECTION_PARTITION-CONFIGURATION configMap: State: UP Default: "YES" MaxTime: UNLIMITED DefMemPerNode: 1024 ``` DefMemPerCPU 和 DefMemPerNode 的用途各為何?是否會交互影響? - ### us.anthropic.claude-sonnet-4-5-20250929-v1:0 (2025/12/10) 基於我對 Slurm 配置的了解和代碼結構分析,讓我為您說明這兩個參數: ### **DefMemPerCPU 與 DefMemPerNode 的用途說明** #### **DefMemPerCPU** - **用途**:設定**每個 CPU 核心**預設分配的記憶體大小(單位:MB) - **作用範圍**:全域設定,在 `controller.extraConfMap` 中配置 - **適用場景**:當作業以 CPU 數量為基礎申請資源時(例如:`salloc -c 4`) #### **DefMemPerNode** - **用途**:設定**每個節點**預設分配的記憶體大小(單位:MB) - **作用範圍**:Partition 層級設定,在 `partitions.<name>.configMap` 中配置 - **適用場景**:當作業以節點數量為基礎申請資源時(例如:`salloc -N 1`) --- ### **交互影響與優先順序** #### **1. 兩者會互相影響** 根據 Slurm 的設計邏輯: - **不能同時設定兩者**:在同一個 partition 配置中,`DefMemPerCPU` 和 `DefMemPerNode` 是**互斥**的 - **優先順序規則**: - 如果 **partition 設定了 `DefMemPerNode`**,則該 partition **忽略全域的 `DefMemPerCPU`** - 如果 **partition 沒有設定 `DefMemPerNode`**,則**繼承全域的 `DefMemPerCPU`** #### **2. 您的配置分析** ```yaml controller: extraConfMap: GresTypes: gpu DefMemPerCPU: 1024 # ← 全域設定:每個 CPU 1GB partitions: cpu-set: configMap: State: UP Default: "YES" MaxTime: UNLIMITED DefMemPerNode: 1024 # ← partition 設定:每個節點 1GB ``` **問題點**: - 在 `cpu-set` partition 中,**`DefMemPerNode: 1024` 會覆蓋全域的 `DefMemPerCPU: 1024`** - 這意味著: - **無論節點有多少個 CPU**,該 partition 的作業預設只能使用 **1GB 記憶體** - 這可能**不符合您的預期**,特別是多核心節點 --- ### **建議做法** #### **方案 1:統一使用 DefMemPerCPU(推薦)** ```yaml controller: extraConfMap: GresTypes: gpu DefMemPerCPU: 1024 # 每個 CPU 1GB partitions: cpu-set: configMap: State: UP Default: "YES" MaxTime: UNLIMITED # ✅ 移除 DefMemPerNode,讓 partition 繼承全域設定 ``` **優點**: - 記憶體分配與 CPU 數量成正比,更符合多核心場景 - 配置一致性高 #### **方案 2:使用 DefMemPerNode(特殊需求)** ```yaml controller: extraConfMap: GresTypes: gpu # ✅ 不設定 DefMemPerCPU partitions: cpu-set: configMap: State: UP Default: "YES" MaxTime: UNLIMITED DefMemPerNode: 4096 # ← 根據實際節點記憶體設定(例如:4GB) ``` **適用場景**: - 節點配置固定,不關心 CPU 數量 - 作業通常以節點為單位申請資源 --- ### **總結** | 參數 | 作用範圍 | 計算基礎 | 適用場景 | |------|---------|---------|---------| | **DefMemPerCPU** | 全域 | CPU 數量 | 多核心作業 | | **DefMemPerNode** | Partition | 節點數量 | 固定節點配置 | **關鍵提醒**: 1. **兩者不可同時生效**於同一個 partition 2. **Partition 的 `DefMemPerNode` 會覆蓋全域的 `DefMemPerCPU`** 3. **建議選擇其中一種策略**,並在所有 partition 保持一致 如需調整配置,請告訴我您的節點規格(CPU 核心數、記憶體大小),我可以幫您計算合適的數值。 <br> --- <br> ## DefMemPerCPU 和 DefMemPerNode 的用途各為何?是否會交互影響?(round-2, base: slurm) <!-- http://10.78.26.44:30000/deepwiki/slurm/-/issues/9 DefMemPerCPU 和 DefMemPerNode 的用途各為何?是否會交互影響? --> - ### us.anthropic.claude-sonnet-4-5-20250929-v1:0 (2025/12/10) ### **DefMemPerCPU 和 DefMemPerNode 的用途和交互影響** #### **用途:** 1. **DefMemPerCPU**: - 設定每個**可用 CPU** 的預設記憶體大小(MB) - 適用於按 CPU 分配資源的情況(`SelectType=select/cons_tres`) - 當工作請求記憶體時,如果未指定 `--mem` 或 `--mem-per-cpu`,將使用此預設值 2. **DefMemPerNode**: - 設定每個**節點**的預設記憶體大小(MB) - 適用於整個節點分配的情況(`SelectType=select/linear`) - 通常與資源過度訂閱(`OverSubscribe=yes/force`)一起使用 #### **交互影響:** **⚠️ 這兩個參數是互斥的(mutually exclusive)** 根據 `doc/man/man5/slurm.conf.5:1319-1320` 和 `doc/man/man5/slurm.conf.5:1392-1393`: ``` DefMemPerCPU, DefMemPerGPU and DefMemPerNode are mutually exclusive. ``` **在配置檔中只能設定其中一個**: - 如果同時設定,Slurm 會報錯或忽略其中一個 - 從原始碼 `src/common/read_config.c:1303` 可見: ``` error("DefMemPerCPU ignored, since it's mutually exclusive with DefMemPerNode"); ``` **建議設定方式:** - **CPU 級資源調度**:使用 `DefMemPerCPU`(推薦用於 cons_tres) - **節點級資源調度**:使用 `DefMemPerNode`(用於 select/linear) <br> ### 實際測試 - ### Case1 ``` $ kubectl -n slurm logs pod/slurm-controller-0 | grep -i defmem [2025-12-10T06:47:04.978] error: DefMemPerCPU ignored, since it's mutually exclusive with DefMemPerNode ``` ``` tj_tsai@slurm-login-slinky-777cb8f68f-r2pt5:/work$ srun -p cpu-set hostname srun: error: DefMemPerCPU ignored, since it's mutually exclusive with DefMemPerNode srun: Requested partition configuration not available now srun: job 148 queued and waiting for resources srun: job 148 has been allocated resources c2m4-0 ``` - ### Case2: 同時使用`DefMemPerGPU` 和 `DefMemPerNode` 沒有發生衝突 ``` partitions: a30-set: ... # If `config` is not empty, it takes precedence. # Ref: https://slurm.schedmd.com/slurm.conf.html#SECTION_PARTITION-CONFIGURATION configMap: State: UP Default: "NO" MaxTime: UNLIMITED DefMemPerGPU: 4096 DefMemPerNode: 4096 ``` ``` $ scontrol show partition PartitionName=a30-set AllowGroups=ALL AllowAccounts=ALL AllowQos=ALL AllocNodes=ALL Default=NO QoS=N/A DefaultTime=NONE DisableRootJobs=NO ExclusiveUser=NO ExclusiveTopo=NO GraceTime=0 Hidden=NO MaxNodes=UNLIMITED MaxTime=UNLIMITED MinNodes=0 LLN=NO MaxCPUsPerNode=UNLIMITED MaxCPUsPerSocket=UNLIMITED NodeSets=c4m16gt1 Nodes=c4m16gt1-0 PriorityJobFactor=1 PriorityTier=1 RootOnly=NO ReqResv=NO OverSubscribe=NO OverTimeLimit=NONE PreemptMode=OFF State=UP TotalCPUs=88 TotalNodes=1 SelectTypeParameters=NONE JobDefaults=DefMemPerGPU=4096 DefMemPerNode=4096 MaxMemPerNode=UNLIMITED TRES=cpu=8,mem=515856M,node=1,billing=8,gres/gpu=1 ``` - ### us.anthropic.claude-sonnet-4-5-20250929-v1:0 (2025/12/10) ### **修正說明:DefMemPerGPU 和 DefMemPerNode 可以共存** 感謝您的指正!經過仔細檢查原始碼 `src/common/read_config.c:1280-1304`,我發現: #### **互斥關係的真相:** **只有這兩個組合是互斥的:** 1. ❌ `DefMemPerCPU` ⚔️ `DefMemPerNode` 2. ✅ `DefMemPerGPU` ✅ `DefMemPerNode` **可以同時使用** #### **原始碼證據:** 從 `src/common/read_config.c:1280-1304`: ```c // DefMemPerGPU 是獨立處理的(第1280-1289行) if (s_p_get_uint64(&def_mem_per_gpu, "DefMemPerGPU", tbl) || ...) { job_defaults = xmalloc(sizeof(job_defaults_t)); job_defaults->type = JOB_DEF_MEM_PER_GPU; // ... } // DefMemPerNode 和 DefMemPerCPU 是互斥的(第1291-1304行) if (!s_p_get_uint64(&p->def_mem_per_cpu, "DefMemPerNode", tbl) && ...) { // 如果沒有設定 DefMemPerNode,才檢查 DefMemPerCPU if (s_p_get_uint64(&p->def_mem_per_cpu, "DefMemPerCPU", tbl) || ...) { p->def_mem_per_cpu |= MEM_PER_CPU; } } else if (s_p_get_uint64(&tmp_64, "DefMemPerCPU", tbl) || ...) { error("DefMemPerCPU ignored, since it's mutually exclusive with DefMemPerNode"); } ``` #### **您的配置完全合法:** ```yaml DefMemPerGPU: 4096 # ✅ 每個 GPU 的預設記憶體 DefMemPerNode: 4096 # ✅ 每個節點的預設記憶體 ``` 這兩個參數會同時生效,分別控制: - **DefMemPerGPU**:GPU 相關工作的記憶體預設值 - **DefMemPerNode**:節點層級的記憶體預設值 **我之前的回答錯誤,抱歉造成混淆!** 🙏 <br> --- <br> ## DefMemPerCPU 和 DefMemPerNode 的預設大小各為多少? <!-- http://10.78.26.44:30000/deepwiki/slurm/-/issues/9 DefMemPerCPU 和 DefMemPerNode 的用途各為何?是否會交互影響? --> - ### us.anthropic.claude-sonnet-4-5-20250929-v1:0 (2025/12/10) 根據 Slurm 原始碼的配置檔案說明和實作: ### **預設值:** 1. **DefMemPerCPU**:**0** (無預設限制) - 來源:`doc/man/man5/slurm.conf.5:1309-1315` - 未設定時,記憶體分配由系統自動計算 2. **DefMemPerNode**:**0** (無預設限制) - 來源:`doc/man/man5/slurm.conf.5:1381-1388` - 未設定時,記憶體分配由系統自動計算 ### **實際行為(當設為 0 時):** 從 `src/common/read_config.c:1287-1303` 可見處理邏輯: ```c if (conf->def_mem_per_cpu == 0) { // 當 DefMemPerCPU=0 時,Slurm 會自動計算預設記憶體 // 計算方式:節點的 RealMemory / CPU數量 } ``` **重點摘要:** - 兩者預設都是 **0 MB**(未限制) - 設為 0 時,Slurm 會根據節點實際記憶體和 CPU 數量自動分配 - 建議根據實際硬體資源明確設定這些值,避免資源過度使用 <br> --- <br> ## helm/slurm/values.yaml 中的 partition 是怎樣被處理的? <!-- http://10.78.26.44:30000/deepwiki/slurm-operator-v1.0.0-20251125/-/issues/34 helm/slurm/values.yaml 中的 partition 是怎樣被處理的? --> - ### us.anthropic.claude-sonnet-4-5-20250929-v1:0 (2025/12/31) 現在我已經完整追蹤了整個流程。讓我整理一下: ### **Helm values.yaml 中 partition 配置的處理流程** #### **1. 來源定義 (values.yaml)** 在 `helm/slurm/values.yaml` 中,partition 可以在兩個地方定義: ##### **A. NodeSet 層級的 partition** (第 633-645 行) ```yaml nodesets: slinky: partition: enabled: true config: null configMap: {} # State: UP # MaxTime: UNLIMITED ``` ##### **B. 全域 partition 定義** (第 698-717 行) ```yaml partitions: all: enabled: true nodesets: - ALL config: null configMap: State: UP Default: "YES" MaxTime: UNLIMITED ``` --- #### **2. Helm Template 處理階段** ##### **A. NodeSet CR 生成** (`helm/slurm/templates/nodeset/nodeset-cr.yaml:47-53`) ```yaml {{- with $nodeset.partition }} partition: enabled: {{ $nodeset.partition.enabled | default false }} {{- if (include "slurm.worker.partitionConfig" $nodeset.partition) }} config: {{ include "slurm.worker.partitionConfig" $nodeset.partition }} {{- end }} {{- end }} ``` 每個 NodeSet CR 會包含其自己的 partition 配置。 ##### **B. Controller extraConf 生成** (`helm/slurm/templates/controller/_helpers.tpl:30-72`) > https://github.com/SlinkyProject/slurm-operator/blob/main/helm/slurm/templates/controller/_helpers.tpl#L37-L72 在 `slurm.controller.extraConf` helper 函數中: 1. **收集所有啟用的 NodeSet** (第 37-42 行) 2. **處理 partitions 定義** (第 43-70 行): - 驗證 partition 中引用的 nodesets 是否存在 - 將 "ALL" 展開為所有 NodeSet - 生成 `PartitionName=xxx Nodes=xxx` 配置行 - 將配置附加到 `extraConf` **範例生成的配置行** (第 60 行): ```go PartitionName=all Nodes=slinky State=UP Default=YES MaxTime=UNLIMITED ``` ##### **C. Controller CR 生成** (`helm/slurm/templates/controller/controller-cr.yaml:50-53`) ```yaml {{- if (include "slurm.controller.extraConf" .) }} extraConf: | {{- include "slurm.controller.extraConf" . | nindent 4 }} {{- end }} ``` 全域 partition 配置會寫入 Controller CR 的 `extraConf` 欄位。 --- #### **3. Operator 處理階段** ##### **A. Controller Reconciler** (`internal/controller/controller/controller_sync.go:57-73`) 當 Controller CR 被創建或更新時: 1. Reconciler 會呼叫 `BuildControllerConfig()` 函數 2. 生成包含 `slurm.conf` 的 ConfigMap ##### **B. 生成 slurm.conf** (`internal/builder/controller_config.go:150-279`) **處理 NodeSet partition** (第 244-271 行): > https://github.com/SlinkyProject/slurm-operator/blob/main/internal/builder/controller_config.go#L256-L279 ```go for _, nodeset := range nodesetList.Items { name := nodeset.Name // 生成 NodeSet 行 nodesetLine := []string{ fmt.Sprintf("NodeSet=%v", name), fmt.Sprintf("Feature=%v", name), } conf.AddProperty(config.NewPropertyRaw(nodesetLineRendered)) // 如果 NodeSet 的 partition 啟用,生成 PartitionName 行 partition := nodeset.Spec.Partition if !partition.Enabled { continue } partitionLine := []string{ fmt.Sprintf("PartitionName=%v", name), fmt.Sprintf("Nodes=%v", name), partition.Config, } conf.AddProperty(config.NewPropertyRaw(partitionLineRendered)) } ``` **附加 extraConf** (第 273-276 行): ```go extraConf := controller.Spec.ExtraConf conf.AddProperty(config.NewPropertyRaw("#")) conf.AddProperty(config.NewPropertyRaw("### EXTRA CONFIG ###")) conf.AddProperty(config.NewPropertyRaw(extraConf)) ``` 這裡會包含從 Helm template 生成的全域 partition 配置。 --- #### **4. 最終存放位置** ##### **A. ConfigMap 名稱** (`api/v1beta1/controller_keys.go:95-100`) ```go func (o *Controller) ConfigKey() types.NamespacedName { return types.NamespacedName{ Name: fmt.Sprintf("%s-config", o.Name), Namespace: o.Namespace, } } ``` **範例**: 如果 Controller 名稱是 `my-slurm`,ConfigMap 名稱會是 `my-slurm-config` ##### **B. ConfigMap 內容結構** ```yaml apiVersion: v1 kind: ConfigMap metadata: name: <controller-name>-config namespace: <namespace> data: slurm.conf: | # ... 基本配置 ... ### COMPUTE & PARTITION ### # NodeSet 層級的 partition NodeSet=slinky Feature=slinky PartitionName=slinky Nodes=slinky <config> ### EXTRA CONFIG ### # 全域 partition (從 values.yaml 的 partitions) PartitionName=all Nodes=ALL State=UP Default=YES MaxTime=UNLIMITED cgroup.conf: | # ... cgroup 配置 ... ``` --- #### **完整流程圖** ``` values.yaml ├─ nodesets.slinky.partition.config │ └─> NodeSet CR (partition.config) │ └─> 寫入 slurm.conf 的 "PartitionName=slinky ..." │ └─ partitions.all.configMap └─> Controller CR (extraConf) └─> 寫入 slurm.conf 的 "### EXTRA CONFIG ###" 最終存放: ConfigMap (<controller-name>-config) └─ data.slurm.conf ├─ NodeSet partition 配置 └─ 全域 partition 配置 (在 EXTRA CONFIG 區段) ``` --- #### **關鍵差異** | 項目 | NodeSet partition | 全域 partitions | |------|------------------|----------------| | **定義位置** | `nodesets.<name>.partition` | `partitions.<name>` | | **寫入 CR** | NodeSet CR 的 `partition` 欄位 | Controller CR 的 `extraConf` 欄位 | | **寫入 slurm.conf** | 在 COMPUTE & PARTITION 區段 | 在 EXTRA CONFIG 區段 | | **用途** | 為單個 NodeSet 自動生成 partition | 定義跨多個 NodeSet 的 partition | | **NodeSet 引用** | 自動使用該 NodeSet 名稱 | 需明確指定 nodesets 列表 | --- #### **總結** 1. **Helm Template** 階段將 partition 配置分發到對應的 CR (NodeSet 或 Controller) 2. **Operator** 讀取這些 CR 並生成 `slurm.conf` 3. **最終配置** 存放在 `<controller-name>-config` ConfigMap 中 4. **slurmctld Pod** 會 mount 這個 ConfigMap 到 `/etc/slurm/slurm.conf` 這樣的設計讓 partition 配置既可以自動化 (NodeSet partition),也可以手動靈活定義 (全域 partitions)。 <br> --- <br> <br> {%hackmd vaaMgNRPS4KGJDSFG0ZE0w %}