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 %}