Skip to content

Placement 결정 로직 테스트 데이터 및 시뮬레이션·모니터링 페이지 기획서

목적: Placement 결정(기존 노드 배치 vs 새 서버 생성) 로직을 검증·증명·테스트하기 위해, (1) 순서대로 들어오는 주문(Order) 형태의 테스트 데이터를 정의하고, (2) 해당 주문이 들어왔을 때 서버 생성·Frappe 설치·DB/Redis 설정·동적 적층 리소스 관리를 시뮬레이션하며 결과를 모니터링할 수 있는 페이지를 만드는 요건을 정리한다. 코드 생성 없음 — 기획·요건만.

참조: tenant-onboard-resource-allocation-flow-plan.md, placement.ts (decidePlacement, R2/R4), prego-control-plane README, provision-tenant-pipeline.md, internal.ts (metrics/summary, dashboard), runbook prego-control-plane-dashboard.md. 서버 생성: 실제 파이프라인은 prego-pulumi(Hetzner) + provision-tenant.yml 연동으로 수행됨 — hetzner-pulumi-trial-dedicated-server-resource-model.md.


1. 배경: Placement 로직과 검증 목표

항목내용
Placement 입력tenant_id, plan_tier, requested_region.
Placement 출력create_new_server (true면 새 서버 생성), target_server_id (기존 노드에 배치 시 node_id).
현재 규칙 (R2)region·status=Active·role(shared/dedicated) 일치, server_metrics 기준 memory_pct < 임계값, tenant_count < 임계값 인 노드만 후보. 후보 중 tenant_count·memory_pct 오름차순으로 1개 선택.
현재 규칙 (R4)Enterprise → dedicated 노드만; Free/Basic/Professional → shared 또는 role NULL 노드.
검증 목표다양한 플랜·리전·순서로 주문이 들어올 때, (1) 기대한 대로 기존 노드에 붙는지 / 새 서버가 생성되는지, (2) 이후 실제(또는 시뮬레이션) 프로비저닝 단계(서버·Frappe·DB·Redis·리소스 적층)가 로그/상태로 추적·모니터링 가능한지.

2. 테스트 데이터: Order 10건 (순서 보장)

아래는 Order를 “POST /v1/tenants 에 대응하는 한 건의 테넌트 생성 요청”으로 정의한다. 순서대로 1 → 10 적용 시 Placement·리소스 적층을 검증할 수 있도록 설계한다.

2.1 초기 상태 (시뮬레이션/테스트 전)

리소스시나리오 A (빈 상태)시나리오 B (1노드 존재)
nodes0건sg, Active, shared 1건 (예: node-sg-001), host 설정
server_metrics없음node-sg-001: memory_pct=20, tenant_count=0 (또는 원하는 값)
tenants_master / provision_jobs비어 있음비어 있음 (또는 기존 테스트 데이터 정리)
  • 시나리오 A: 첫 주문부터 “노드 없음 → create_new_server” 가 나와야 함.
  • 시나리오 B: 첫 주문은 “기존 노드에 배치”, 메트릭을 올려 가며 N번째부터 “create_new_server” 또는 “포화로 새 서버”가 나오는지 검증.

2.2 Order 10건 정의 (예시)

#Order IDplan_tierregionsubdomain_slug기대 Placement (예시)비고
1order-01freesgsim-acmecreate_new_server (노드 0개) 또는 target_sg_001 (노드 1개)첫 주문: 빈 상태면 새 서버, 있으면 기존 노드.
2order-02freesgsim-betause_existing (target_sg_001)동일 region·shared, 용량 여유 있으면 기존 노드.
3order-03basicsgsim-gammause_existing (target_sg_001)shared 노드 재사용.
4order-04professionalsgsim-deltause_existing (target_sg_001)shared.
5order-05freesgsim-epsilonuse_existing 또는 create_new_servertenant_count/memory_pct 임계값 근처에서 분기 검증.
6order-06enterprisesgsim-enterprise1create_new_server (dedicated 없음) 또는 target_dedicated_001R4: Enterprise는 dedicated만. dedicated 노드 없으면 새 서버.
7order-07freeussim-us-alphacreate_new_server (us 노드 없음)리전 다름 → sg 노드 사용 불가 → 새 서버.
8order-08basicussim-us-betause_existing (target_us_001)7번으로 us 노드 생겼다면 재사용.
9order-09enterpriseeusim-eu-enterprisecreate_new_server (eu dedicated 없음)eu 전용 노드 없음 → 새 서버.
10order-10freesgsim-sg-omegause_existing (target_sg_001 또는 target_sg_002)sg shared 여유 노드 또는 포화 후 새 노드.
  • 실제 기대값은 초기 상태(시나리오 A/B), PLACEMENT_MEMORY_PCT_MAX / PLACEMENT_MAX_TENANTS_PER_NODE, 그리고 각 Order 처리 후 server_metrics 갱신 여부에 따라 달라진다. 기획서에서는 “검증 포인트”만 정의하고, 테스트 데이터 스펙으로는 위 10건의 payload(JSON)초기 nodes/server_metrics(선택) 를 명시한다.

2.3 Order Payload 스펙 (POST /v1/tenants body)

각 Order는 동일한 스키마를 따른다. 예시(Order 1):

{
"tier": "free",
"region": "sg",
"subdomain_slug": "sim-acme",
"subdomain_name": "sim-acme",
"company_name": "Sim Acme Corp",
"abbr": "SAC",
"admin_email": "admin@sim-acme.example.com",
"admin_name": "Admin One",
"admin_phone": "",
"additional_users": []
}
  • 10건 전체: order-01 ~ order-10 에 대해 tier(free/basic/professional/enterprise), region(sg/us/eu), subdomain_slug(고유 값) 등만 위 표에 맞게 치환한 JSON 배열로 보관. (실제 파일은 기획서 외부에서 “테스트 데이터 세트”로 관리 가능.)

2.4 테스트 데이터 산출물 (요건)

산출물설명
orders.json위 10건 Order의 POST /v1/tenants body 배열. 순서 유지.
initial_state (선택)시나리오 A/B용 nodes INSERT, server_metrics INSERT (SQL 또는 JSON). 테스트 전 D1 초기화 또는 시뮬레이션 입력으로 사용.
expected_placement (선택)Order별 기대 결과(create_new_server, target_server_id) — 시나리오·임계값별로 “기대 매트릭스” 표 또는 파일. 자동 검증 시 비교용.

3. 시뮬레이션·검증 범위

Order가 들어왔을 때 실제로 어떻게 서버가 생성되고, Frappe가 설치되고, DB/Redis가 설정되고, 리소스가 적층되는지를 다음 두 가지 방식으로 검증할 수 있도록 기획한다.

3.1 방식 A: Placement 전용 시뮬레이션 (드라이 런)

항목내용
입력초기 상태(nodes, server_metrics) + Order 1~10 순차.
처리실제 D1 쓰기 없이(또는 전용 테스트 DB에서) decidePlacement 만 호출하여 결과(create_new_server, target_server_id) 산출. 각 Order 후 가상 갱신: “이 노드에 배치됐다”고 가정하고 server_metrics.tenant_count +1, memory_pct 보정(선택).
목적Placement 로직 단위 검증. R2(용량)·R4(shared/dedicated) 동작 확인.
산출Order별 Placement 결과 + (선택) “가상 노드 상태 변화” 타임라인.

3.2 방식 B: E2E 시뮬레이션 또는 실제 파이프라인 연동

항목내용
입력동일 Order 10건 (또는 subset). 실제 POST /v1/tenants 호출 또는 동일 로직으로 D1에 tenants_master·provision_jobs 삽입 후 workflow_dispatch.
처리resolve-server → DNS → Ansible(Frappe, DB, Redis) → Zuplo Sync → provision-complete 콜백. (실제 인프라 사용 시 “실서버 생성” 발생; 시뮬레이션 모드가 있으면 Ansible/Pulumi를 mock 또는 skip하고 콜백만 시뮬레이션 가능.)
목적서버 생성·Frappe 설치·DB/Redis 설정·동적 적층이 로그·상태로 추적 가능한지 검증.
산출provision_jobs 상태, trace_events, tenant_runtime, server_metrics 갱신, 노드별 tenant_count·메모리 변화.

3.3 리소스·로그 기반 동적 적층 검증 포인트

검증 항목데이터 소스확인 내용
노드 배치provision_jobs.infra_mode, workflow 입력(create_new_server, target_server_id)Order별 “기존 노드” vs “새 서버” 결정이 기대와 일치하는지.
서버 생성Pulumi 출력, POST /internal/nodes, nodes 테이블create_new_server 시 실제 노드 등록·host 반영.
Frappe 설치Ansible 로그, provision-complete 호출, tenant_runtime (host, site_name, api_key_ref)테넌트별 사이트·API Key 생성.
DB/Redis 설정Ansible 인벤토리·vars, GET /internal/db-host, plan_limitsregion별 db_host, 플랜별 리소스 한도 반영.
적층 상태server_metrics (tenant_count, memory_pct), nodes, tenants_master노드별 “몇 테넌트가 올라와 있는지”, 포화 임계 초과 시 알림(R8)·다음 Placement에서 제외되는지.
로그·상태trace_events, provision_jobs.updated_at, Cloudflare Workers 로그, GitHub Actions run단계별 시각화·타임라인.

4. 모니터링 페이지 요건

Placement 및 (가능하면) 프로비저닝 단계까지 한 화면에서 시뮬레이션·검증·상태를 볼 수 있는 전용 페이지를 둔다.

4.1 페이지 목적

  • Placement 테스트 데이터(Order 10건) 를 로드하고, 순서대로 Placement를 실행(드라이 런 또는 실제 API 호출)한 결과를 표시.
  • 현재 리소스 상태(nodes, server_metrics, provision_jobs, tenants_master 요약)를 동적으로 표시.
  • Order 처리 후 “어떤 노드에 붙었는지 / 새 서버가 생성됐는지”, “Frappe·DB·Redis·Zuplo·콜백” 단계가 로그/상태 기준으로 어떻게 적층되는지 타임라인 또는 테이블로 모니터링.

4.2 기능 요건 (우선순위)

#기능설명
F1테스트 데이터 로드orders.json(10건) 업로드 또는 프리셋 선택(시나리오 A/B). 초기 상태(initial_state) 선택적 적용.
F2Placement 실행(시뮬레이션)Order 1~10 순차로 decidePlacement 호출(또는 내부 API). 결과 테이블: Order #, plan_tier, region, create_new_server, target_server_id, 비고.
F3현재 리소스 현황nodes(region, status, role, host), server_metrics(tenant_count, memory_pct, disk_pct), saturated_node_ids. 기존 GET /internal/metrics/summary 재사용 또는 전용 API.
F4프로비저닝 작업 목록provision_jobs 최근 N건: job_id, tenant_id, status, plan_tier, infra_mode, created_at. 클릭 시 상세(trace_id, 단계별 로그 링크).
F5Order → Job 매핑테스트 Order와 실제 provision_jobs 매핑(동일 subdomain_slug 또는 job_id). “이 Order가 어떤 job으로 처리됐는지” 표시.
F6타임라인/단계 뷰단일 job 선택 시: resolve-server → DNS → Ansible → Zuplo → provision-complete 단계별 상태·로그 링크. trace_events 기반 또는 workflow run 링크.
F7동적 적층 시각화노드별 “현재 테넌트 수·메모리 %” 막대 또는 테이블. Order 처리 순서에 따라 어떻게 쌓였는지(히스토리)는 선택.
F8시뮬레이션 모드 전환“Placement만 시뮬레이션(드라이 런)” vs “실제 API 호출(POST /v1/tenants) 후 workflow 연동” 전환. 실제 호출 시 경고 표시.

4.3 비기능 요건

항목내용
인증기존 내부 API와 동일하게 Bearer INTERNAL_API_KEY.
위치GET /internal/placement-simulation 또는 /internal/dashboard 아래 “Placement 시뮬레이션” 탭/섹션. 기존 dashboard-html 패턴 참고.
데이터 소스Control Plane D1(nodes, server_metrics, provision_jobs, tenants_master), GET /internal/metrics/summary, GET /internal/trace/:trace_id. Placement 시뮬레이션 전용 엔드포인트(예: POST /internal/placement-simulation/run)는 구현 시 설계.

4.4 화면 구성 (초안)

  • 상단: 테스트 데이터 선택(프리셋 10건) + “Placement 시뮬레이션 실행” 버튼 + (선택) 초기 상태 로드.
  • 중단: Order별 Placement 결과 테이블 (Order #, tier, region, create_new_server, target_server_id).
  • 하단 좌: 노드·메트릭 요약 (노드 목록, tenant_count, memory_pct, 포화 여부).
  • 하단 우: 최근 provision_jobs 목록 + job 선택 시 단계별 타임라인(트레이스/로그 링크).
  • 동적 적층: 노드별 테넌트 수·메모리 % 시각화(테이블 또는 간단 차트).

5. 구현 시 고려 사항 (기획 범위)

  • 테스트 데이터 파일 위치: prego-control-plane 또는 Prego/docs/planning 하위에 placement-test-data/ (orders.json, initial_state 시나리오별) 보관 시, 문서에서 경로만 명시.
  • 드라이 런 API: decidePlacement를 “D1 읽기만 하고 쓰지 않는” 모드로 호출하려면, 초기 상태를 인자(JSON)로 넘기는 전용 시뮬레이션 API가 필요할 수 있음. 기존 D1을 건드리지 않는 것이 목적이면 별도 엔드포인트 권장.
  • 실제 POST /v1/tenants 연동: 모니터링 페이지에서 “실제 주문 제출” 시 기존 www와 동일하게 job_id가 발급되고 workflow가 트리거됨. 테스트 환경·스테이징에서만 사용하고, subdomain_slug는 충돌하지 않는 접두사(sim-*) 유지.
  • R8 포화 알림: server_metrics가 갱신되는 경우, 포화 노드가 R8 Cron으로 ALERT_WEBHOOK_URL에 전달되는지도 검증 대상. 모니터링 페이지에서 “포화 노드 목록”이 이미 metrics/summary에 있으므로 동일 데이터로 표시 가능.

6. 요약

산출물내용
테스트 데이터순서 고정 Order 10건 (free/basic/professional/enterprise, sg/us/eu 혼합). orders.json + 선택적 initial_state(nodes, server_metrics).
시뮬레이션(A) Placement 전용 드라이 런으로 “기존 노드 vs 새 서버” 결정 검증. (B) 실제 POST /v1/tenants + workflow로 서버 생성·Frappe·DB/Redis·적층을 로그/상태로 검증.
모니터링 페이지테스트 데이터 로드 → Placement 실행 결과 표시, 노드·메트릭·provision_jobs·단계별 타임라인, 동적 적층 시각화. Bearer 인증, /internal 하위.

이 기획서를 바탕으로 테스트 데이터 파일(orders.json, initial_state) 구체화와 모니터링 페이지·시뮬레이션 API 구현 단계를 진행할 수 있다.

Help