VDI Logic and Architecture KR
Architecture
UniFi-/QNAP-스타일 VDI 컨트롤러 — 기술 개요
목표
UniFi 또는 QNAP OS와 같은 웹 기반 관리자 콘솔과 사용자 포털을 가진 VDI 솔루션을 만든다.
하나의 메인 컴퓨터(Proxmox VE)가 여러 개의 가상머신(VM)을 운영하고,
사용자는 PoE 기반 씬 클라이언트(라즈베리파이/ThinOS 계열)에서 ID와 비밀번호로 로그인하여
자신의 VM에 접속한다.
관리 화면은 직관적이고 단순해서, 소규모 팀도 별도의 IT 부서 없이 운영할 수 있다.
1) 페르소나 & 핵심 흐름
| 페르소나 | 필요사항 | 핵심 화면 | 성공 기준 |
|---|---|---|---|
| 관리자(Admin) | Proxmox 연결, 템플릿 등록, VM 생성/할당, 모니터링, 스냅샷/복원 | 설치 마법사, 클러스터 개요, VM 목록, 템플릿 관리, 사용자/팀 관리, 스냅샷 | 템플릿에서 VM 생성 ≤3분, 원클릭 시작/중지/복원 |
| 팀 운영자(Operator) | 팀 단위 운영 관리, 스케줄/쿼터 | 팀 대시보드, 스케줄, 자원 할당 | 팀 VM 안정 운영, 복원 가능, 기본 제한 적용 |
| 최종 사용자(User) | 어떤 클라이언트에서도 로그인 후 내 VM 접속 | 로그인 화면, 내 VM 목록 | 로그인 → 2클릭 이내 접속, 자동 재접속 지원 |
| 설치자(Installer) | 초기 설정/진단 | 설치 마법사 | 15–30분 내 모든 항목 정상 설정 완료 |
2) 시스템 아키텍처 (상위 구조)
| 레이어 | 구성 요소 | 설명 |
|---|---|---|
| 하이퍼바이저/인프라 | Proxmox VE (KVM) | 메인 서버, VM 템플릿은 Cloud-Init 포함 |
| 오케스트레이터 API | FastAPI (Python) | Proxmox REST API 래핑, Guacamole 세션 발급, JWT 인증 |
| 웹 UI | React + TypeScript + Tailwind | UniFi/QNAP 스타일 관리자 콘솔 및 사용자 포털 |
| 원격 게이트웨이 | Apache Guacamole (guacd + web) | 브라우저 기반 RDP/VNC, 씬클라이언트는 RDP/SPICE 직접 연결 가능 |
| 인증 | JWT (MVP), 이후 OIDC/LDAP | MFA, 장치 인증은 추후 |
| 데이터 저장소 | PostgreSQL, Redis(선택) | 사용자/VM/템플릿/감사 로그/스케줄 |
3) 사용자 시나리오 (시퀀스)
3.1 로그인 → VM 접속 (Guacamole)
sequenceDiagram autonumber participant U as 사용자 (Thin Client/웹) participant FE as 웹 UI participant BE as 오케스트레이터 API participant DB as PostgreSQL participant PVE as Proxmox participant G as Guacamole
U-»FE: 로그인 화면 접근 FE-»BE: POST /auth/login {id,pw} BE-»DB: 계정 검증, JWT 발급 BE–»FE: {access_token}
U-»FE: VM 카드에서 “접속” 클릭 FE-»BE: POST /session/open {vmid} BE-»PVE: VM 실행 확인 (필요시 Start) BE-»G: Guacamole 세션 생성 G–»BE: {guac_url} BE–»FE: {guac_url} FE-»U: VM 데스크톱 브라우저 접속
3.2 템플릿 -> VM 생성
sequenceDiagram autonumber participant A as 관리자 participant FE as 웹 UI participant BE as 오케스트레이터 participant PVE as Proxmox participant DB as PostgreSQL
A-»FE: “VM 생성” 요청 FE-»BE: POST /vm/create {template,newid,name,cores,ram,storage} BE-»PVE: 템플릿 클론 시작 (UPID 반환) PVE–»BE: {upid} BE-»PVE: /tasks/{upid}/status 폴링 BE-»PVE: VM 설정 적용 (CPU, 메모리, Cloud-Init) BE-»PVE: VM 시작 BE-»DB: VM 메타데이터 기록 BE–»FE: {vmid,state:”running”}
UniFi-/QNAP-스타일 VDI 컨트롤러 — 기술 개요 (계속)
4) 데이터 모델 (MVP)
| 테이블 | 주요 필드 | 목적 |
|---|---|---|
| users | id, username(고유), password_hash, role {admin, operator, user} | 사용자 계정 및 권한 관리 |
| teams | id, name | 팀 단위 그룹 관리 |
| vms | id, vmid, node, owner_user_id, team_id, name, state, created_at | VM 메타데이터 및 소유자 매핑 |
| templates | id, name, vmid, os_type {win_client, win_server, linux}, requires(json), enabled | VM 템플릿 카탈로그 (Cloud-Init 포함) |
| settings | key, value(json) | 시스템 전역 설정 (브랜딩, 모드, 클러스터 연결 정보 등) |
| audit | id, actor_user_id, action, target, payload(json), ts | 모든 작업 로그 (불변) |
| schedules (후속) | id, vmid/team_id, cron_expr, action | VM 자동 시작/중지/스냅샷 |
| quotas (후속) | team_id, vcpu_limit, ram_mb_limit, storage_gb_limit | 팀별 자원 제한 |
인덱스 설계:
users.username고유 인덱스vms.owner_user_id,vms.vmid조회 최적화audit.ts시간순 로그 필터링
5) REST API (MVP)
5.1 인증
| 메서드 | 경로 | 요청 | 응답 |
|—|—|—|—|
| POST | /auth/login | {username,password} | {access_token, role} |
5.2 인벤토리
| 메서드 | 경로 | 쿼리 | 응답 |
|—|—|—|—|
| GET | /nodes | — | Proxmox 노드 목록 |
| GET | /vms | mine=true/false | VM 리스트: {node, vmid, name, state, owner} |
5.3 VM 라이프사이클
| 메서드 | 경로 | 요청 | 응답 |
|—|—|—|—|
| POST | /vm/create | {node, template_vmid, newid, name, storage, cores, memory, ci_vars?} | {upid} (폴링으로 상태 확인) |
| POST | /vm/{node}/{vmid}/start | — | {state:"running"} |
| POST | /vm/{node}/{vmid}/stop | — | {state:"stopped"} |
| DELETE | /vm/{node}/{vmid} | ?purge=1 | {deleted:true} |
| GET | /tasks/{upid}/status | — | {status, exitstatus, progress} |
5.4 세션
| 메서드 | 경로 | 요청 | 응답 |
|—|—|—|—|
| POST | /session/open | {vmid} | {guac_url} 또는 RDP/Spice 연결 정보 |
| POST | /session/close | {vmid} | {closed:true} |
보안:
- JWT 토큰 기반 인증 (헤더
Authorization) - TLS 종단은 nginx 리버스 프록시에서 처리
- CSRF 보호 적용
6) 관리자 콘솔 (UniFi/QNAP 스타일 UI)
6.1 주요 화면
| 화면 | 위젯 | 설명 |
|---|---|---|
| 설치 마법사 | PVE URL/토큰 입력, 템플릿 검색, 브랜딩 설정 | 초기 4~6단계 가이드, 진단 포함 |
| 클러스터 개요 | 노드 카드, CPU/RAM/IO 게이지, 알림 | 전체 상태를 한눈에 확인 |
| VM 관리 | 표(노드, vmid, 소유자, 상태, 실시간 자원), 액션 버튼 | 시작/중지/삭제, 스냅샷, 자원 확장 |
| 템플릿 관리 | 카드/리스트, VMID로 등록, Cloud-Init 체크 | 태깅, 검색 지원 |
| 사용자/팀 관리 | CRUD, VM 할당, 권한(Role) 부여 | 기본 RBAC 제공 |
| 스냅샷 관리 | 트리 구조, 생성/복원 버튼 | MVP+1 단계에서 추가 |
| 스케줄/쿼터 | 크론 에디터, 슬라이더 | MVP+1 단계 |
| 감사 로그 | 필터링/검색, CSV/JSON 내보내기 | 항상 활성화 |
6.2 UX 원칙
- 큰 카드형 UI + 색상 배지(녹색/주황/빨강)로 상태 시각화
- 원클릭 액션 + 확인 토스트 메시지
- UPID 폴링 기반 진행률 모달로 장시간 작업 표시
- VM 카드마다 항상 “접속” 버튼 고정 표시
7) 씬 클라이언트 (PoE 모듈)
7.1 최소/권장 사양
| 항목 | 최소 | 권장 |
|---|---|---|
| CPU | 듀얼코어 ARM/x86 | 저전력 쿼드코어 |
| RAM | 2–4 GB | 8 GB (듀얼 디스플레이, 화상회의 지원) |
| 저장공간 | 16–32 GB eMMC/SSD | 64–128 GB |
| 네트워크 | 기가비트 이더넷, PoE 지원 | + Wi-Fi 6 (옵션) |
| 디스플레이 | HDMI/DP 1개 | 2개 출력 |
| 주변기기 | USB 키보드/마우스 | USB 리디렉션 (옵션) |
| OS | ThinOS/ThinStation/경량 리눅스 | Kiosk 모드 자동 접속 |
7.2 부팅 & 접속 흐름
- 최소 OS 부팅 → 키오스크 모드 진입
- 로그인 화면 표시 → 사용자 ID/비밀번호 입력
/auth/login호출 → JWT 발급/vms?mine=true호출 → 사용자 VM 목록 표시- “접속” 클릭 →
/session/open→ Guacamole URL 획득 - 브라우저/네이티브 클라이언트에서 전체 화면으로 실행
- Heartbeat 유지 → 네트워크 끊김 시 자동 재접속
8) 배포 & 환경 구성
8.1 .env.example
PVE_BASE_URL=https://pve.local:8006/api2/json PVE_API_TOKEN=PVEAPIToken=root@pam!demo=SECRET123 PVE_DEFAULT_NODE=pve1 PVE_TEMPLATE_VMID=9000 PVE_DEFAULT_STORAGE=local-lvm JWT_SECRET=change_me POSTGRES_URL=postgresql://app:pass@db:5432/app GUACD_HOST=guacd GUACD_PORT=4822 COMPLIANCE_MODE=false # 라이선스/정책 훅은 존재하지만 MVP에서는 비활성화 BRANDING_NAME=”Orbit VDI”
8.2 Docker Compose 서비스 구성
| 서비스 | 역할 |
|—|—|
| api | FastAPI 백엔드 (Proxmox API 래핑, 인증, VM 관리) |
| web | React 프론트엔드 (관리자 콘솔 + 사용자 포털) |
| db | PostgreSQL (사용자, VM, 템플릿, 감사 로그 저장) |
| guacd + guacamole | 브라우저 원격 접속 게이트웨이 |
| reverse-proxy | nginx, TLS 종단, /api와 /guac 라우팅 |
네트워크:
- backend: api, db, guac 간 통신
- edge: proxy, web
볼륨:
- db 데이터
- guac 설정
- TLS 인증서
9) 비기능 요구사항 (NFR)
| 영역 | MVP 목표 | 후속 목표 |
|---|---|---|
| 프로비저닝 시간 | 템플릿 클론 후 부팅 ≤ 3분 | 최적화된 템플릿으로 ≤ 90초 |
| 접속 지연 | LAN 환경에서 데스크톱 표시 ≤ 3초 | WAN 환경 적응형 (코덱/비트레이트 조정) |
| 가용성 | 단일 노드 | HA 클러스터, 라이브 마이그레이션 |
| 보안 | TLS, JWT, 최소 RBAC | MFA, OIDC/LDAP, 장치 인증서, Vault 연동 |
| 모니터링 | Proxmox 기본 그래프 | Prometheus + Grafana, 알림 시스템 |
| 백업/복원 | 수동 스냅샷 | 예약 백업, 보존 정책 |
10) 리스크 & 대응책
| 리스크 | 영향 | 대응책 |
|---|---|---|
| 스토리지 I/O 병목 | VM 느려짐 | NVMe/ZFS 캐시 사용, 클론 작업 분산, 쿼터 적용 |
| 단일 서버 장애 | 전체 서비스 중단 | 예비 노드 준비, v2에서 클러스터링 |
| 라이선스 정책 혼란 | 법적 리스크 | MVP에서는 훅만 구현 후 비활성화, 후속 단계에서 정책 적용 |
| WAN 품질 저하 | 사용자 경험 악화 | Guacamole 튜닝, 자동 재접속 로직, 지역 PoP 확장 고려 |
11) MVP 단계별 로드맵
| 단계 | 범위 | 산출물 | 완료 기준 |
|---|---|---|---|
| MVP-0 (1주차) | 기초 인프라 | Repo, CI/CD, docker-compose.yml, README |
docker compose up -d로 모든 서비스 기동 |
| MVP-1 (2–3주차) | 인증 & 인벤토리 | /auth/login, /vms, React 로그인 & VM 테이블 |
JWT 로그인 성공, Proxmox VM 목록 UI에 표시 |
| MVP-2 (4–5주차) | VM 프로비저닝 | /vm/create, UPID 폴링, 생성 마법사 |
템플릿→VM 생성 후 ≤ 3분 내 부팅 확인 |
| MVP-3 (6–7주차) | 세션 접속 | /session/open, Guacamole 연동 |
“접속” 버튼 클릭 시 브라우저에서 VM 데스크톱 표시 |
| MVP-4 (8–9주차) | 운영 편의성 | 스냅샷 생성/복원, 자원 확장 | 원클릭 스냅샷 복원 동작 |
| MVP-5 (10–12주차) | 팀 기능 | 사용자/팀 CRUD, RBAC, VM 할당 | 사용자 계정은 자기 VM만 확인, 운영자는 팀 범위 제한 |
참고:
- MVP에서는 라이선스/정책 가드레일은 비활성화 (
COMPLIANCE_MODE=false). - 코드/데이터 구조에는 훅을 남겨두어 추후 활성화 시 재개발 없이 확장 가능.
UniFi-/QNAP-스타일 VDI 컨트롤러 — 기술 개요 (코드 구조 정리)
12) 코드 구조 (Code Organization)
- api/
- FastAPI 라우터 (얇게 유지)
- routes/
auth.py→ 로그인/인증 처리inventory.py→ 노드/VM 조회lifecycle.py→ VM 생성/시작/중지/삭제session.py→ VM 접속/종료 세션 관리
- core/
- 비즈니스/도메인 로직
models.py→ Pydantic/ORM 모델services.py→ VM 오케스트레이션, UPID 처리policies.py→ 라이선스/정책 훅 (MVP에서는 스텁)
- adapters/
- 외부 연동 계층
proxmox.py→ Proxmox REST API 호출 래퍼guacamole.py→ Guacamole 세션 생성/티켓 발급db.py→ PostgreSQL 세션 및 리포지토리auth.py→ 비밀번호 해시, JWT 발급/검증
- web/
- React 프론트엔드
- src/
pages/→ Login, Dashboard, VMList, Wizardcomponents/→ UI 카드, 테이블, 토스트, 배너api/→ TanStack Query 기반 API 훅store/→ 상태 관리 (인증/세션)
- deploy/
- 배포 및 설정 파일
docker-compose.yml→ 서비스 정의nginx.conf→ 리버스 프록시 및 TLSinitdb.sql→ 초기 DB 스키마
- docs/
- 문서/설계
ADRs/→ 아키텍처 결정 기록OPERATIONS.md→ 운영/운영자 가이드API.md→ 엔드포인트 명세
- .env.example
- 환경 변수 예시 파일
- PVE API 토큰, DB 접속 정보, JWT 시크릿, Guac 설정 등 포함
설계 원칙
- 라우터는 얇게 유지하고 핵심 로직은
core/에 집중 - VM 라이프사이클 API는 idempotent (반복 호출 안전)
- 에러 응답은
{code, message, cause?}형식으로 표준화 - 장시간 태스크는 UPID 기반 폴링 (추후 SSE/WebSocket 확장 가능)
13) 씬 클라이언트 접속 흐름
- 장치 전원 인가 → 최소 OS 부팅 (ThinOS/ThinStation)
- 키오스크 모드 실행 → 로그인 화면 표시
- 사용자 입력 →
/auth/login호출 → JWT 발급 /vms?mine=true호출 → 사용자 VM 목록 표시- 사용자가 VM 선택 →
/session/open {vmid}호출 →guac_url반환 - 브라우저/네이티브 클라이언트에서 전체 화면으로 VM 실행
- Heartbeat 유지 → 네트워크 끊김 시 자동 재접속
- 로그아웃 시
/session/close호출
14) TL;DR
- 핵심 약속:
- 관리자는 누구나 손쉽게 VM을 만들 수 있다.
- 사용자는 단 두 번의 클릭으로 자신의 VM에 접속할 수 있다.
- MVP 범위:
- 로그인 → VM 목록 → 생성/시작/중지/삭제 → 브라우저 접속 (Guacamole)
- 설계 스타일:
- UniFi/QNAP과 같은 직관적 UI
- 큰 카드형 UI, 상태 배지(녹/주/적), 원클릭 액션
- 정책/라이선스 훅:
- 코드 구조에 포함되어 있으나 MVP에서는 비활성화
COMPLIANCE_MODE=false
- 코드베이스 특징:
- 모듈화, 가독성, 확장성을 고려한 설계
- 추후 제품화/상용화 시 확장 가능
Leave a comment