インバウンドトラフィックへの対応 - AWS Panorama

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

インバウンドトラフィックへの対応

アプリケーションコードと一緒に HTTP サーバーを実行することで、アプリケーションをローカルでモニタリングまたはデバッグできます。外部トラフィックを処理するには、AWS Panorama アプライアンスのポートをアプリケーションコンテナのポートにマッピングします。

重要

デフォルトでは、AWS Panorama アプライアンスはどのポートでも着信トラフィックを受け付けません。アプライアンスのポートを開くことには、暗黙のセキュリティリスクがあります。この機能を使用するときは、外部トラフィックからアプライアンスを保護し、許可されたクライアントとアプライアンス間の通信を保護するための追加措置を講じる必要があります。

このガイドに含まれるサンプルコードはデモンストレーションを目的としており、認証、承認、暗号化は実装されていません。

アプライアンスでは 8000 ~ 9000 の範囲のポートを開くことができます。これらのポートを開くと、ルーティング可能なすべてのクライアントからのトラフィックを受信できます。アプリケーションをデプロイするときは、開くポートを指定し、アプライアンス上のポートをアプリケーションコンテナのポートにマッピングします。アプライアンスソフトウェアはトラフィックをコンテナに転送し、要求者に応答を送り返します。リクエストは指定したアプライアンスポートで受信され、応答はランダムなエフェメラルポートに送信されます。

インバウンドポートの設定

ポートマッピングはアプリケーション設定の 3 つの場所で指定します。コードパッケージの package.json では、コードノードがリッスンするポートを network ブロック内で指定します。次の例では、ノードがポート 80 でリッスンすることを宣言しています。

packages/123456789012-debug_server-1.0/Package.json
"outputs": [ { "description": "Video stream output", "name": "video_out", "type": "media" } ], "network": { "inboundPorts": [ { "port": 80, "description": "http" } ] }

アプリケーションマニフェストでは、アプライアンスのポートをアプリケーションのコードコンテナのポートにマップするルーティングルールを宣言します。次の例では、デバイスのポート 8080 を code_node コンテナのポート 80 にマッピングするルールを追加します。

graphs/my-app/graph.json
{ "producer": "model_input_width", "consumer": "code_node.model_input_width" }, { "producer": "model_input_order", "consumer": "code_node.model_input_order" } ], "networkRoutingRules": [ { "node": "code_node", "containerPort": 80, "hostPort": 8080, "decorator": { "title": "Listener port 8080", "description": "Container monitoring and debug." } } ]

アプリケーションをデプロイするときは、AWS Panorama コンソールで同じルールを指定するか、CreateApplicationInstance API に渡されるオーバーライドドキュメントを使用して指定します。アプライアンスでポートを開きたいことを確認するために、デプロイ時にこの設定を提供する必要があります。

graphs/my-app/override.json
{ "replace": "camera_node", "with": [ { "name": "exterior-north" } ] } ], "networkRoutingRules":[ { "node": "code_node", "containerPort": 80, "hostPort": 8080 } ], "envelopeVersion": "2021-01-01" } }

アプリケーションマニフェストで指定されているデバイスポートが別のアプリケーションで使用されている場合は、オーバーライドドキュメントを使用して別のポートを選択できます。

トラフィックを処理する

コンテナのポートが開いていると、ソケットを開いたり、サーバーを実行して受信リクエストを処理したりできます。この debug-server サンプルは、コンピュータービジョンのアプリケーションコードと一緒に稼働する HTTP サーバーの基本的な実装を示しています。

重要

このサンプル実装は、実稼働環境では安全ではありません。アプライアンスが攻撃に対して脆弱にならないようにするには、コードとネットワーク構成に適切なセキュリティ制御を実装する必要があります。

packages/123456789012-DEBUG_SERVER-1.0/application.py — HTTP サーバー
# HTTP debug server def run_debugger(self): """Process debug commands from local network.""" class ServerHandler(SimpleHTTPRequestHandler): # Store reference to application application = self # Get status def do_GET(self): """Process GET requests.""" logger.info('Get request to {}'.format(self.path)) if self.path == '/status': self.send_200('OK') else: self.send_error(400) # Restart application def do_POST(self): """Process POST requests.""" logger.info('Post request to {}'.format(self.path)) if self.path == '/restart': self.send_200('OK') ServerHandler.application.stop() else: self.send_error(400) # Send response def send_200(self, msg): """Send 200 (success) response with message.""" self.send_response(200) self.send_header('Content-Type', 'text/plain') self.end_headers() self.wfile.write(msg.encode('utf-8')) try: # Run HTTP server self.server = HTTPServer(("", self.CONTAINER_PORT), ServerHandler) self.server.serve_forever(1) # Server shut down by run_cv loop logger.info("EXITING SERVER THREAD") except: logger.exception('Exception on server thread.')

サーバーは /status パスで GET リクエストを受け付けて、アプリケーションに関する情報を取得します。また、アプリケーションを再起動するための /restart への POST リクエストも受け付けます。

この機能を実証するために、サンプルアプリケーションは別のスレッドで HTTP クライアントを実行します。クライアントは起動後すぐにローカルネットワーク経由で /status パスを呼び出し、数分後にアプリケーションを再起動します。

packages/123456789012-DEBUG_SERVER-1.0/application.py — HTTP クライアント
# HTTP test client def run_client(self): """Send HTTP requests to device port to demnostrate debug server functions.""" def client_get(): """Get container status""" r = requests.get('http://{}:{}/status'.format(self.device_ip, self.DEVICE_PORT)) logger.info('Response: {}'.format(r.text)) return def client_post(): """Restart application""" r = requests.post('http://{}:{}/restart'.format(self.device_ip, self.DEVICE_PORT)) logger.info('Response: {}'.format(r.text)) return # Call debug server while not self.terminate: try: time.sleep(30) client_get() time.sleep(300) client_post() except: logger.exception('Exception on client thread.') # stop signal received logger.info("EXITING CLIENT THREAD")

メインループはスレッドを管理し、終了時にアプリケーションを再起動します。

packages/123456789012-DEBUG_SERVER-1.0/application.py — メインループ
def main(): panorama = panoramasdk.node() while True: try: # Instantiate application logger.info('INITIALIZING APPLICATION') app = Application(panorama) # Create threads for stream processing, debugger, and client app.run_thread = threading.Thread(target=app.run_cv) app.server_thread = threading.Thread(target=app.run_debugger) app.client_thread = threading.Thread(target=app.run_client) # Start threads logger.info('RUNNING APPLICATION') app.run_thread.start() logger.info('RUNNING SERVER') app.server_thread.start() logger.info('RUNNING CLIENT') app.client_thread.start() # Wait for threads to exit app.run_thread.join() app.server_thread.join() app.client_thread.join() logger.info('RESTARTING APPLICATION') except: logger.exception('Exception during processing loop.')

サンプルアプリケーションをデプロイするには、このガイドの GitHub リポジトリにある「手順」を参照してください。