Skip to content

NVIDIA OpenShell — 系統架構

分析版本

本文件基於 commit d9908222 進行分析。

相關章節

整體架構

OpenShell 的架構圍繞三個穩定的執行時元件:CLIGatewaySupervisor,搭配底層計算驅動(Compute Driver)支援多種執行環境。

┌─────────────────────────────────────────────┐
│              使用者介面層                      │
│   CLI ─── SDK ─── TUI(Terminal UI)         │
└───────────────────┬─────────────────────────┘
                    │ gRPC / HTTP
┌───────────────────▼─────────────────────────┐
│                控制平面(Gateway)              │
│  ┌──────────┐ ┌──────────┐ ┌─────────────┐  │
│  │  Compute  │ │Credentials│ │   Identity  │  │
│  │ Subsystem │ │ Subsystem │ │  Subsystem  │  │
│  └────┬─────┘ └────┬─────┘ └──────┬──────┘  │
│       │ Compute    │ Creds         │ OIDC     │
│       │ Driver     │ Driver        │ / mTLS   │
└───────┼────────────┼───────────────┼──────────┘
        ▼            ▼               ▼
   Docker/Podman  Keychain/       mTLS/OIDC/
   K8s / VM       Vault/K8s       Local
                  Secrets

        ▼ 佈建工作負載
┌───────────────────────────────────────────┐
│              沙箱資料平面                    │
│  ┌──────────────────────────────────────┐ │
│  │              Supervisor              │ │
│  │  ┌────────────┐  ┌────────────────┐  │ │
│  │  │Policy Proxy│  │Inference Router│  │ │
│  │  │  (Egress)  │  │  (inference.   │  │ │
│  │  │            │  │   local)       │  │ │
│  │  └─────┬──────┘  └───────┬────────┘  │ │
│  │        │ OPA Engine       │           │ │
│  │  ┌─────▼──────────────────▼────────┐  │ │
│  │  │       受限 Agent 程序             │  │ │
│  │  └────────────────────────────────┘  │ │
│  └──────────────────────────────────────┘ │
└───────────────────────────────────────────┘

核心元件詳解

Gateway(控制平面)

Gateway 是 OpenShell 的認證控制平面,擁有:

職責說明
API 伺服器gRPC / HTTP 端點,供 CLI、SDK 與 Supervisor 呼叫
沙箱生命週期建立、刪除、監視、協調沙箱狀態轉換
持久化狀態沙箱記錄、策略版本、Provider、推理配置(SQLite 或 PostgreSQL)
策略分發將策略、設定與憑證交付給各沙箱的 Supervisor
Relay 協調管理沙箱 SSH 連線的 Relay 中繼通道
身份驗證支援 mTLS 與 OIDC(Keycloak、Entra ID、Okta 等)

Supervisor(沙箱安全邊界)

Supervisor 執行於每個沙箱工作負載內,是本地安全邊界的核心:

職責說明
程序隔離以受限子程序啟動 Agent,降低程序權限
Policy Proxy攔截所有 Agent 對外流量,透過 OPA 策略引擎評估
Inference Routerhttps://inference.local 路由至已配置的模型後端
憑證注入以環境變數形式注入 Provider 憑證,不寫入沙箱檔案系統
控制通道與 Gateway 保持持久連線,接收策略更新與 Relay 請求
日誌推送即時將日誌推送至 Gateway

Policy Engine(OPA)

Policy Engine 是 Supervisor 中的 Policy Proxy 所依賴的策略評估核心:

Agent 出站請求


 Policy Proxy

      ├─ 目的地與方法評估 (OPA)
      │     ├─ Allow → 轉發至外部服務
      │     ├─ Route → 剝除 API Key,注入後端憑證,轉發至推理後端
      │     └─ Deny  → 阻斷並記錄

      └─ inference.local → Inference Router → 模型後端

策略決策邏輯:

  • 允許(Allow):目的地與 HTTP 方法符合策略 Block
  • 推理路由(Route for Inference):剝除 Caller 憑證、注入後端憑證、轉發至受管模型
  • 拒絕(Deny):阻斷請求並記錄

計算驅動架構

每個 Compute Driver 接收來自 Gateway 的沙箱規格,負責:

  1. 選取沙箱映像
  2. 注入沙箱身份與 Gateway 回呼設定
  3. 提供 TLS 或 Secret 素材
  4. 提供 Supervisor 二進位或映像
  5. 回報生命週期與平台事件
  6. 清理執行時資源

Driver 比較

Driver適用場景沙箱邊界特點
Docker本機開發容器 + 沙箱命名空間使用 Host 網路,Loopback Gateway 端點可用
PodmanRootless / 單機容器 + 沙箱命名空間Podman REST API、OCI Image Volume、CDI GPU
Kubernetes叢集佈署(Helm)Pod + 沙箱命名空間K8s API、Service Account、PVC、GPU 資源
VM(MicroVM)最高隔離(實驗性)libkrun VM每沙箱一個 VM,rootfs.ext4 + overlay.ext4

Supervisor 二進位交付方式

Supervisor 必須存在於每個沙箱工作負載內,不同 Driver 有不同的交付方式:

Driver交付方式
Docker本機 Supervisor 二進位 Bind Mount
Podman唯讀 OCI Image Volume(含 Supervisor 二進位)
Kubernetes沙箱 Pod 映像 或 Init Container 複製
VM嵌入於 Guest Rootfs Bundle

在 Kubernetes 環境下,Supervisor 的交付方式由叢集版本決定:

  • K8s ≥ 1.35:使用 image-volume(ImageVolume GA 於 1.36)
  • K8s < 1.35:使用 init-container(複製至 emptyDir)

安全模型

Gateway ↔ Supervisor 關係

兩者的關係由 Supervisor 主動發起

  • Supervisor 向已知的 Gateway 端點主動發出連線
  • 以沙箱工作負載身份驗證(mTLS)
  • 保持持久 Session 用於控制流量與 Relay
  • 如 Session 中斷,沙箱可繼續執行,但即時操作失敗直到 Supervisor 重新連線

此設計避免 Compute Driver 必須解決 Gateway → Sandbox 的可達性問題(Pod IP、Port Forwarding、NAT 穿透等)。

策略更新機制

策略類型更新時機方式
Filesystem 策略沙箱建立時鎖定不可熱重載
Process 策略沙箱建立時鎖定不可熱重載
Network 策略執行時openshell policy set 熱重載
Inference 策略執行時openshell policy set 熱重載

目錄結構

OpenShell/
├── architecture/          # 架構文件(Gateway、Sandbox、Security Policy、Compute Runtime)
├── crates/                # Rust crates(核心)
│   ├── openshell-gateway/ # Gateway 核心實作
│   ├── openshell-supervisor/ # Supervisor 實作
│   ├── openshell-driver-docker/    # Docker Driver
│   ├── openshell-driver-podman/    # Podman Driver
│   ├── openshell-driver-kubernetes/ # Kubernetes Driver
│   └── openshell-driver-vm/        # VM Driver
├── deploy/
│   └── helm/openshell/    # Helm Chart(Kubernetes 部署)
├── examples/              # 使用範例(sandbox-policy-quickstart 等)
├── .agents/skills/        # Agent Skills(Agent 驅動的開發工作流程)
└── install.sh             # 二進位安裝腳本

Kubernetes Driver 底層實作流程

以下是一次 openshell sandbox create 在 Kubernetes 上的控制流程(偏實作視角):

OpenShell Kubernetes Driver 執行流程圖

建立路徑中的關鍵狀態

狀態觸發條件常見失敗點
RequestedGateway 收到建立請求API 驗證參數不完整
ProvisioningDriver 開始建立 K8s 資源Secret / PVC / RBAC 權限不足
BootstrappingPod 已啟動、Supervisor 初始化Supervisor sidecar 交付失敗
ConnectedSupervisor 成功回連 GatewaymTLS 憑證錯誤或 CA 不一致
Running策略與推理路由載入完成OPA policy syntax / provider credentials 錯誤

控制平面與資料平面的請求路徑

OpenShell 控制流與資料流路徑圖

上圖可拆成兩條獨立路徑:

  • 控制流:CLI ↔ Gateway ↔ Supervisor(生命週期、策略、Relay)
  • 資料流:Agent ↔ Policy Proxy/Inference Router ↔ 外部 API(執行期網路請求)

維運痛點與實務對策(OpenShell on K8s)

維運痛點底層原因建議對策
Gateway 擴容後狀態不一致多副本下若使用 SQLite,狀態無法共享生產環境改用外部 PostgreSQL;啟用備援與連線池監控
沙箱大量建立時 PendingPVC / Image Pull / Node 資源三方競爭預先容量規劃、分離 sandbox node pool、設定 ResourceQuota
policy 更新延遲Supervisor 控制通道抖動或重連頻繁監控 supervisor reconnect rate,設定告警並檢查網路抖動
inference.local 成功率下降上游 LLM provider 限流、憑證過期、DNS 問題導入 provider 健康檢查、API Key 輪替排程、失敗率 SLO
憑證輪替造成短暫中斷mTLS 憑證與 Supervisor session 更新不同步採雙憑證重疊期(overlap)與分批滾動更新
Debug 困難(Pod 秒退)啟動期錯誤在容器早期發生,日誌不完整啟用集中式日誌,保留 init-container 與 supervisor 啟動日誌

基於 Apache 2.0 授權