On-Demand Plugin Runtime

이 문서는 plugin을 항상 떠 있는 HTTP 서비스로 둘지, 아니면 Runner가 필요할 때만 시작할지를 평가합니다.

결정 요약

현재의 always-on plugin 모델은 유효합니다. 하지만 그것만이 유일한 정답으로 볼 이유는 없습니다.

AisOpsFlow의 다음 단계 아키텍처로는 다음이 더 적합합니다.

  • Core, Runner, plugin 의 논리적 경계는 유지
  • Runner가 plugin을 필요할 때 시작
  • plugin은 manifest 와 entrypoint 계약을 가진 패키지로 관리
  • “폴더 안의 임의 파일 실행”을 실행 모델로 삼지 않음

요약하면:

  • plugin 은 계속 실행 어댑터
  • skill 은 계속 판단 자산
  • Runner가 plugin lifecycle manager가 됩니다

왜 on-demand 실행을 고려하는가

plugin 수가 늘어나면 always-on 모델은 운영 비용이 커집니다.

예:

  • Slack plugin
  • Gmail plugin
  • Microsoft Email plugin
  • Microsoft Office plugin
  • DB query plugin

이것들을 전부 항상 띄워두면 다음이 늘어납니다.

  • 컨테이너 수
  • 유휴 메모리 사용량
  • secret 배포 지점
  • healthcheck 잡음
  • 업그레이드 조정 비용

자주 쓰지 않는 plugin이 많다면 always-on 서비스는 낭비가 큽니다.

대안 비교

옵션 A: Always-on plugin services

모델:

  • 각 plugin이 Runner 옆에서 계속 실행
  • Runner는 HTTP로 plugin 호출

장점:

  • 이해하기 쉬운 모델
  • 격리가 비교적 명확함
  • 언어/runtime 독립성 좋음
  • health와 observability 구성이 단순함

단점:

  • plugin 수가 runtime footprint에 바로 반영됨
  • 안 쓰는 plugin도 계속 리소스를 사용
  • 컨테이너와 배포 wiring이 계속 늘어남

옵션 B: Runner-managed on-demand plugin processes

모델:

  • Runner가 capability를 로컬 plugin package로 resolve
  • 필요할 때만 plugin 프로세스를 시작
  • 요청 처리 후 종료하거나 짧게 재사용

장점:

  • 유휴 리소스 사용량 감소
  • 항상 떠 있어야 하는 컨테이너 수 감소
  • plugin 수가 많을수록 고객 배포 단순화

단점:

  • Runner가 lifecycle을 관리해야 함
  • packaging이 표준화되지 않으면 local runtime 의존성이 Runner 문제로 옮겨감
  • 장애 처리 복잡도 증가

옵션 C: Runner-managed on-demand plugin containers

모델:

  • 논리 흐름은 옵션 B와 같음
  • 실제 실행 단위는 여전히 컨테이너

장점:

  • raw process보다 더 나은 격리
  • always-on보다 낮은 idle 비용
  • OCI 배포 모델 유지 가능

단점:

  • 구현 복잡도가 가장 큼
  • cold-start 비용
  • 로컬 container runtime 연동 필요

권장 선택

이 제품에서는 optional integration이 많아지는 방향이라면 옵션 B가 기본 방향으로 가장 적절합니다.

이유:

  • steady-state 운영 비용을 줄일 수 있음
  • Core/Runner/plugin 경계를 유지할 수 있음
  • 고객 관리 환경에서 많은 sidecar보다 실용적임
  • capability resolution을 Runner 안에 둘 수 있어 실행 정책과 잘 맞음

격리가 더 중요해지면 옵션 C는 좋은 후속 확장입니다.

옵션 A는 다음 경우에는 여전히 적절합니다.

  • 호출 빈도가 높은 plugin
  • long-lived socket이나 webhook listener가 필요한 plugin
  • integration이 한두 개 수준인 단순 배포

중요한 구분

on-demand plugin 실행이 plugin을 skill로 바꾸는 것은 아닙니다.

역할 구분은 그대로입니다.

  • skill = Core에서의 판단과 plan 생성
  • plugin = 실제 외부 실행 어댑터

바뀌는 것은 runtime model 뿐입니다.

  • 항상 떠 있는 서비스
  • Runner가 관리하는 lifecycle

필요한 설계 제약

Runner가 plugin을 on-demand로 시작하더라도, 계약 없이 폴더의 임의 파일을 실행하는 방식은 피해야 합니다.

그 방식은 보안, 호환성, 운영 측면에서 너무 약합니다.

대신 다음을 요구해야 합니다.

  • plugin manifest
  • 선언된 capability
  • 선언된 entrypoint
  • 선언된 runtime type
  • 선언된 환경변수
  • 선언된 timeout / concurrency 모델

권장 plugin package 형태

예:

api_version: plugin-runtime/v1
plugin_name: microsoft-email
plugin_version: 0.1.0
runtime: node
entrypoint: src/index.js
transport: stdio-json
capabilities:
  - microsoft.mail.read
  - microsoft.mail.send
limits:
  startup_timeout_seconds: 10
  request_timeout_seconds: 30
  max_concurrency: 4
env:
  required:
    - MICROSOFT_GRAPH_ACCESS_TOKEN

가능한 runtime 값:

  • node
  • python
  • binary
  • 이후 필요하면 container

권장 실행 흐름

  1. Core가 workflow 또는 planned job 선택
  2. workflow step 이 plugin capability 참조
  3. Runner가 capability를 설치된 plugin package로 resolve
  4. Runner가 manifest와 로컬 정책 검증
  5. Runner가 plugin runtime 시작
  6. Runner가 요청 payload 전달
  7. plugin이 정규화된 JSON 반환
  8. Runner가 결과, 종료 상태, 실행 시간, 오류 수집
  9. Runner가 plugin 프로세스를 종료하거나 pool에 유지

Capability 기반 resolution

Core는 보통 하드코딩된 실행 파일 경로보다 capability를 지정하는 것이 좋습니다.

예:

{
  "kind": "plugin_call",
  "plugin_capability": "gmail.read",
  "input": {
    "query": "from:alerts@example.com newer_than:1d",
    "page_size": 20
  }
}

그 다음 Runner가 다음을 resolve 합니다.

  • capability -> plugin package
  • plugin package -> entrypoint
  • entrypoint -> process invocation

이 구조가 tenant/env 별 매핑 유연성을 유지합니다.

이 모델에서 Runner 책임

Runner는 다음 lifecycle 기능을 가져야 합니다.

  • plugin registry
  • manifest validation
  • capability resolution
  • process startup / shutdown
  • timeout enforcement
  • concurrency control
  • stdout/stderr capture
  • secret injection
  • request/result normalization
  • audit logging

이 부분이 없으면 on-demand 실행은 불안정해집니다.

보안 모델

최소 제어:

  • 설치된 plugin allowlist
  • 서명된 manifest 또는 신뢰된 로컬 설치 경로
  • workflow payload에서 임의 shell 실행 금지
  • plugin별 환경변수 allowlist
  • 강제 실행 timeout
  • 가능하면 memory/process 제한
  • 구조화된 로그

강력 권장:

  • Runner 전용 plugin 설치 디렉터리 사용
  • plugin 프로세스 전용 OS 사용자 또는 service account
  • immutable plugin version 참조
  • plugin hash 또는 signature 검증

언제 always-on 이 더 나은가

다음 plugin은 always-on 유지가 더 적합합니다.

  • inbound webhook 수신
  • long-lived session 유지
  • cold-start 없이 매우 빠른 응답 필요
  • 운영상 핵심이고 호출 빈도가 높음

예:

  • Slack interactive approval callback
  • webhook receiver
  • 실시간 chat bridge

Hybrid 권장안

AisOpsFlow의 장기 형태는 hybrid가 가장 적절할 가능성이 높습니다.

  • inbound 또는 고빈도 integration은 always-on
  • 저빈도 outbound integration과 문서/데이터 접근은 on-demand

예:

  • slack 은 always-on 유지
  • gmail 은 on-demand 가능
  • microsoft-email 은 on-demand 가능
  • microsoft-office 은 on-demand 가능
  • db-query 는 on-demand 가능

왜 이 선택이 더 낫나

이 선택은 제품에 다음을 제공합니다.

  • 낮은 기본 footprint
  • 유지되는 아키텍처 경계
  • 늘어나는 integration에 대한 더 나은 확장성
  • 실행 정책을 통제하기 쉬운 구조

비용은 Runner 복잡도 증가이지만, plugin 수가 늘어날 제품이라면 그 비용은 정당화됩니다.