---
# System prepended metadata

title: values.yaml 總覽
tags: [k8s, slurm, v1.0.0-rc1, app, SlinkyProject, Kubernetes, upgrade]

---

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