コード サンドボックス 展開
Aivory の Python コード実行機能は、独立したサンドボックス サービスによって提供されています。このページでは、その sidecar アーキテクチャ、compose 内の各重要構成要素の意味、セキュリティの限界、サンドボックスを別のマシンに独立してデプロイする方法について説明します。Python サンドボックス ガイド。
構造:sidecar コントロール + シングル セッション コンテナ
サンドボックスは2つの鏡で構成されています:
| 鏡像 | 役割 |
|---|---|
ghcr.io/hjxwz123/aivory-sandbox-sidecar | コントロールサービス (sidecar): バックエンドの HTTP リクエストを受信し、Docker daemon がセッションコンテナを作成/リサイクルします。 |
ghcr.io/hjxwz123/aivory-sandbox | 実行時刻鏡:各セッションにロックされたコンテナで、実際にユーザーコードを実行する |
┌──────────┐ POST /sessions /exec /files ┌───────────────┐ docker exec ┌────────────────┐
│ app 后端 │ ────────────────────────────► │ sidecar 控制面 │ ────────────► │ 会话容器 │
└──────────┘ SANDBOX_BASE_URL └───────────────┘ │ aivory-sandbox │
└────────────────┘
sidecar自体はユーザーコードを実行しません。/var/run/docker.sockDocker daemon ホストを操作し、セッションごとにシブリング コンテナを引っ張ります。/workspace同じセッションの複数の実行間で、pip がインストールしたパッケージ、生成されたファイルが存在し、ChatGPT Code Interpreter が動作する。
宿泊プログラムはホストです。/var/run/docker.socksidecar コンテナに入ると、セッション コンテナはホストの daemon によって作成されます。 あなたの環境がホストの socket を持ち込むことを許可していない場合は、ドッカー (docker:dind) daemon を独自のドッカー(docker:dind)に追加することもできます。 ストレージのコストと複数のレイヤーがかかります。 どちらにしても、sidecar は Docker daemon にアクセスする必要があります。
実行時鏡には、データサイエンススタック(numpy、pandas、scipy、scikit-learn、matplotlib、seaborn、plotly など)、ドキュメント処理ライブラリ(python-pptx、python-docx、openpyxl、reportlab、weasyprint など)と Noto Sans CJK フォントが組み込まれ、matplotlib はテキストを事前に構成し、グラフの中国語は文字列として表示されません。
内蔵 サンドボックス : デフォルトゼロ設定
生産コンポーネント縛られたsandboxサービス、docker compose up -dサンドボックスと一緒に引っ張るコマンドは、追加の設定を必要としません:
- ホストポートを公開しない: たった
app民間を通じてinternalネットワーク(SANDBOX_BASE_URL=http://sandbox:8000ネットは決して触れない。 - 内部 API キーの共有:
app与sandbox2 サービスは同じ読み方SANDBOX_API_KEY(仮認)aivory-bundled-sandboxサンドボックスが外部に曝露されていないため、このデフォルト値は利用可能ですが、サンドボックスポートを他のネットワークに曝露する場合は強力なランダム値に変更する必要があります。 - スタートは鏡像。:
SANDBOX_PULL_ON_START=1sidecar を冷たいスタート時に最初に走行時刻鏡を引っ張り、健康チェックstart_period: 120s今回の引越しのための予約です。 - 柔らかな依存:
app不depends_onサンドボックス サンドボックス 利用できないときは、コード実行機能のエラーのみが表示され、残りのアプリケーションは正常に動作します。
各コンポーネントの重要な構成
以下は、コンポーネントです。sandboxサービスの環境変数は、生産 compose のデフォルト値です。
| 変数 | デフォルト値 | 説明 |
|---|---|---|
SANDBOX_API_KEY | aivory-bundled-sandbox | bearer 認証キーは、appsidecar キーなし スタートを拒否、試験用常時比較 |
SANDBOX_IMAGE | ghcr.io/hjxwz123/aivory-sandbox:latest | 各セッションの時刻表 |
SANDBOX_PULL_ON_START | 1 | 起動時に実行時刻鏡を押して、最初の実行が失敗しないようにします。 |
SANDBOX_NETWORK | none | 会話コンテナネットワーク。noneネットワークを完全に断ち切る;bridgeネットワーク(たとえば、実行時)pip install) |
SANDBOX_MEMORY | 2g | 単一セッションコンテナのメモリ上限 |
SANDBOX_CPUS | 1 | 単一セッションコンテナのCPU上限 |
SANDBOX_MAX_SESSIONS | 16 | 同時に生存するセッションコンテナの数の上限 |
SANDBOX_EXEC_TIMEOUT_CAP_MS | 600000 | 単一実行時間のハードウェア上限(10分) |
SANDBOX_IDLE_TTL_CAP_SECONDS | 86400 | リサイクルウィンドウのハードワーク上限(24時間) |
SANDBOX_READ_ONLY_ROOTFS | 1 | セッション コンテナ ルート ファイル システム 読み込みのみ、防御ディスク 攻撃を満たす |
SANDBOX_WORKSPACE_SIZE | 512m | 読書モデルのみ/workspacetmpfs のサイズを書く |
SANDBOX_LOCAL_STORAGE_DIR | /var/lib/aivory/sandbox-archives | ローカルワークゾーンアーカイブカタログ、持続的なボリュームでゼロ配置持続化を実現 |
SANDBOX_API_KEY:アプリと共有する認証証
sidecar は「ドライブホスト Docker」の能力にさらされ、ホスト RCE に相当します。認証は強制的:key for スペースタイム sidecar 直接起動を拒否(唯一の例外は明示的な設定)SANDBOX_ALLOW_NO_AUTH=1(信頼性の高い開発環境のみ)appサービスとsandboxサービスは同じ値を設定する必要があります。強力なキーを生成する:
openssl rand -hex 24
SANDBOX_NETWORK:デフォルトのネットワーク切断、ネットワークにはコストがかかります
仮認noneセッションコンテナにはネットワークが全くなく、ユーザコードも存在しません。pip install変更の要請もできません。bridge後コードはネットワークに接続できますが、コストは明確にしてください:
ネットワークのサンドボックスは、ユーザーのコードがセッション内のデータ(アップロードされたファイル、生成された中間結果)を意外なアドレスに送信したり、ネットワーク内のサンドボックスのコンテナにアクセスできるサービスをスキャンしたり、攻撃したりすることができることを意味します。パッケージをインストールしたり、外部データをスキャンしたりする必要がある場合を除き、none。
リソース上限:MEMORY / CPUS / MAX_SESSIONS
SANDBOX_MEMORY(仮認)2g)およびSANDBOX_CPUS(仮認)1個々のセッションコンテナを制限する。SANDBOX_MAX_SESSIONS(仮認)16) 同時に生存するセッションの合計数を制限します。最悪の状況でホスト容量を推定します。MAX_SESSIONS x MEMORYセッションコンテナが占める可能性のあるメモリの総量です。SANDBOX_MAX_CONCURRENT_EXECS(デフォルト4)同時実行の総数を制限し、SANDBOX_PIDS_LIMIT(デフォルト256)防フォーク爆弾。
sidecar コントロール面自体も compose に制限されているmem_limit: 1g / pids_limit: 512メモリに最大200MBのワークスペース tar パッケージをバックアップする。SANDBOX_MAX_ARCHIVE_BYTES),mem_limitこの値の上に残る余分な量を保持する。
2 つの「ハードマップ」:EXEC_TIMEOUT_CAP_MS と IDLE_TTL_CAP_SECONDS
この2つの変数は運用層の天井管理コンソールの調整可能な設定と連携する:
- 管理者によるバックグラウンドでの単一実行超過時間(
sandbox_exec_timeout_sec)に拘束される。SANDBOX_EXEC_TIMEOUT_CAP_MS(デフォルトでは600000ms、すなわち10分以内) - 管理者設定の無償回収ウィンドウ(
sandbox_idle_ttl_sec)に拘束される。SANDBOX_IDLE_TTL_CAP_SECONDS(デフォルトは86400s、すなわち24時間以内) フロントがダウンロードされない場合、sidecar は 30 分間のフリーセッションをリサイクルします。
つまり、管理者は天井の下で短縮することができるが、常に compose で定められた上限を維持することができない。
ディスク保護ライン:READ_ONLY_ROOTFS / WORKSPACE_SIZE
SANDBOX_READ_ONLY_ROOTFS=1(デフォルトオープン) セッションコンテナのルートファイルシステムは読み込みのみで、3箇所しか書き込みできませんし、サイズ上限のtmpfs があります。
| ルート | 小さな源 | 仮認 |
|---|---|---|
/workspace | SANDBOX_WORKSPACE_SIZE | 512m |
/tmp | SANDBOX_TMPFS_SIZE | 256m |
ユーザー$HOME | SANDBOX_TMPFS_SIZE | 256m |
したがって、単一のセッションでは、どのように書くかに関わらず、ファイルがホストディスクを満たすことはできません。/workspace/uploads/製品コードを書き込む/workspace/outputs/全て受けるWORKSPACE_SIZE制限 より大きなワークスペース(ビッグデータセットを処理するなど)が必要な時間調整SANDBOX_WORKSPACE_SIZEtmpfs がメモリを占めることに注意してください。
SANDBOX_LOCAL_STORAGE_DIR: ワークスペースアーカイブの永続化
セッションコンテナがリサイクルされた場合(無期限または明示的に破壊された場合)、sidecar は/workspacetar アーカイブとして保存する; 同じ セッションは、次回コードを実行するときに自動的に回復します。会話IDキーとして、セッションコンテナを1回変えても、ワークスペースのコンテンツは回収され続けます。
SANDBOX_LOCAL_STORAGE_DIRローカルアーカイブディレクトリを指定し、compose がその名に貼り付けました。sandbox-archives永続ボリュームでは、ゼロ構成永続化を実現し、S3/OSS/MinIOは必要ありません。
- この変数環境変数によって設定できるリクエストまたは管理コンソールからの値を決して受け入れません(sidecar は root で実行され、docker.sock を保有し、リモートで書き込みパスを指定することは、ホストの書き込み面を開くことに等しい)。
- 空の場合、ローカルアーカイブは有効でなく、リサイクルは失われます(reaped = gone)。
- 単一ノードにのみ適用: 通常の Docker ボリュームはコピー間で共有されず、複数のコピーのデプロイは S3/OSS バックエンドに変更する必要があります。
- アーカイブは最善の取り組みです: 200 MiB を超えるワークスペースがアーカイブをジャンプしてログを記録し、アーカイブ/回復の失敗によりリクエストの実行が失敗しません。
コンソールの管理が可能
compose 環境変数に加えて、一部の行動はコンソールの管理で行うことができます。場所設定オンラインで変更し、再起動する必要はありません:
| バックセット | 役割 | 縛り |
|---|---|---|
超過時間の実施(sandbox_exec_timeout_sec) | 各コードを実行する時間制限 | 被 SANDBOX_EXEC_TIMEOUT_CAP_MS制 |
リサイクル時間(sandbox_idle_ttl_sec) | コンテナのリサイクル時間はどのくらい? | 被 SANDBOX_IDLE_TTL_CAP_SECONDS制 |
保管(後部)storage_provider) | 職場のアーカイブはどこ? | local(デフォルト、すなわちテキスト地帯)s3 / aliyun_oss |
サンドボックス アドレスと key (sandbox_base_url / sandbox_api_key) | 環境変数をカバーするサンドボックス | 環境変数が有効に |
保管後の選択s3エンドポイント、バケット、クレジットを入力します。MinIO と任意の S3 互換性サービス同じ選択s3定義されたエンドポイントを記入すると、自動的に path-style アドレス + SigV4 サインに切り替わります。
安全な国境
サンドボックス コンテナレベルの隔離を使用し、各セッションコンテナにはロックアイテムが含まれています。
- root で動作しない,
--cap-drop ALL,--security-opt no-new-privileges。 - デフォルトネットワークなし(
--network none)。 - ルートドキュメントシステムのみ+ tmpfs の上限が付いている(上記を参照)、memory/cpu/pids/nofile の制限が付いている。
- 同一セッション内での実施連行グローバル同時配信が制限され、stdout/stderr は 32KB まで切断され、プロダクト リスト ファイルは 20MB まで、一度に最大 20MB まで、合計 50MB まで。
- 選択可能:通過
SANDBOX_SECCOMP_PROFILEセッションコンテナに seccomp profile を固定する (パスは sidecar コンテナ内で読み取れる必要がある) で、核の攻撃面をさらに狭めます。
sidecar は、Docker Daemon を駆動する必要があります。/var/run/docker.sockホスト上で root に等しい:Sidecar サービスにアクセスできる人はホストに等しい。
- sidecar ポートを公共のネットワークに暴露しないでください内蔵デプロイは完了しました(ポートのリリースはありません);独立したデプロイ時にインネットインターフェイスを結び付けるか、VPNを使用します。
SANDBOX_API_KEY強力なランダム値でなければなりません(内蔵スタックのプライベートネットワークのデフォルト値を除く)。- 生産環境は、裸のソケットの前に置くことをお勧めしますdocker-socket-proxycontainer create/start/exec/kill/inspect と image pull をリリースし、その他の API をすべて拒否し、Sidecar をリリースします。
DOCKER_HOST: tcp://socket-proxy:2375裸のソケットを貼らない。
これはコンテナ級の隔離で、単機自体のデプロイをサポートするのに十分ですが、ノーgVisor/microVM レベル.sidecar の HTTP プロトコルは安定契約であり、より高いセキュリティ要件のデプロイは実行バックエンドを gVisor、Firecracker などに置き換えることができます。app側面に変更は必要ありません。
さらに、sidecar が再起動すると、バンドが自動的に検出されます。aivory.sandbox=1タグの貯蔵容器は、トラッキングし、TTLに従ってリサイクルし続け、孤児容器を残さない。
独立した展開:サンドボックスを別のマシンに置く
コード実行は、CPU/メモリ密集した負荷であり、サンドボックスを独立したマシンに分解して、メインアプリケーションとリソースを奪うのを防ぐことができます。サンドボックスサービスには、独立した公開倉庫と映像があります。
1. サンドボックス 機内での展開
git clone https://github.com/hjxwz123/aivory-sandbox.git
cd aivory-sandbox
export OWNER=hjxwz123
export SANDBOX_API_KEY=$(openssl rand -hex 24)
printf 'SANDBOX_API_KEY=%s\n' "$SANDBOX_API_KEY" # 保存这个值
docker compose pull
docker compose up -d
独立した compose は sidecar をホストにリリースします48217ポート(容器内はまだ 8000)。
curl -H "Authorization: Bearer $SANDBOX_API_KEY" http://localhost:48217/healthz
戻る{ok, docker, image}即準備です。
2.過去を指す主なアプリケーション
主な応用.env2 つの変数を変更し、メイン スタックから内蔵の変数を削除する (または起動しない)sandboxサービス:
SANDBOX_BASE_URL=http://<沙箱机内网地址>:48217
SANDBOX_API_KEY=<第 1 步生成的同一个值>
環境変数を変更せずに直接管理コンソールで記入することもできます。sandbox_base_url / sandbox_api_key背景値は環境変数を優先する。
内蔵のキー(aivory-bundled-sandbox)は「サンドボックス ポートなし、プライベート ネットワークのみ」の前提でのみ受け入れられます。サンドボックス がリアル ネットワーク カード ポートを監視すると、キーを取得した誰でも、ホスト コンピュータの Docker をドライブできます。独立したデプロイは、openssl rand -hex 24新しい key を生成し、ファイアウォール/セキュリティ グループで48217メインアプリケーションサーバーのみにアクセスできるように制限し、両方のマシン間のインネットまたはVPNリンクを可能な限り使用してください。
故障チェック
| 現象 | チェック方向 |
|---|---|
| 最初のコードは失敗しました。 | 冷たくなった時点で、画面が止まらないので、見てください。docker compose logs sandbox健康診断は、120sを予約しました。start_period |
| 健康診断は不健康です。 | 「Sidecar」がDocker DAEMONに搭載されていない/var/run/docker.sock持ち歩き、宿主のDAEMONが正常 |
| sidecar スタート 終了 | SANDBOX_API_KEYSidecar はキーなしで起動を拒否するように設計されています。 |
コード内pip install失敗 | 仮認SANDBOX_NETWORK=noneネットワークなし、リスク評価後の変更bridge |
| 書類のディスクが満載。 | 打った/workspacetmpfsの上限、拡大SANDBOX_WORKSPACE_SIZE |
| リサイクル後に失われた職場 | SANDBOX_LOCAL_STORAGE_DIR未設定または相応のボリュームが貼り付けられていないか、またはバックアップstorage_provider清掃された |
| 他の機能への影響 | 起こらないべき:appサンドボックスはソフト依存であり、コード実行機能のみがエラーを報告します。 |