最終更新: a few seconds ago Remove Netlify-related code from main (grafted, HEAD)
リモート CAD
概要
遠隔地にあるサーバに画像を暗号化して送信し、そこで CAD を実行させ、その結果を暗号化して受信するための仕組みを構築する。
リモートサーバとしては以下のようなものを想定している。
- AWS Lambda や Google Cloud Run のような従量課金制のクラウド Docker コンテナ実行環境
- Intel TDX を用いたセキュアな VM
処理の大まかな流れ
現在の CIRCUS の CAD プラグインは Preprocess, Main process, Postprocess から成立しているが、このうち Main process について新たな処理の分岐を導入する。

各ステップの概要をもう少し詳しく述べると以下の通り。詳細は CS Core 概要を参照。
-
Preprocess:
-
CAD 用の一時作業ディレクトリ (
/tmp/circus/${jobId}) を作る。 -
一時ディレクトリの
inに DICOM シリーズをボリュームに変換したものを作っていく。/tmp/circus /a1b2c3 (job ID) /in /0.mhd /0.json /0.vol /1.mhd /1.json /1.vol
-
-
Main process:
-
一時ディレクトリの
inを外部ボリュームとして/circus/inにマウント (-v /tmp/circus/${jobId}:/circus) しつつ、CAD プラグインとなる Docker イメージを起動する。CAD の実行終了を待つ。結果は/circus/outに書かれる。/tmp/circus /a1b2cd (job ID) /in (略) /out results.json log.txt image1.png image2.png -
またその際にリアルタイムのログをストリームとして受け取ることができる(上記の
log.txt)。このリアルタイムログは CIRCUS の責任でout内に書き込まれる。
-
- Postprocess:
outディレクトリに書かれたresult.jsonの結果が正しいかどうかをバリデーションし、問題なければその結果を MongoDB に書き込む。outに書かれたその他のファイル(ログも含む)をプラグイン結果格納ディレクトリにコピーする。- 一時フォルダを削除する。
今回のリモート CAD では Preprocess と Postprocess については全く同じ処理でよい(というか設計上、全く同じ処理であるべき)。Main proces の実行方法のみを以下のように変更する。
- Main process: リモート CAD を起動し、preprocess の結果を、暗号化ストリームで転送する。実行ログと CAD 実行結果それぞれ暗号化ストリームで受信し、それを一時ディレクトリの
outに一旦書いていく。
「リモート CAD をどう起動するのか」といった部分についてはリモートの CAD 実行環境の要件によって異なる可能性があるため、ここについては拡張可能にする。具体的には以下のインターフェースとサービス定義を参照。
新しい CAD 定義
現在の pluginDefinition は "type": "CAD" として Docker イメージを登録するが、ここに新たなプラグインタイプである "type": "CAD+remote" を追加する。
{
"type": "CAD+remote",
"adapter": "HttpRemoteCadAdapter",
"parameters": {
"endpoint": "https://abcdefg123.execute-api.ap-northeast-1.amazonaws.com/prod/users",
"authentication": "aaaaabbbbcccccdddddeeeee",
"maxConcurrency": 5,
"env": {
"encryptSecret": "rsa:111122223333"
}
}
}
endpoint: リモート CAD 実行環境を起動するための URL。authentication: CIRCUS を認証するために必要な文字列。複数の CIRCUS サーバが同じ URL にアクセスする場合にそれらを区別するためにも用いる。env: その他にアダプタによって使用される文字列。maxConcurrency: ここに書いてある数までは CAD を同時に実行できるようにする。AWS Lambda のような環境では無制限でもなんとかなる。一方でリモート環境の制限によっては同時実行数を 1 にする必要があることもある。プリプロセスの部分ではそれなりに CIRCUS 本体に負荷がかかることにも注意が必要。
新しいプロトコル
CIRCUS プラグインマネージャーでは、以下に似たインターフェースのアダプタを「サービス」として実装する(具体的な例はリポジトリを参照)。
interface RemotePluginConfig {
endPiont: string;
authentication: string;
env: Record<string, string>;
}
type RemotePluginResult = {
logStream: Readable;
result: Promise<
| { status: 'finished'; outputFileStream: Readable }
| { status: 'failed'; message: string }
>;
};
interface RemoteCadAdapter {
run: (
remotePluginDefinition: RemotePluginConfig,
inputFileStream: Readable,
signal: AbortSignal // 実行キャンセル用
) => RemotePluginResult;
}
CIRCUS がデフォルトで用意する実際のアダプタの実装は HttpRemoteCadAdapter のみ。必要に応じて、HTTP 通信が使えないリモート CAD 環境が出てきた場合などに、このアダプタを差し替えて利用できるようにする。
このアダプタに対応するウェブサーバが必要。以下のようなものを実装する。
- ダミー(デバッグ用)
- AWS Lambda や GKE などのリモートコンテナ実行環境を呼び出すアダプタ。