---
# System prepended metadata

title: '[API] Slurm CLI (Slurm client: sinfo, scontrol, sacctmgr) (not RESTful API)'
tags: [scontrol, sinfo, k8s, slurm, Slurm CLI, app, SlinkyProject, sacctmgr, Kubernetes, SlinkyProject / CLI & REST API]

---

[API] Slurm CLI (Slurm client: sinfo, scontrol, sacctmgr) (not RESTful API)
===
###### tags: `SlinkyProject / CLI & REST API`
###### tags: `Kubernetes`, `k8s`, `app`, `slurm`, `SlinkyProject`, `sinfo`, `scontrol`, `sacctmgr`, `Slurm CLI`

<br>

[TOC]

<br>

## Slurm 溝通方式
- **CLI**：Slurm client →（Slurm RPC）→ slurmctld / slurmdbd
- **REST**：HTTP client → (HTTP/HTTPS) → slurmrestd →（Slurm RPC）→ slurmctld / slurmdbd
- **補充說明**
    - **Slurm RPC**：
        - CLI 透過 `libslurm` 這層 API 函式庫，對 slurmctld/slurmdbd 發出 Slurm RPC 請求
    - **slurmrestd**：
        - 對外是 HTTP/HTTPS 介面
        - 內部把 JSON 請求轉成 Slurm RPC
        - **stateless**：不在 request 間保存狀態
        - **同步**：每個請求會等 controller（slurmctld 或 slurmdbd）處理完才回 HTTP response
    - **sinfo / scontrol / squeue / srun / sbatch**
        對 **slurmctld**（控制器）發 RPC 溝通，用於查詢/提交/控制工作與叢集狀態
    - **sacct / sacctmgr**
        - **`sacctmgr`**：對 **slurmdbd** 發 RPC，存取/管理 accounting 資料
        - **`sacct`**：顯示 accounting 資料（來源可能是 slurmdbd 或 job accounting log，取決於設定）
- **參考連接**
    - [REST API Details - Slurm Workload Manager - SchedMD](https://slurm.schedmd.com/rest.html)
    - [slurmrestd(8) — Arch manual pages](https://man.archlinux.org/man/slurmrestd.8.en)

<br>

---

<br>

## 安裝 Slurm CLI

### Ubuntu 環境
- ### 目標
    在容器裡，直接操作 slurm CLI (而不是透過 restful API )
- ### 安裝方式
    ```
    apt install slurm-client
    ```
    - ### 檢視套件資訊與版本
        ```
        $ apt show slurm-client
        Package: slurm-client
        Version: 24.11.5-4
        Priority: optional
        Section: admin
        Source: slurm-wlm
        Maintainer: Debian HPC Team <debian-hpc@lists.debian.org>
        Installed-Size: 2227 kB
        Depends: libc6 (>= 2.38), liblua5.1-0 (>= 5.1.3), liblz4-1 (>= 0.0~r130), libreadline8t64 (>= 6.0), slurm-wlm-basic-plugins (= 24.11.5-4), munge, ucf
        Conflicts: sinfo (<< 0.0.47-4)
        Homepage: http://slurm.schedmd.com
        Tag: uitoolkit::ncurses
        Download-Size: 842 kB
        APT-Manual-Installed: yes
        APT-Sources: http://deb.debian.org/debian trixie/main amd64 Packages
        Description: Slurm client side commands
        ```
    - ### 指令路徑
        ```
        $ which sinfo
        /usr/bin/sinfo

        $ type -a sinfo
        sinfo is /usr/bin/sinfo
        sinfo is /bin/sinfo
        ```
- ### 設定組態 ＆ 認證資訊
    ```
    slurm:slurm  755  slurm.conf      (連線用)
    slurm:slurm  600  slurm.key       (認證用)
    slurm:slurm  600  jwt_hs256.key   (認證用)(選用)
    ```
    (後面會介紹如何設定)


<br>

---

<br>


## 將 Slurm CLI 的連線，串接到目標 K8s

### 需要準備的檔案
> - `/etc/slurm/slurm.key`  (認證用)
> - `/etc/slurm/jwt_hs256.key`  (認證用)(選用)
> - `/etc/slurm/slurm.conf`  (連線用)

<br>

### 準備 `/etc/slurm/slurm.key` & `/etc/slurm/jwt_hs256.key`
> - key 沒有匹配，將直接導致 authentication error
> - 可透過 md5sum 指令檢查，看 server & client 兩邊的 key 內容是否有一致性

- ### export secrets
    - ### K8s ststus
        ```
        $ kubectl -n slurm get pod,svc
        NAME                                      READY   STATUS    RESTARTS   AGE
        ...
        pod/slurm-accounting-0                    1/1     Running   0          40m
        pod/slurm-controller-0                    3/3     Running   0          40m
        ...

        NAME                          TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
        ...
        service/slurm-accounting      ClusterIP      10.97.148.183   <none>        6819/TCP       40m
        service/slurm-controller      ClusterIP      10.99.227.20    <none>        6817/TCP       40m
        ...
        ```
        - ### md5sum 檢查
            > 先把 md5sum 記錄下來，比對後面的 md5sum 是否一致
            ```bash
            # slurm.key
            kubectl -n slurm exec pod/slurm-controller-0 \
              -- cat /etc/slurm/slurm.key | md5sum

            # jwt_hs256.key
            kubectl -n slurm exec pod/slurm-controller-0 \
              -- cat /etc/slurm/jwt_hs256.key | md5sum
            ```
        - ### wc 檢查
            ```bash
            # slurm.key
            kubectl -n slurm exec pod/slurm-controller-0 \
              -- cat /etc/slurm/slurm.key | wc
            # expected:       0       6    1024

            # jwt_hs256.key
            kubectl -n slurm exec pod/slurm-controller-0 \
              -- cat /etc/slurm/jwt_hs256.key | wc
            # expected:       0       6    1024
            ```
        - 其他比對指令：`xxd`

    - ### export `slurm.key`
        ```
        $ kubectl -n slurm get secret/slurm-auth-slurm -o jsonpath='{.data.slurm\.key}' | base64 -d > slurm.key
        $ md5sum slurm.key
        ```
        - ### [必要] 檔案權限必須是 600
            ```
            # sackd 啟動失敗
            sackd: fatal: auth/slurm: key file is insecure: '/etc/slurm/slurm.key' mode=0644
            ```
            - 修正方式：`chmod 600 /etc/slurm/slurm.key`
        - ### [必要] 檔案擁有者必須是 `slurm:slurm`
            > 與 sackd 啟動者必須是相同身份，不限定一定要 `401:401`
            ```
            # sackd 啟動失敗
            sackd: debug:  auth/slurm: init_internal: loading key: `/etc/slurm/slurm.key`
            sackd: debug:  create_mmap_buf: Failed to open file `/etc/slurm/slurm.key`, Permission denied
            sackd: fatal: auth/slurm: Could not load key file (/etc/slurm/slurm.key)
            ```
            - 修正方式：`chown slurm:slurm /etc/slurm/slurm.key`
    - ### export `jwt_hs256.key`
        ```
        $ kubectl -n slurm get secret/slurm-auth-jwths256 -o jsonpath='{.data.jwt_hs256\.key}' | base64 -d > jwt_hs256.key
        $ md5sum jwt_hs256.key
        ```
        - 預期設定應同 `slurm.key`

    <br>

### 準備 `/etc/slurm/slurm.conf`

```conf=
# Cluster 識別
ClusterName=slurm

# Controller 連線設定
# -------------------
# SlurmctldHost=slurm-controller.slurm.svc.cluster.local
SlurmctldHost=127.0.0.1
SlurmctldPort=6817

# 認證設定 (關鍵安全配置)
# -------------------
AuthType=auth/slurm
# 選用：AuthInfo=use_client_ids
# 效果：執行 scontrol|sacctmgr 會有底下 log
# sackd: debug2: _group_cache_lookup_internal: no entry found for uid=0
# sackd: debug2: _group_cache_lookup_internal: found valid entry for user=root
AuthInfo=use_client_ids
CredType=cred/slurm

# 替代認證方式 (JWT)(選用)
# --------------------
# AuthAltTypes=auth/jwt
# AuthAltParameters=jwt_key=/etc/slurm/jwt_hs256.key

# Accounting 設定
# -------------------
AccountingStorageType=accounting_storage/slurmdbd
# AccountingStorageHost=slurm-accounting.slurm.svc.cluster.local
AccountingStorageHost=127.0.0.1
AccountingStoragePort=6819
# AccountingStorageEnforce=associations,limits,qos,safe

# 日誌設定
# -------------------
# SlurmctldLogFile=/var/log/slurm/slurmctld.log
# SlurmdLogFile=/var/log/slurm/slurmd.log

# 必要的額外配置
# -------------------
SlurmUser=slurm
CommunicationParameters=block_null_hash
```
- ### 影響範圍
    - 缺少 `SlurmUser=slurm` 設定，將會造成：
        ```
        $ su -s /bin/bash -c 'sacctmgr -vvvv list user' slurm
        sacctmgr: debug3: _sack_try_connection: connect() failed for /run/slurm/sack.socket: Connection refused
        sacctmgr: debug3: _sack_try_connection: connect() failed for /run/slurmctld/sack.socket: No such file or directory
        sacctmgr: debug3: _sack_try_connection: connect() failed for /run/slurmdbd/sack.socket: No such file or directory
        sacctmgr: error: failed to connect to any sack sockets
        sacctmgr: error: create_external: failed to create token
        sacctmgr: error: slurm_buffers_pack_msg: auth_g_create: REQUEST_PERSIST_INIT has authentication error
        sacctmgr: error: slurm_persist_conn_open: failed to send persistent connection init message to 127.0.0.1:6819
        sacctmgr: error: Sending PersistInit msg: Protocol authentication error
        ```
- ### 使用 JWT 認證（替代方案 (尚未驗證可行性)
    ```conf
    # 只使用 JWT 認證
    AuthType=auth/jwt
    AuthAltTypes=auth/jwt
    AuthAltParameters=jwt_key=/etc/slurm/jwt_hs256.key
    ```

<br>

---

<br>

### 將 K8s service 的 slurm-controller & slurm-accounting，串接到本地端的 127.0.0.1:6817 & 127.0.0.1:6819

#### local / terminal1
```
# service/slurm-controller 6817
# service/slurm-accounting 6819
$ ssh Tj_Tsai@10.78.26.162 \
  -L 127.0.0.1:6817:10.99.227.20:6817 \
  -L 127.0.0.1:6819:10.97.148.183:6819
```

#### local / terminal2
- ### image
    - **python image (需要安裝 sackd)**
        ```
        $ docker run -it \
          -v /home/tj/workspace/k8s/slinky/iam-to-slurm-sync-service/work:/work \
          --network host \
          python:3.11-slim \
          bash
        ```
    - **使用 slinky login image**
        ```
        $ docker run -it \
          -v /home/tj/workspace/k8s/slinky/iam-to-slurm-sync-service/work:/work \
          --network host \
          --entrypoint="" \
          ghcr.io/slinkyproject/login:25.11-ubuntu24.04 \
          bash
        ```
- ### 在容器中操作
    ```bash=
    # 在容器中執行
    apt update;  apt install \
      --no-install-recommends -y \
      gcc nano tree netcat-openbsd slurm-client sackd
    # tools:
    # - gcc:            ?
    # - nano:           text editor
    # - tree:           file explorer
    # - netcat-openbsd: test connection (nc command)
    # - slurm-client:   Slurm CLI
    # - sackd:          Slurm Auth & Cred Kiosk Daemon

    # 測試連線
    # $ nc -zv slurm-controller.slurm.svc.cluster.local 6817
    nc -zv 127.0.0.1 6817
    # Connection to 127.0.0.1 6817 port [tcp/*] succeeded!
 
    # $ nc -zv slurm-accounting.slurm.svc.cluster.local 6819
    nc -zv 127.0.0.1 6819
    # Connection to 127.0.0.1 6819 port [tcp/*] succeeded!

    # 新增 使用者 slurm
    # - uid 和 gid 不一定要 401
    # - 安裝完 slurm-client 套件後，就會有 slurm 使用者和群組：
    #   - cat /etc/group | grep slurm
    #     slurm:x:64030:
    #   - cat /etc/passwd | grep slurm
    #     slurm:x:64030:64030::/nonexistent:/usr/sbin/nologin
    # ---
    # groupadd -g 401 slurm
    # useradd -u 401 -g slurm -s /bin/bash -d /var/lib/slurm slurm
    # su -s /bin/bash -c 'id' slurm
    # ---
    
    # - `chmod 600 /etc/slurm/slurm.key`
    #   sackd: fatal: auth/slurm: key file is insecure: '/etc/slurm/slurm.key' mode=0644
    mkdir -p /etc/slurm
    cp /work/* /etc/slurm
    chmod 755 /etc/slurm/slurm.conf
    chmod 600 /etc/slurm/slurm.key
    chmod 600 /etc/slurm/jwt_hs256.key
    ls -ls /etc/slurm/

    # 變更檔案所有者
    # chown 401:401 /etc/slurm/* -R
    # 
    # - `chown slurm:slurm /etc/slurm/slurm.key`
    #   sackd: debug:  create_mmap_buf: Failed to open file `/etc/slurm/slurm.key`, Permission denied
    #   sackd: fatal: auth/slurm: Could not load key file (/etc/slurm/slurm.key)
    chown slurm:slurm /etc/slurm/* -R
    ls -ls /etc/slurm/

    # 啟動 sackd
    mkdir -p /run/slurm
    chown slurm:slurm /run/slurm
    chmod 755 /run/slurm

    su -s /bin/bash -c '
      export SLURM_CONF=/etc/slurm/slurm.conf
      sackd -vvv -f /etc/slurm/slurm.conf 2>&1 | tee /tmp/sackd.log
    ' slurm
    
    # ???
    su -s /bin/bash -c '
      export SLURM_CONF=/etc/slurm/slurm.conf
      export RUNTIME_DIRECTORY=/run/slurm
      sackd -D -vvv -f /etc/slurm/slurm.conf
    ' slurm

    
    
    # 成功情況：
    # ---
    # $ ps -aux | grep sackd
    # root        1104  0.0  0.0 679416  8536 ?        Sl   10:08   0:00 sackd -v
    # ---
    
    # 重新測試 sackd
    # $ kill 1104
    
    
    # [測試存取] 在容器中以 slurm 使用者執行
    # ---------------------------------
    # 測試連線
    $ su -s /bin/bash -c 'sacctmgr show config' slurm
    # 列出使用者
    $ su -s /bin/bash -c 'sacctmgr -vvvv list user' slurm
    # 列出帳號
    $ su - slurm -c "sacctmgr list account -n"
    $ su -s /bin/bash -c 'scontrol show partitions' slurm
    ```
- ### 備註
    - ### 預設路徑
        > 不用特別加，也能 work
        - `RUNTIME_DIRECTORY=/run/slurm`
        - `SLURM_CONF=/etc/slurm/slurm.conf`
        - `SLURM_JWT_KEY=/etc/slurm/jwt_hs256.key`
    - ### 能使用 root 身份啟動 sackd
        > - 會有警告訊息：`sackd: warning: sackd running as root instead of SlurmUser(slurm)`
        > - 建議使用使用 SlurmUser(slurm)
        
        ```
        root@test-sackd:/data# sackd -D -vvv -f /etc/slurm/slurm.conf
        sackd: debug:  _establish_config_source: config will load from file
        sackd: debug2: _establish_config_source: using config_file=/etc/slurm/slurm.conf (provided)
        sackd: debug:  slurm_conf_init: using config_file=/etc/slurm/slurm.conf
        sackd: debug:  Reading slurm.conf file: /etc/slurm/slurm.conf
        sackd: warning: sackd running as root instead of SlurmUser(slurm) <---
        sackd: debug:  _plugrack_foreach: serializer plugin type:serializer/json path:(null)
        sackd: debug:  auth/slurm: init: running as daemon
        sackd: debug:  auth/slurm: init_internal: loading key: `/etc/slurm/slurm.key`
        sackd: debug:  auth/slurm: init: loaded: internal=true, use_client_ids=true
        sackd: debug:  hash/k12: init: init: KangarooTwelve hash plugin loaded
        sackd: running
        ```

    - ### 能使用 root 身份執行 `scontrol` & `sacctmgr`
        - Termianl-1
            ```
            $ su -s /bin/bash -c '
                  export SLURM_CONF=/etc/slurm/slurm.conf
                  export RUNTIME_DIRECTORY=/run/slurm
                  sackd -D -vvv -f /etc/slurm/slurm.conf
                ' slurm
            sackd: debug:  _establish_config_source: config will load from file
            sackd: debug2: _establish_config_source: using config_file=/etc/slurm/slurm.conf (provided)
            sackd: debug:  slurm_conf_init: using config_file=/etc/slurm/slurm.conf
            sackd: debug:  Reading slurm.conf file: /etc/slurm/slurm.conf
            sackd: debug:  _plugrack_foreach: serializer plugin type:serializer/json path:(null)
            sackd: debug:  auth/slurm: init: running as daemon
            sackd: debug:  auth/slurm: init_internal: loading key: `/etc/slurm/slurm.key`
            sackd: debug:  auth/slurm: init: loaded: internal=true, use_client_ids=true
            sackd: debug:  hash/k12: init: init: KangarooTwelve hash plugin loaded
            sackd: running
            sackd: debug2: _group_cache_lookup_internal: no entry found for uid=64030
            sackd: debug2: _group_cache_lookup_internal: found valid entry for user=slurm
            sackd: debug2: _group_cache_lookup_internal: no entry found for uid=0
            sackd: debug2: _group_cache_lookup_internal: found valid entry for user=root <---
            sackd: debug2: _group_cache_lookup_internal: found valid entry for user=root <---
            sackd: debug2: _group_cache_lookup_internal: found valid entry for user=root <---
            ```
        - Termianl-2
            ```
            root@test-sackd:/tmp# sacctmgr list account -n
            ```

<br>

---

<br>

## 討論
### `apt install slurm-client` 該套件能在 github 上找到？
- ### gpt-5.2 (2026/01/09)
    可以，但要先分清楚「`slurm-client` 這個 apt 套件」跟「Slurm 原始碼」是兩件事：

    * **Slurm（上游原始碼）**：在 GitHub 上，Repo 是 **SchedMD/slurm**。([GitHub][20260109-A-1])
      （SchedMD 官方下載頁也直接提供 `git clone https://github.com/SchedMD/slurm.git`。） ([SchedMD][20260109-A-2])

    * **`apt install slurm-client`（Ubuntu/Debian 的二進位套件）**：這不是一個「獨立的 GitHub 專案」，而是由發行版的**source package** 打包產生的。

      * 在 **Ubuntu**，它來自 Launchpad 上的 **source package：`slurm-wlm`**，其中就包含 `slurm-client`（client side commands）。([Launchpad][20260109-A-3])
      * 在 **Debian**，打包用的 Git 倉庫在 **Debian Salsa**（不是 GitHub）。([Debian Packages][20260109-A-4])

    如果你要在你的機器上快速確認「這個套件是從哪個 source package 來的」，可以用：

    ```bash
    apt show slurm-client | sed -n '1,80p'
    apt-cache showsrc slurm-wlm | sed -n '1,120p'
    ```

    如果你想拿到「Ubuntu 打包的原始碼（含 debian/ 打包目錄）」：

    ```bash
    # 需要啟用 deb-src
    sudo apt-get source slurm-wlm
    ```

    總結：**Slurm 本體在 GitHub（SchedMD/slurm），但 `slurm-client` 這個 apt 套件的「打包來源」主要在 Ubuntu Launchpad / Debian Salsa，而不是 GitHub。**

    [20260109-A-1]: https://github.com/SchedMD/slurm?utm_source=chatgpt.com "Slurm: A Highly Scalable Workload Manager"
    [20260109-A-2]: https://www.schedmd.com/download-slurm/?utm_source=chatgpt.com "Download Slurm"
    [20260109-A-3]: https://launchpad.net/ubuntu/%2Bsource/slurm-wlm/25.05.4-2?utm_source=chatgpt.com "slurm-wlm 25.05.4-2 source package in Ubuntu - Launchpad"
    [20260109-A-4]: https://packages.debian.org/sid/source/slurm?utm_source=chatgpt.com "Debian -- Details of source package slurm in sid"

<br>

---

<br>

### Slurm CLI (from slurm-client) (sinfo, scontrol, sacctmgr) ，跟 restAPI 是兩套溝通方式嗎？
- ### gpt-5.2 (2026/01/08)
    對，**基本上可以把它們視為兩套「對外介面／溝通方式」**，但它們在 Slurm 內部會「匯流」到同一批核心服務，所以不是兩套各做各的系統。

    ### 1) Slurm CLI（sinfo / scontrol / sacctmgr）在跟誰講話？

    CLI 是走 Slurm 的原生通訊路徑：

    * **sinfo / scontrol / squeue / srun / sbatch**
      主要是跟 **slurmctld**（控制器）溝通，讀/改叢集狀態、提交工作、查節點狀態等。
    * **sacct / sacctmgr**
      主要跟 **slurmdbd**（記帳資料庫守護程式）溝通（或透過 slurmctld 間接），做 accounting 查詢與管理。

    CLI 的好處是：

    * 功能通常最完整、行為最貼近 Slurm 原生能力
    * 走 Slurm 的認證/授權模型（例如 MUNGE、或 JWT / auth 方式）

    ### 2) REST API 在跟誰講話？

    REST API 是另一個入口：HTTP(S) 介面，通常由 Slurm 提供的 REST 服務（例如 **slurmrestd**）對外提供。

    * 你用 HTTP 呼叫 `/jobs`, `/nodes`, `/partitions`…
      REST 服務再去跟 **slurmctld / slurmdbd** 互動（或讀取同一份設定/狀態來源），把結果轉成 JSON 回來。

    REST API 的好處是：

    * **更容易被非 Linux/非 Slurm 環境的系統整合**（Web 後台、Portal、IAM 系統、外部排程器）
    * 統一用 HTTP + Token/JWT 等方式做 auth，比較像一般雲端服務

    ### 3) 所以是「兩套」但背後是「同一套」

    你可以這樣記：

    * **CLI：原生 Slurm client →（Slurm RPC）→ slurmctld / slurmdbd**
    * **REST：HTTP client → slurmrestd →（Slurm 內部互動）→ slurmctld / slurmdbd**

    換句話說：**入口兩套，核心仍是同一套控制面與記帳面**。

    ### 4) 什麼時候用哪個？

    * 你在叢集內（login node/pod）做維運、排查、快速操作 → **CLI**
    * 你要做 Portal、管理平台、跨語言整合、對外提供服務 → **REST API**
    * 若你發現 REST 缺某些管理能力或行為不一致 → 通常 **CLI 仍是最可靠的 fallback**

    如果你願意貼一下：你現在用的 REST 端點是 slurmrestd 嗎？以及你目前 CLI 是用 MUNGE 還是 JWT？我可以用你現在的架構把「兩者在你環境內的實際資料流」畫成一張清楚的流程圖。

<br>

---

<br>

### [接續] 所以，Slurm CLI 並不是轉成 REST API？
- ### gpt-5.2 (2026/01/08)
    對，**一般情況下 Slurm CLI 不是把指令「轉成 REST API」去呼叫**。

    ### Slurm CLI 實際在做什麼

    以標準 Slurm 來說：

    * `sinfo / scontrol / squeue / sbatch / srun`
      會用 **Slurm 原生 RPC 協定**（透過 `libslurm`）直接跟 **`slurmctld`** 溝通。
    * `sacct / sacctmgr`
      主要跟 **`slurmdbd`** 溝通（accounting / association 等）。

    這條路徑跟 HTTP/REST 沒關係。

    ### REST API 是另一個「入口」

    REST API 通常是：

    * 你的系統（HTTP client）→ **`slurmrestd`** →（再去跟 `slurmctld` / `slurmdbd` 互動）→ 回 JSON

    所以是 **兩套 client 入口**，不是「CLI 內部改走 REST」。

    ### 什麼情況下你會看到「像是 CLI 走 REST」？

    只有在**你自己或某個平台**做了包裝（例如：寫了個 `sinfo` wrapper script，實際上 curl REST），才會變成 CLI → REST；但那不是 Slurm 原生行為。

    ### 你要驗證的話（很快）

    * 看你執行的 `sinfo` 是不是原生 binary：`type -a sinfo` / `which sinfo`
    * 若是原生 binary，它就不會去打 `https://.../slurm/...`；反而會連 `slurmctld` 的 port（以及 `slurmdbd` 的 port）。

    如果你貼一下你環境中 `type -a sinfo` 的輸出，或 `slurm.conf` 裡 `SlurmctldHost/SlurmctldPort`、`AccountingStorageHost`，我可以直接幫你對上「CLI 會連哪裡、REST 會連哪裡」。

<br>

---

<br>

### 針對 「CLI 功能通常最完整、行為最貼近 Slurm 原生能力。」，現況有哪些功能 Slurm client 可以做到，但 HTTP client 做不到？
- ### gpt-5.2 (2026/01/08)
    對，**現況（以 Slurm-25.11.1、OpenAPI v0.0.44 為例）確實有一些「Slurm CLI 做得到，但 REST/HTTP client 做不到或很難完整做到」的地方**。差異的根源是：REST 能做什麼，取決於 `slurmrestd` 當下啟用的 OpenAPI plugins；而且 OpenAPI 規格就是功能邊界。 ([slurm.schedmd.com][20260109-B-1])

    下面列幾個最常見、也最「貼近 Slurm 原生能力」的落差：

    | 類別 | Slurm CLI（scontrol/srun/sinfo…）可做到 | REST/HTTP client 現況 | 你會感覺到的差異 |
    |-----|-----|-----|-----|
    | **Partition 動態管理** | `scontrol update partition ...` 直接改 partition 參數（不一定要改檔、重啟） | REST API 只有 `get /partition/{name}`、`get /partitions/`，**沒有 create/update/delete partition 的 endpoint** ([slurm.schedmd.com][20260109-B-2]) | 你用 HTTP 只能查，無法像 CLI 一樣在線調整 partition 行為 |
    | **真正的互動式執行（job step / pty / attach 類）** | `srun --pty bash`、互動式 stdin/stdout、跟著 job step 生命週期走 | REST 有 `post /job/allocate` 但文件明確寫是「**allocate without any steps**」 ([slurm.schedmd.com][20260109-B-2]) | REST 很難「等價取代」`srun --pty` 這種互動體驗；最多做到「送出/配置/查詢/取消」這一層 |
    | **CLI 的輸出格式化與人類友善視圖** | `sinfo -o ...`、`scontrol show ...`、各種 `--Format` / 欄位排列 | REST 端有些地方甚至明示 `format` 參數「ignored；要自己在 client 端處理 JSON」 ([slurm.schedmd.com][20260109-B-2]) | CLI 直接可讀、好查；HTTP 你要自己做欄位選取、排序、表格化 |
    | **「scontrol 的雜項維運指令」覆蓋率** | 很多 `scontrol` 子命令（各種 show/update/特殊操作） | REST v0.0.44（slurmctld 那半）公開的方法其實不多：jobs/nodes/reservations/diag/ping/reconfigure/licenses/shares/resources 等等 ([slurm.schedmd.com][20260109-B-2]) | 你會遇到「CLI 一句搞定，但 REST 找不到對應 endpoint」的情況（尤其偏管理/維運類） |

    ---

    ### 怎麼判斷「你家叢集」到底差哪些？

    不要用猜的，**直接看你那台 `slurmrestd` 產出的 OpenAPI**最準。

    * 官方建議把 OpenAPI 規格當成 primary doc，而且規格內容會因為 `slurmrestd` 啟用的 plugins 而不同。 ([slurm.schedmd.com][20260109-B-1])
    * 通常你可以在 `slurmrestd` 上看到 `/openapi.json`、`/openapi.yaml` 等輸出（用來產生 client code 也很常見）。 ([slurm.schedmd.com][20260109-B-1])

    ---

    ### 小結（你在設計系統時可以這樣取捨）

    * **REST 適合**：做 Portal/UI、做跨語言整合、做「查詢 + 提交/取消/更新部分屬性」的自動化。 ([slurm.schedmd.com][20260109-B-2])
    * **CLI 仍不可替代的核心場景**：互動式 `srun --pty`、以及一些「更完整/更即時的維運調整」（特別是 partition 動態管理這類）。 ([slurm.schedmd.com][20260109-B-2])

    如果你願意貼一下你目前 `slurmrestd` 的 `/openapi.json`（或說你用的 plugin 版本路徑，例如 v0.0.4x），我可以直接幫你把「CLI 功能清單 vs 你家 REST endpoints」做一份對照表，會更精準。

    [20260109-B-1]: https://slurm.schedmd.com/rest_clients.html "Slurm Workload Manager - REST API Client Writing Guide"
    [20260109-B-2]: https://slurm.schedmd.com/rest_api.html "Slurm Workload Manager - "

<br>

---

<br>

### 怎麼知道 slurm 內部是走 RPC？
- ### gpt-5.2 (2026/01/08)
    我不是用「推測」的，是因為 **Slurm 的官方文件（SchedMD）自己就把它稱為 RPC**，而且還把「REST 轉 RPC」寫得很明白。

    你可以用這幾個一眼就能驗證的證據：

    1. **Slurm 官方診斷工具 `sdiag` 直接報表「RPC」統計**
       ` sdiag` 文件寫得很直白：它會報告最常被發出的 *remote procedure calls (RPCs)*，而且說這些是讓 `slurmctld` 執行動作的呼叫，甚至指出 RPC code 定義在 Slurm source code 的 `slurm_protocol_defs.h`。([slurm.schedmd.com][20260109-C-1])
       → 這等於官方明示：「commands/daemons 之間的動作呼叫就是 RPC」。

    2. **Slurm 官方 Troubleshooting Guide 也用「RPC 相容性」描述 daemon/commands 通訊**
       它提到 Slurm daemons 會支援前幾個 major release 的 **RPC**（以及 state files），用來跟 `slurmctld`、commands 等互通。([slurm.schedmd.com][20260109-C-2])

    3. **官方 REST API 說明：`slurmrestd` 會把 JSON/YAML 請求翻成 Slurm RPC**
       SchedMD 的 REST API 投影片直接寫：Slurm REST API 是一個工具，會把 **JSON/YAML requests 轉成 Slurm RPC requests**，再去找 `slurmctld/slurmdbd`。
       而官方 `rest.html` 也描述 `slurmrestd` stateless、同步地跟 controller（`slurmctld` 或 `slurmdbd`）互動處理請求。([slurm.schedmd.com][20260109-C-3])

    4. **`slurmrestd(8)` man page 甚至直接提到「Slurm RPC layer」**
       例如它說可以讓對外 HTTPS 用 TLS，但「Slurm RPC layer」本身仍可不透過 TLS（受 `slurm.conf` 的 TLS 設定影響）。([man.archlinux.org][20260109-C-4])

    ---

    所以比較精準的結論是：

    * **Slurm 元件彼此（commands ↔ daemons、daemons ↔ daemons）的控制面通訊，是 Slurm 自己的 RPC 協定（Slurm RPC）。**([slurm.schedmd.com][20260109-C-1])
    * **CLI 通常透過 `libslurm` 這層 API 來發出 Slurm RPC。**（`sdiag` 也明確把這些互動稱為 RPC，並指到 protocol defs）([slurm.schedmd.com][20260109-C-1])
    * **REST 是「外層入口」：HTTP 到 `slurmrestd`；內層仍轉回 Slurm RPC。**

    如果你想在你環境做「實證」而不是看文件：跑一次 `sdiag`，你會看到 RPC 的 message type/次數/耗時統計；那就是 controller 收到的 RPC 呼叫量。([slurm.schedmd.com][20260109-C-1])

    [20260109-C-1]: https://slurm.schedmd.com/sdiag.html "Slurm Workload Manager - sdiag"
    [20260109-C-2]: https://slurm.schedmd.com/troubleshoot.html "Slurm Workload Manager - Slurm Troubleshooting Guide"
    [20260109-C-3]: https://slurm.schedmd.com/rest.html?utm_source=chatgpt.com "REST API Details - Slurm Workload Manager - SchedMD"
    [20260109-C-4]: https://man.archlinux.org/man/slurmrestd.8.en "slurmrestd(8) — Arch manual pages"

<br>

---

### 在容器中，如何讓 sacctmgr 連線到 slurmdb?
- ### Q:
    我在容器內開發：
    ```
    root@63564e7893b5:/work# apt install slurm-client
    ...
    root@63564e7893b5:/work# sacctmgr 
    sacctmgr: error: resolve_ctls_from_dns_srv: res_nsearch error: Unknown host
    sacctmgr: error: fetch_config: DNS SRV lookup failed
    sacctmgr: error: _establish_config_source: failed to fetch config
    sacctmgr: fatal: Could not establish a configuration source
    ```
    我要如何讓 sacctmgr 連線到 slurmdb
- ### `us.anthropic.claude-sonnet-4-5-20250929-v1:0` (2026/01/16)
    根據你的情況和文檔，我來幫你解決在容器中讓 `sacctmgr` 連接到 `slurmdb` 的問題。

    ### 問題分析

    你遇到的錯誤：
    ```
    sacctmgr: error: resolve_ctls_from_dns_srv: res_nsearch error: Unknown host
    sacctmgr: error: fetch_config: DNS SRV lookup failed
    ```

    這表示 `sacctmgr` 無法找到 Slurm controller 的配置。在容器中，你需要：

    1. **安裝 Slurm 客戶端工具** ✅ (已完成)
    2. **配置 slurm.conf** ❌ (缺少)
    3. **配置 Slurm 認證密鑰** ❌ (缺少)

    ### 解決方案

    根據你的 K8s 環境資訊，你需要在容器中配置以下內容：

    #### 步驟 1：在容器中建立 Slurm 配置目錄

    ```bash
    # 在容器內執行
    mkdir -p /etc/slurm
    chmod 755 /etc/slurm
    ```

    #### 步驟 2：從 K8s 匯出認證密鑰

    **在宿主機上執行**（你的 K8s master node）：

    ```bash
    # 檢查 secrets 是否存在
    kubectl get secrets -n default | grep slurm

    # 匯出 slurm.key
    kubectl get secret slurm-auth-key -n default \
      -o jsonpath='{.data.slurm\.key}' | base64 -d > /tmp/slurm.key

    # 匯出 jwt_hs256.key
    kubectl get secret slurm-jwt-hs256-key -n default \
      -o jsonpath='{.data.jwt_hs256\.key}' | base64 -d > /tmp/jwt_hs256.key

    # 複製到容器內
    docker cp /tmp/slurm.key <container-id>:/etc/slurm/slurm.key
    docker cp /tmp/jwt_hs256.key <container-id>:/etc/slurm/jwt_hs256.key

    # 清理宿主機上的密鑰
    rm /tmp/slurm.key /tmp/jwt_hs256.key
    ```

    #### 步驟 3：在容器中設定密鑰權限

    **在容器內執行**：

    ```bash
    chmod 600 /etc/slurm/slurm.key
    chmod 600 /etc/slurm/jwt_hs256.key
    ```

    #### 步驟 4：建立 slurm.conf 配置檔

    根據你的 K8s 環境，`slurm-accounting` 服務的地址應該是 `slurm-accounting.default.svc.cluster.local:6819`。

    **在容器內建立配置檔**：

    ```bash
    cat > /etc/slurm/slurm.conf <<'EOF'
    # Cluster 識別
    ClusterName=your-cluster-name

    # Controller 連線設定
    SlurmctldHost=slurm-controller.default.svc.cluster.local
    SlurmctldPort=6817

    # 認證設定 (關鍵安全配置)
    AuthType=auth/slurm
    AuthInfo=use_client_ids
    CredType=cred/slurm

    # 替代認證方式 (JWT)
    AuthAltTypes=auth/jwt
    AuthAltParameters=jwt_key=/etc/slurm/jwt_hs256.key

    # Accounting 設定
    AccountingStorageType=accounting_storage/slurmdbd
    AccountingStorageHost=slurm-accounting.default.svc.cluster.local
    AccountingStoragePort=6819
    AccountingStorageEnforce=associations,limits,qos,safe

    # 日誌設定
    SlurmctldLogFile=/var/log/slurm/slurmctld.log
    SlurmdLogFile=/var/log/slurm/slurmd.log
    EOF

    chmod 644 /etc/slurm/slurm.conf
    ```

    #### 步驟 5：測試連接

    ```bash
    # 測試網路連線
    nc -zv slurm-accounting.default.svc.cluster.local 6819

    # 如果 nc 未安裝，先安裝
    apt update && apt install -y netcat-openbsd

    # 測試 sacctmgr 連線
    sacctmgr show config

    # 如果成功，應該會顯示 Slurm 配置資訊
    ```

    ### 簡化方案：使用 Port-Forward（推薦用於開發）

    如果你在 K8s master node 上開發，可以使用 port-forward 簡化配置：

    ```bash
    # 在宿主機上執行 port-forward
    kubectl port-forward -n default svc/slurm-accounting 6819:6819 &

    # 在容器中修改 slurm.conf，將 Host 改為宿主機 IP
    # AccountingStorageHost=<host-machine-ip>
    # 或使用 host.docker.internal (某些 Docker 版本支援)
    ```

    ### 驗證清單

    完成配置後，請確認：

    - [ ] `/etc/slurm/slurm.key` 存在且權限為 600
    - [ ] `/etc/slurm/jwt_hs256.key` 存在且權限為 600
    - [ ] `/etc/slurm/slurm.conf` 存在且權限為 644
    - [ ] 可以 ping 通 `slurm-accounting.default.svc.cluster.local`
    - [ ] `sacctmgr show config` 能正常執行

    ### 故障排除

    如果仍然無法連接，請檢查：

    1. **K8s Service 狀態**：
       ```bash
       kubectl get svc -n default | grep slurm
       kubectl describe svc slurm-accounting -n default
       ```

    2. **Pod 狀態**：
       ```bash
       kubectl get pods -n default | grep slurm
       kubectl logs -n default slurm-accounting-0
       ```

    3. **認證密鑰是否正確**：
       ```bash
       # 檢查密鑰長度（應該是 1024 bytes）
       stat -c%s /etc/slurm/slurm.key
       ```

    需要我協助你生成具體的配置文件或腳本嗎？

<br>

---

<br>

## 討論 - 錯誤排解

### `_sack_try_connection: connect() failed for /run/slurm/sack.socket: No such file or directory`
- ### Q:
    - ### 啟動 sackd
        ```
        su -s /bin/bash -c '
          export SLURM_CONF=/etc/slurm/slurm.conf
          sackd -vvv -f /etc/slurm/slurm.conf 2>&1 | tee /tmp/sackd.log
        ' slurm
        ```
    - ### 連線測試
        ```
        root@test-sackd:/# su -s /bin/bash -c 'sacctmgr -vvvv list user' slurm
        sacctmgr: debug3: _sack_try_connection: connect() failed for /run/slurm/sack.socket: No such file or directory
        sacctmgr: debug3: _sack_try_connection: connect() failed for /run/slurmctld/sack.socket: No such file or directory
        sacctmgr: debug3: _sack_try_connection: connect() failed for /run/slurmdbd/sack.socket: No such file or directory
        sacctmgr: error: failed to connect to any sack sockets
        sacctmgr: error: create_external: failed to create token
        sacctmgr: error: slurm_buffers_pack_msg: auth_g_create: REQUEST_PERSIST_INIT has authentication error
        sacctmgr: error: slurm_persist_conn_open: failed to send persistent connection init message to slurm-accounting.slurm.svc.cluster.local:6819
        sacctmgr: error: Sending PersistInit msg: Protocol authentication error

        root@test-sackd:/# sackd -h
        usage:	sackd [OPTIONS]
            --conf-server host[:port]   Get configs from slurmctld at `host[:port]`.
            -f config                   Read configuration from the specified file.
            -h                          Print this help message.
            --systemd                   Started from a systemd unit file.
            -v                          Verbose mode. Multiple -v's increase verbosity.
        ```
- ### `us.anthropic.claude-sonnet-4-5-20250929-v1:0` (2026/01/19)
    根據文件和原始碼，我發現問題了。讓我分析關鍵資訊並提供解決方案：

    ### 問題分析

    根據您提供的錯誤資訊和 Slurm 原始碼，問題出在：

    1. **Socket 檔案沒有建立**
       ```
       _sack_try_connection: connect() failed for /run/slurm/sack.socket: No such file or directory
       ```

    2. **核心問題**: sackd 需要在 **前景模式 (foreground)** 運行，或需要配合 systemd 使用。

    ### 解決方案

    根據 `sackd.8` 手冊，有幾個關鍵選項：

    #### 方法 1：使用前景模式 (`-D` flag)

    ```bash
    # 使用 -D flag 讓 sackd 在前景運行
    su -s /bin/bash -c '
      export SLURM_CONF=/etc/slurm/slurm.conf
      export RUNTIME_DIRECTORY=/run/slurm
      mkdir -p /run/slurm
      sackd -D -vvv -f /etc/slurm/slurm.conf 2>&1 | tee /tmp/sackd.log &
    ' slurm
    ```

    #### 方法 2：確保 RUNTIME_DIRECTORY 存在並可寫入

    ```bash
    # 1. 建立 runtime 目錄
    mkdir -p /run/slurm
    chown slurm:slurm /run/slurm
    chmod 755 /run/slurm

    # 2. 以 slurm 使用者啟動 sackd (使用 -D 前景模式)
    su -s /bin/bash -c '
      export SLURM_CONF=/etc/slurm/slurm.conf
      export RUNTIME_DIRECTORY=/run/slurm
      sackd -D -vvv -f /etc/slurm/slurm.conf 2>&1 | tee /tmp/sackd.log
    ' slurm &
    ```

    #### 方法 3：檢查 slurm.conf 是否正確

    確保 `slurm.conf` 中包含必要的配置：

    ```bash
    # 檢查設定檔
    grep -E "(AuthType|AuthInfo|CredType|AuthAltTypes)" /etc/slurm/slurm.conf

    # 應該要有類似以下設定：
    # AuthType=auth/slurm
    # AuthInfo=use_client_ids
    # CredType=cred/slurm
    # AuthAltTypes=auth/jwt
    # AuthAltParameters=jwt_key=/etc/slurm/jwt_hs256.key
    ```

    ### 完整測試腳本

    以下是完整的測試流程：

    ```bash
    #!/bin/bash
    # 測試 sackd 啟動腳本

    set -e

    echo "==> 1. 清理舊程序"
    pkill -9 sackd || true
    rm -rf /run/slurm/sack.socket || true

    echo "==> 2. 建立 runtime 目錄"
    mkdir -p /run/slurm
    chown slurm:slurm /run/slurm
    chmod 755 /run/slurm

    echo "==> 3. 檢查配置檔"
    ls -la /etc/slurm/
    cat /etc/slurm/slurm.conf | grep -E "(AuthType|AuthInfo|CredType|ClusterName)"

    echo "==> 4. 啟動 sackd (前景模式 + 背景執行)"
    su -s /bin/bash -c '
      export SLURM_CONF=/etc/slurm/slurm.conf
      export RUNTIME_DIRECTORY=/run/slurm
      sackd -D -vvv -f /etc/slurm/slurm.conf 2>&1 | tee /tmp/sackd.log
    ' slurm &

    SACKD_PID=$!
    echo "sackd PID: $SACKD_PID"

    echo "==> 5. 等待 socket 建立"
    for i in {1..10}; do
      if [ -S /run/slurm/sack.socket ]; then
        echo "✅ Socket 已建立！"
        ls -la /run/slurm/sack.socket
        break
      fi
      echo "等待 socket 建立... ($i/10)"
      sleep 1
    done

    if [ ! -S /run/slurm/sack.socket ]; then
      echo "❌ Socket 未建立，檢查日誌："
      cat /tmp/sackd.log
      exit 1
    fi

    echo "==> 6. 檢查 sackd 程序狀態"
    ps aux | grep sackd

    echo "==> 7. 測試連線"
    su -s /bin/bash -c 'sacctmgr show config' slurm
    ```

    ## 關鍵要點

    1. **必須使用 `-D` flag**: sackd 預設會 fork 成背景程序，但在容器環境中可能會失敗
    2. **RUNTIME_DIRECTORY 必須存在**: 預設是 `/run/slurm/`，必須由 slurm 使用者可寫入
    3. **slurm 使用者必須有正確權限**: 對 `/etc/slurm` 和 `/run/slurm` 都要有存取權
    4. **使用 `&` 將前景程序放到背景**: 因為 `-D` 會讓程序在前景運行

    ## 除錯技巧

    如果還是失敗，可以這樣除錯：

    ```bash
    # 直接以 slurm 使用者執行，查看詳細錯誤
    su - slurm
    export SLURM_CONF=/etc/slurm/slurm.conf
    export RUNTIME_DIRECTORY=/run/slurm
    export SACKD_DEBUG=9
    sackd -D -vvv -f /etc/slurm/slurm.conf

    # 檢查是否有權限問題
    strace -f sackd -D -f /etc/slurm/slurm.conf 2>&1 | grep -E "(EACCES|EPERM|/run/slurm)"
    ```

    請嘗試以上方法，特別是**使用 `-D` flag**，這應該能解決 zombie 程序和 socket 未建立的問題。

<br>

---

<br>

### ``create_mmap_buf: Failed to open file `/etc/slurm/slurm.key`, Permission denied``
- ### Q:
    ```
    # 啟動 sackd
    root@test-sackd:/data# su -s /bin/bash -c '
      export SLURM_CONF=/etc/slurm/slurm.conf
      export RUNTIME_DIRECTORY=/run/slurm
      sackd -D -vvv -f /etc/slurm/slurm.conf 2>&1 | tee /tmp/sackd.log
    ' slurm
    sackd: debug:  _establish_config_source: config will load from file
    sackd: debug2: _establish_config_source: using config_file=/etc/slurm/slurm.conf (provided)
    sackd: debug:  slurm_conf_init: using config_file=/etc/slurm/slurm.conf
    sackd: debug:  Reading slurm.conf file: /etc/slurm/slurm.conf
    sackd: debug:  _plugrack_foreach: serializer plugin type:serializer/json path:(null)
    sackd: debug:  auth/slurm: init: running as daemon
    sackd: debug:  auth/slurm: init_internal: loading key: `/etc/slurm/slurm.key`
    sackd: debug:  create_mmap_buf: Failed to open file `/etc/slurm/slurm.key`, Permission denied
    sackd: fatal: auth/slurm: Could not load key file (/etc/slurm/slurm.key)
    ```

- ### 解法
    ```
    $ ls -ls /etc/slurm/slurm.key 
    4 -rw------- 1 root root 1024 Jan 19 06:14 /etc/slurm/slurm.key
    
    $ chown slurm:slurm /etc/slurm/slurm.key 
    
    $ ls -ls /etc/slurm/slurm.key 
    4 -rw------- 1 slurm slurm 1024 Jan 19 06:14 /etc/slurm/slurm.key
    ```

<br>

---

<br>

### `sacctmgr: error: Sending PersistInit msg: Incompatible versions of client and server code`
- ### Q:
    - ### 線索1：`command not found`
        ```
        $ kubectl -n slurm get pod/test-sackd -o jsonpath='{.spec.containers[0].image}'
        ghcr.io/slinkyproject/slurmdbd:25.11-ubuntu24.04
        # server image

        $ kubectl -n slurm exec -it pod/test-sackd -- bash
        root@test-sackd:/tmp# scontrol
        bash: scontrol: command not found

        root@test-sackd:/tmp# sacctmgr
        bash: sacctmgr: command not found
        ```
    - ### 線索2：`Incompatible versions of client and server code`
        ```
        $ scontrol version
        slurm-wlm 23.11.4

        # 啟動 sackd
        $ su -s /bin/bash -c 'sacctmgr -vvvv list user' slurm
        sacctmgr: debug2: _sack_connect: connected to /run/slurm/sack.socket
        sacctmgr: error: slurm_persist_conn_open: Something happened with the receiving/processing of the persistent connection init message to slurm-accounting.slurm.svc.cluster.local:6819: Failed to unpack SLURM_PERSIST_INIT message
        sacctmgr: error: Sending PersistInit msg: Incompatible versions of client and server code
        ```
    - ### 線索3
        ```
        $ $ kubectl -n slurm get pod/slurm-login-slinky-6b99b68f64-vg97b -o jsonpath='{.spec.containers[0].image}'
        ghcr.io/slinkyproject/login-pyxis:25.11-ubuntu24.04

        $ kubectl exec -it slurm-login-slinky-6b99b68f64-vg97b -n slkubectl exec -it slurm-login-slinky-6b99b68f64-vg97b -n slurm -- bash

        root@slurm-login-slinky-6b99b68f64-vg97b:/tmp# sacctmgr version
        slurm 25.11.1
        ```
- ### `us.anthropic.claude-sonnet-4-5-20250929-v1:0` (2026/01/19)
    讓我基於文檔和配置來解釋這兩個映像檔的差異：

    ### **差異分析**

    根據 Slurm 架構和您提供的資訊，這兩個映像檔之間的主要差異如下：

    #### **1. 映像檔用途不同**

    **`ghcr.io/slinkyproject/slurmdbd:25.11-ubuntu24.04`**
    - **用途**: Slurm Database Daemon (slurmdbd) 專用映像檔
    - **角色**: 負責 Slurm 會計系統 (accounting)，處理作業歷史記錄的儲存
    - **主要服務**: `slurmdbd` daemon
    - **參考**: helm/slurm/README.md:46

    **`ghcr.io/slinkyproject/login-pyxis:25.11-ubuntu24.04`**
    - **用途**: Login node 映像檔，包含 Pyxis 容器化作業支援
    - **角色**: 使用者登入節點 (submit node/jump host)，供使用者提交作業
    - **主要功能**: 完整的 Slurm 客戶端工具集 + Pyxis/Enroot 容器支援
    - **參考**: docs/usage/pyxis.md:43

    #### **2. 包含的 Slurm 工具不同**

    **slurmdbd 映像檔 (test-sackd pod)**
    ```
    ✗ sacctmgr  - 不包含
    ✗ scontrol  - 不包含  
    ✓ slurmdbd  - 主要服務
    ```
    - **原因**: 這是一個**最小化映像檔**，僅包含 `slurmdbd` daemon 本身
    - **設計理念**: 遵循容器最佳實踐 - 單一職責原則 (single responsibility)

    **login-pyxis 映像檔**
    ```
    ✓ sacctmgr  - 包含
    ✓ scontrol  - 包含
    ✓ srun      - 包含
    ✓ sbatch    - 包含
    ✓ squeue    - 包含
    ✓ scancel   - 包含
    + Pyxis/Enroot 容器工具
    ```
    - **原因**: Login node 需要**完整的使用者工具集**供管理員和使用者操作
    - **參考**: helm/slurm/values.yaml:98-99

    #### **3. 使用場景差異**

    | 項目 | slurmdbd 映像檔 | login-pyxis 映像檔 |
    |------|----------------|-------------------|
    | **主要用途** | 資料庫代理服務 | 使用者互動節點 |
    | **網路通訊** | 與 MariaDB 通訊 (port 3306) | 與 slurmctld 通訊 (port 6817) |
    | **是否需要用戶工具** | ❌ 不需要 | ✅ 必須 |
    | **是否執行作業** | ❌ 不執行 | ✅ 提交作業 |
    | **特殊功能** | 會計資料處理 | Pyxis 容器化作業 |

    #### **4. 為什麼 slurmdbd 映像檔沒有這些命令**

    根據 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 不應該被當作管理介面使用

    #### **5. 正確的使用方式**

    如果您需要執行 `sacctmgr` 或 `scontrol`：

    ```bash
    # ✅ 正確：在 login pod 執行
    kubectl -n slurm exec -it pod/slurm-login-slinky-6b99b68f64-vg97b -- sacctmgr list account

    # ✅ 正確：在 controller pod 執行  
    kubectl -n slurm exec -it pod/slurm-controller-0 -c slurmctld -- scontrol show config

    # ❌ 錯誤：在 slurmdbd pod 執行（工具不存在）
    kubectl -n slurm exec -it pod/test-sackd -- sacctmgr
    ```

    ### **總結**

    這不是 bug，而是**正確的容器化設計**：
    - `slurmdbd` 映像檔：專注於資料庫代理服務，僅包含 `slurmdbd` daemon
    - `login-pyxis` 映像檔：完整的使用者環境，包含所有 Slurm 客戶端工具和容器支援

    如果您需要在不同環境執行特定命令，請選擇正確的 pod 類型。


<br>

{%hackmd vaaMgNRPS4KGJDSFG0ZE0w %}