인바운드 트래픽 지원 - AWS Panorama

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

인바운드 트래픽 지원

애플리케이션 코드와 함께 HTTP 서버를 실행하여 로컬에서 애플리케이션을 모니터링하거나 디버깅할 수 있습니다. 외부 트래픽을 처리하려면 AWS Panorama 어플라이언스의 포트를 애플리케이션 컨테이너의 포트에 매핑합니다.

중요

기본적으로 AWS Panorama 어플라이언스는 어떤 포트에서도 들어오는 트래픽을 수락하지 않습니다. 어플라이언스에서 포트를 열면 보안 위험의 가능성이 발생합니다. 이 기능을 사용할 때는 외부 트래픽으로부터 어플라이언스를 보호하고 인증된 클라이언트와 어플라이언스 간의 통신을 보호하기 위한 추가 조치를 취해야 합니다.

이 가이드에 포함된 샘플 코드는 데모용이며 인증, 권한 부여 또는 암호화를 구현하지 않습니다.

어플라이언스에서 8000~9000 범위의 포트를 열 수 있습니다. 이러한 포트를 열면 모든 라우팅 가능한 클라이언트로부터 트래픽을 수신할 수 있습니다. 애플리케이션을 배포할 때 열려는 포트를 지정하고 어플라이언스의 포트를 애플리케이션 컨테이너의 포트에 매핑합니다. 어플라이언스 소프트웨어는 트래픽을 컨테이너로 전달하고 다시 요청자에게 응답을 보냅니다. 지정한 어플라이언스 포트에서 요청이 수신되고 응답은 임의의 임시 포트로 전송됩니다.

인바운드 포트 구성

애플리케이션 구성의 세 위치에서 포트 매핑을 지정합니다. 코드 패키지가 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 리포지토리에서 지침을 참조하십시오.