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