Skip to content

0nyx-networks/deploy-gpu-cli

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

deploy-gpu-cli

Runpod の GPU Pod へコンテナを 1コマンドでデプロイ + 後始末 までやる CLI。

  • Runpod REST API v1 (https://rest.runpod.io/v1) を直接叩く。SDK 依存なし
  • Tailscale auth-key を都度発行 (ephemeral / 1度きり / 10分有効)
  • 同名 Offline デバイスを事前削除 → Tailscale 上の重複名衝突を回避
  • GPU type / DC / 国 / 価格 で自動候補検索 (REST が単一リクエストで在庫マッチング)
  • 登録待機 (--wait) → 成功で auth-key を自動 revoke
  • destroy 時に Runpod 側消滅確認 + Tailscale デバイス削除
  • ラベル指名 (ollama / comfyui / studio) でも pod id でも操作可

構成

app/
  config.py     - 設定 / プロファイル読み込み (pydantic v2)
  runpod.py     - Runpod REST v1 クライアント (httpx)
  tailscale.py  - Tailscale REST クライアント
  deploy.py     - 一連の処理オーケストレーション
  cli.py        - typer ベースの CLI (deploy-gpu-cli)
  api.py        - FastAPI HTTP ラッパー (POST /deploy, GET /pods)
templates/
  _shared/onstart.sh
  ollama/profile.json
  comfyui/profile.json
  studio/{profile.json,onstart.sh}
.env            - API キー (gitignore 対象)

セットアップ

cd /opt/deploy-gpu-cli
pip install -e .

cp .env.example .env
# RUNPOD_API_KEY / TAILSCALE_API_KEY / TAILSCALE_TAILNET を埋める

pip install -e .deploy-gpu-cli コマンドが PATH に登録されます。python -m app でも同じです。

.env キー一覧

RUNPOD_API_KEY=...            # 必須。Runpod console で 2024-11-11 以降に発行したキー
TAILSCALE_API_KEY=tskey-api-...
TAILSCALE_TAILNET=-           # `-` で自分の tailnet を自動解決
TAILSCALE_TAGS=tag:cloud-gpu-pods
SSH_PUBLIC_KEY="ssh-ed25519 AAAA... user@host"

重要: Runpod の API キーは 2024-11-11 より前に発行されたもの (legacy key) だと REST API で 401 を返します。古いキーは Runpod console から再発行してください。CLI は 401/403 時にその旨を案内します。

bash 補完 (任意)

deploy-gpu-cli --install-completion bash
exec bash

Tailscale 側の準備

  1. https://login.tailscale.com/admin/settings/keysAPI access token (PAT) を発行
  2. ACL に使用するタグを tagOwners として登録
    "tagOwners": { "tag:cloud-gpu-pods": ["autogroup:admin"] }

Runpod 側の準備

  1. https://www.runpod.io/console/user/settings で API key を発行 (REST API 対応キー)
  2. .envRUNPOD_API_KEY に設定
  3. SSH_PUBLIC_KEY.env に入れると Pod の PUBLIC_KEY env 経由で ~/.ssh/authorized_keys に追記される

デプロイ

既定は実行 (deploy)。計画のみ確認は --dry-run。 Tailscale 登録待機は デフォルト off (--no-wait)。--wait で最大 300秒ブロック。

# 本実行
deploy-gpu-cli deploy ollama
deploy-gpu-cli deploy comfyui -v

# 計画のみ表示
deploy-gpu-cli deploy ollama --dry-run

# Tailscale 登録まで待機
deploy-gpu-cli deploy ollama --wait

# Pod 名 (label / Tailscale hostname) を上書き
deploy-gpu-cli deploy ollama --name ollama-dev

# GPU type を直接指名 (検索スキップ)
deploy-gpu-cli deploy ollama --gpu-type-id "NVIDIA GeForce RTX 5090"

# 待機タイムアウトを延長
deploy-gpu-cli deploy comfyui --wait --wait-timeout 600

内部フロー

  1. name を DNS-safe に正規化
  2. Pre-flight: Runpod 上に同名 Pod があれば即エラー (二重課金回避)
  3. Tailscale で同名 Offline デバイスを削除
  4. ephemeral auth-key を発行 (expirySeconds=600)
  5. search.gpu_name を Runpod REST の gpuTypeIds 列挙にマップ (_GPU_ALIAS による別名解決)
  6. Probe: フィルタ条件で POST /pods を試行し、Runpod が割当てた gpuTypeId / dataCenterId を回収して即 terminate
  7. 回収した正解の GPU/DC を data_center_priority="custom" で固定し、本番の POST /pods を発行
  8. onstart スクリプトを base64 で dockerArgs に埋め込み (Runpod は onstart 専用フィールドが無い)
  9. exposed_ports は空配列であっても明示送信 (送らないとイメージの EXPOSE が拾われ Jupyter 等が出る)
  10. Tailscale 登録待機 → 成功で auth-key を即 revoke

Pod 管理

<target> には pod id または label を渡せる。

deploy-gpu-cli pods                   # Pod 一覧
deploy-gpu-cli status                 # Pod 詳細一覧
deploy-gpu-cli status ollama
deploy-gpu-cli status <pod-id>

deploy-gpu-cli logs ollama            # runtime/status の要約のみ
                                      # (詳細ログは `runpodctl get logs <id>` か Web Console)

deploy-gpu-cli stop ollama
deploy-gpu-cli start ollama

deploy-gpu-cli destroy ollama         # 確認プロンプトあり (default N)
deploy-gpu-cli destroy ollama -y
deploy-gpu-cli destroy ollama --skip-tailscale

pods / statusGET /pods?includeMachine=true を使い、gpu_name / geolocation (= dataCenterId) を表示します。

destroy の処理順:

  1. label / id を捕捉
  2. Runpod 側 terminate_pod
  3. 消滅をポーリングして確認
  4. 同名 Tailscale デバイスを online/offline 問わず 全削除

候補のプレビュー / 診断

deploy-gpu-cli offers ollama --limit 20   # フィルタ済 GPU type ID の優先順リスト
deploy-gpu-cli ts-find ollama             # Tailscale 上の同名/類似デバイス
deploy-gpu-cli ts-purge ollama            # 同名 Offline デバイスを掃除

REST API には公開 GPU カタログ (価格 / VRAM) のエンドポイントが無いため、offersgpuTypeIds の優先リストのみ返します。価格・在庫の確定は実際の create_pod 試行で行います。


HTTP API

deploy-gpu-cli serve --host 127.0.0.1 --port 8000

# デプロイ
curl -X POST localhost:8000/deploy \
  -H 'content-type: application/json' \
  -d '{"target":"ollama","wait_for_tailscale":true,"wait_timeout":300}'

curl localhost:8000/pods
curl localhost:8000/healthz

プロファイルのカスタマイズ

templates/<target>/profile.json:

{
  "name": "ollama",
  "image": "m10i1986/ollama-running-on-gpupods:latest",
  "onstart_script": "_shared/onstart.sh",   // base64 で dockerArgs に注入
  "runtype": "ssh",

  // ---- Pod 作成設定 (検索条件ではない) ----
  "num_gpus": 1,
  "container_disk_gb": 32,                  // コンテナの ephemeral disk
  "volume_gb": 0,                           // 永続ボリューム GB (0 なら無し)
  "volume_mount_path": "/workspace",        // 永続ボリュームのマウント先 (volume_gb > 0 の場合必須)

  "env": {
    "TAILSCALE_HOSTNAME": "ollama",         // Pod 名 + Tailscale hostname
    "TAILSCALE_TAG": "cloud-gpu-pods"       // prefix `tag:` は自動付与
    // TAILSCALE_AUTHKEY は deploy 時に自動注入
    // SSH_PUBLIC_KEY が設定済なら PUBLIC_KEY も自動注入
  },
  "exposed_ports": [],                      // 空でも明示送信される

  // ---- 検索/フィルタ条件 ----
  "search": {
    "gpu_name": ["RTX 5090"],                // 別名/部分一致で gpuTypeIds に解決
    "gpu_ram_gb_min": 32,                    // (REST 側でなくクライアント側の参考値)
    "max_dph": 1.0,                          // 上限 USD/hour
    "region": ["AP-JP-1", "JP"],             // DC ID(`-` 含む) または ISO 国コードの優先リスト。空なら任意
    "cloud_type": "SECURE",                  // "SECURE" | "COMMUNITY" | "ALL"
    "network_volume_id": null,               // 既存 network volume を attach する場合
    "min_vcpu_per_gpu": 4,                   // UI "vCPUs / GPU"。pod 全体には num_gpus 倍で送信
    "min_ram_per_gpu_gb": 16,                // UI "RAM / GPU"。同上
    "min_download_mbps": 400,                // UI "Internet speed" (Mbps)
    "min_upload_mbps": null,                 // 同上
    "support_public_ip": false,              // Tailscale 利用なら通常 false
    "cuda_versions": ["12.8", "13.0"]        // UI "CUDA versions"
  }
}

TargetProfile のトップレベル項目

フィールド 意味
name プロファイル名 (CLI でのターゲット名と一致させる)
image Runpod に渡す Docker image
onstart_script templates/ 配下の onstart スクリプトパス
runtype ssh / ssh_proxy / args / jupyter
num_gpus Pod に割り当てる GPU 枚数
container_disk_gb コンテナの ephemeral disk (GB)
volume_gb 永続ボリュームの容量 (GB)。0 で無し
volume_mount_path 永続ボリュームのマウント先
env コンテナ env (TAILSCALE_AUTHKEY / PUBLIC_KEY は自動上書き)
exposed_ports 公開ポート。空配列でも明示送信される
search 下表の検索/フィルタ条件

主な search フィールド

フィールド 意味
gpu_name GPU type id / 別名 (rtx5090, h100 等)。_GPU_ALIAS で正規化
gpu_ram_gb_min クライアント側の参考下限値 (REST 検索には未使用)
max_dph 上限 USD/hour
region DC ID (AP-JP-1 等、- を含む) または ISO 国コード (JP) の優先リスト
cloud_type Runpod の cloud_type (SECURE 推奨)
network_volume_id 既存 network volume を attach する場合の ID
min_vcpu_per_gpu / min_ram_per_gpu_gb UI 同名項目。REST には num_gpus 倍した pod 全体値で送信
min_download_mbps / min_upload_mbps Runpod の minDownload / minUpload (Mbps)
support_public_ip Runpod に Public IP を要求するか (Tailscale 利用なら通常 false)
cuda_versions 許容 CUDA バージョンのリスト (allowedCudaVersions)。空なら無指定

SSH 鍵の挙動

SSH_PUBLIC_KEY.env に入れると PUBLIC_KEY env としてコンテナに渡され、公式 Runpod イメージが ~/.ssh/authorized_keys に追記します。

onstart スクリプトの埋め込み

Runpod には onstart 専用フィールドが無いため、onstart_script で指定したスクリプトを base64 化して以下の形で dockerArgs に注入します:

bash -lc 'echo <BASE64> | base64 -d | bash'

イメージの ENTRYPOINT/CMD を上書きしたくない場合は最小のダミー (_shared/onstart.sh 等) を指定してください。


注意

  • ephemeral auth-key: Pod 停止 = Tailscale ノード自動削除。stopstart の再接続では tailscaled が node-key を保持しているので auth-key 不要
  • Runpod の RTX 5090 SECURE は ~$0.99/h、COMMUNITY は ~$0.69/h。max_dph を極端に絞ると候補ゼロ
  • destroy の確認プロンプトは -y で抑止可
  • Runpod の公開 API では container ログを取得できない。logs コマンドは runtime/status の要約のみを返す。詳細は runpodctl get logs <id> か Web Console を参照
  • API キーは 2024-11-11 以降に発行されたもの が必要。旧 GraphQL 専用キーは 401 になる

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors