Version: 2.0.0-alpha Date: 2025-11-21 Status: Implementation in Progress
Refactoring StreamSpace from a Kubernetes-native architecture to a multi-platform Control Plane + Agent architecture.
Key Changes:
- Control Plane: Centralized API managing sessions across all platforms
- Platform-Specific Agents: K8s Agent, Docker Agent, future platform agents
- Outbound Connections: Agents connect TO Control Plane (firewall-friendly)
- VNC Tunneling: VNC traffic tunneled through Control Plane (multi-network support)
- Platform Abstraction: Generic "Session" concept, agents handle platform specifics
┌─────────────────────────────────────────────────────────────┐
│ Kubernetes Cluster (Single Cluster Required) │
│ │
│ ┌──────────┐ ┌─────────────────┐ │
│ │ Web UI │─────▶│ API (REST) │ │
│ └──────────┘ └─────────────────┘ │
│ │ │ │
│ │ │ │
│ │ ▼ │
│ │ ┌─────────────────┐ │
│ │ │ Kubebuilder │ │
│ │ │ Controller │ │
│ │ │ │ │
│ │ │ - Watches CRDs │ │
│ │ │ - Reconcile Loop│ │
│ │ │ - Creates Pods │ │
│ │ └─────────────────┘ │
│ │ │ │
│ │ ▼ │
│ │ ┌─────────────────┐ │
│ │ │ Session Pods │ │
│ │ │ (with VNC) │ │
│ │ └─────────────────┘ │
│ │ │ │
│ └─────────────────────┘ │
│ Direct VNC Connection │
│ (Requires same cluster) │
└─────────────────────────────────────────────────────────────┘
Limitations:
- ❌ Kubernetes-only (no Docker, VM, or other platforms)
- ❌ Single cluster requirement (API, UI, Controller, Sessions all in one cluster)
- ❌ Direct VNC access requires network connectivity to pods
- ❌ Tight coupling to Kubernetes API
- ❌ No multi-region, multi-cluster support
┌─────────────────────────────────────────────────────────────────────┐
│ Control Plane (Centralized - Any Deployment) │
│ │
│ ┌──────────┐ ┌─────────────────────────────────┐ │
│ │ Web UI │─────▶│ Control Plane API │ │
│ └──────────┘ │ │ │
│ │ │ - Agent Registration │ │
│ │ │ - WebSocket Hub (Agent Comms) │ │
│ │ │ - Command Dispatcher │ │
│ │ │ - VNC Proxy/Tunnel │ │
│ │ │ - Session State Manager │ │
│ │ └─────────────────────────────────┘ │
│ │ │ │
│ │ │ WebSocket (Outbound from Agents) │
│ │ ▼ │
│ │ ┌──────────────────────────────┐ │
│ │ │ VNC Proxy Endpoint │ │
│ │ │ /vnc/{session_id} │ │
│ │ │ │ │
│ │ │ - Accepts UI connections │ │
│ │ │ - Tunnels to appropriate Agent│ │
│ │ │ - Multiplexes VNC streams │ │
│ │ └──────────────────────────────┘ │
│ │ │ │
│ └──────────────────────────┘ │
│ VNC via Control Plane Proxy │
└──────────────────────────────────────────────────────────────────────┘
│
┌──────────────────────────┼──────────────────────────┐
│ │ │
▼ ▼ ▼
┌────────────────┐ ┌────────────────┐ ┌────────────────┐
│ K8s Agent │ │ Docker Agent │ │ Future Agents │
│ (Cluster 1) │ │ (Host 1) │ │ (VM, Cloud) │
│ │ │ │ │ │
│ - K8s Client │ │ - Docker API │ │ - Platform API │
│ - Creates Pods │ │ - Runs Contnrs │ │ - Provisions │
│ - Exposes VNC │ │ - Exposes VNC │ │ - Exposes VNC │
│ - Tunnels to CP│ │ - Tunnels to CP│ │ - Tunnels to CP│
└────────────────┘ └────────────────┘ └────────────────┘
│ │ │
▼ ▼ ▼
┌────────────────┐ ┌────────────────┐ ┌────────────────┐
│ Session Pod │ │ Session Contnr │ │ Session VM │
│ (K8s) │ │ (Docker) │ │ (Cloud) │
└────────────────┘ └────────────────┘ └────────────────┘
Benefits:
- ✅ Multi-platform support (K8s, Docker, VMs, Cloud)
- ✅ Multi-cluster, multi-region support
- ✅ Agents can be anywhere (only need outbound HTTPS/WSS)
- ✅ VNC works across network boundaries
- ✅ Centralized control and monitoring
- ✅ Easy to add new platforms (write new agent)
Location: Can be deployed anywhere (K8s, VM, Docker, Cloud)
Responsibilities:
- Manage agent lifecycle (registration, heartbeat, deregistration)
- Maintain WebSocket connections with all agents
- Dispatch commands to agents (start, stop, hibernate sessions)
- Aggregate session status from all agents
- Proxy/tunnel VNC traffic between UI and agents
- Enforce licensing and resource limits
- Audit logging
New Endpoints:
// Agent Management
POST /api/v1/agents/register // Agent registers itself
DELETE /api/v1/agents/{agent_id} // Deregister agent
GET /api/v1/agents // List all agents
GET /api/v1/agents/{agent_id} // Get agent details
// WebSocket for Agents
WS /api/v1/agents/connect // Agent establishes WebSocket
// VNC Proxy
WS /vnc/{session_id} // UI connects for VNC (proxied to agent)
// Session Management (Updated)
POST /api/v1/sessions // Create session (CP dispatches to agent)
GET /api/v1/sessions/{id} // Get session (queries agent)
PUT /api/v1/sessions/{id}/state // Update state (hibernate, wake, terminate)WebSocket Protocol (Control Plane ↔ Agent):
// Agent → Control Plane (Registration)
{
"type": "register",
"payload": {
"agent_id": "k8s-cluster-1",
"platform": "kubernetes",
"region": "us-east-1",
"capacity": {
"max_sessions": 100,
"cpu": "64 cores",
"memory": "256Gi"
}
}
}
// Control Plane → Agent (Command)
{
"type": "command",
"command_id": "cmd-123",
"payload": {
"action": "start_session",
"session": {
"id": "sess-456",
"user": "john",
"template": "firefox-browser",
"resources": {
"memory": "2Gi",
"cpu": "1000m"
}
}
}
}
// Agent → Control Plane (Status Update)
{
"type": "status",
"command_id": "cmd-123",
"payload": {
"session_id": "sess-456",
"state": "running",
"vnc_ready": true,
"vnc_port": 5900,
"pod_name": "sess-456-abc123" // Platform-specific details
}
}
// VNC Tunnel Data (Bidirectional)
{
"type": "vnc_data",
"session_id": "sess-456",
"data": "<base64-encoded-vnc-traffic>"
}Database Schema Changes:
-- New: Agent Registry
CREATE TABLE agents (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
agent_id VARCHAR(255) UNIQUE NOT NULL, -- "k8s-cluster-1"
platform VARCHAR(50) NOT NULL, -- "kubernetes", "docker"
region VARCHAR(100), -- "us-east-1", "eu-west-1"
status VARCHAR(50) DEFAULT 'offline', -- "online", "offline", "draining"
capacity JSONB, -- max_sessions, cpu, memory
last_heartbeat TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- Updated: Sessions (Platform-Agnostic)
ALTER TABLE sessions ADD COLUMN agent_id VARCHAR(255) REFERENCES agents(agent_id);
ALTER TABLE sessions ADD COLUMN platform VARCHAR(50);
ALTER TABLE sessions ADD COLUMN platform_metadata JSONB; -- Pod name, container ID, etc.
-- New: Command Queue
CREATE TABLE agent_commands (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
command_id VARCHAR(255) UNIQUE NOT NULL,
agent_id VARCHAR(255) REFERENCES agents(agent_id),
session_id UUID REFERENCES sessions(id),
action VARCHAR(50) NOT NULL, -- "start_session", "stop_session"
payload JSONB,
status VARCHAR(50) DEFAULT 'pending', -- "pending", "sent", "ack", "completed", "failed"
created_at TIMESTAMP DEFAULT NOW(),
completed_at TIMESTAMP
);What It Is:
- Converted from current Kubebuilder controller
- Lightweight agent connecting to Control Plane
- Manages sessions as Kubernetes Pods
Responsibilities:
- Connect to Control Plane via WebSocket (outbound connection)
- Listen for commands from Control Plane
- Translate generic session specs → Kubernetes Pods/Services
- Report session status back to Control Plane
- Tunnel VNC traffic from pods to Control Plane
Architecture:
┌─────────────────────────────────────────────────────────┐
│ Kubernetes Agent (Running in K8s Cluster) │
│ │
│ ┌────────────────────────────────────┐ │
│ │ Agent Manager (Main Loop) │ │
│ │ │ │
│ │ - Connects to Control Plane WSS │ │
│ │ - Sends heartbeats every 10s │ │
│ │ - Listens for commands │ │
│ └────────────────────────────────────┘ │
│ │ │ │
│ │ │ │
│ ▼ ▼ │
│ ┌───────────────┐ ┌──────────────────┐ │
│ │ K8s Client │ │ VNC Tunnel Mgr │ │
│ │ │ │ │ │
│ │ - Create Pods │ │ - Port Forward │ │
│ │ - Watch Status│ │ - Tunnel to CP │ │
│ └───────────────┘ └──────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────────────────────────┐ │
│ │ Session Pods │ │
│ │ - Application + VNC Container │ │
│ │ - VNC on port 5900 │ │
│ └──────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
Command Handlers:
// Agent command handlers
func (a *KubernetesAgent) HandleCommand(cmd *Command) {
switch cmd.Action {
case "start_session":
a.startSession(cmd.Payload)
case "stop_session":
a.stopSession(cmd.Payload)
case "hibernate_session":
a.hibernateSession(cmd.Payload)
case "wake_session":
a.wakeSession(cmd.Payload)
}
}
func (a *KubernetesAgent) startSession(spec SessionSpec) {
// 1. Translate generic spec → K8s Pod
pod := a.buildPodFromSpec(spec)
// 2. Create Pod in cluster
_, err := a.k8sClient.CoreV1().Pods(a.namespace).Create(ctx, pod, metav1.CreateOptions{})
// 3. Wait for Pod to be Running
a.waitForPodRunning(pod.Name)
// 4. Start VNC tunnel
a.startVNCTunnel(spec.SessionID, pod.Name)
// 5. Report status to Control Plane
a.sendStatus(spec.SessionID, "running")
}VNC Tunneling:
// Tunnel VNC traffic from Pod to Control Plane WebSocket
func (a *KubernetesAgent) startVNCTunnel(sessionID, podName string) {
// Port-forward to pod's VNC port (5900)
portForwarder := a.createPortForward(podName, 5900)
// Connect to local forwarded port
vncConn, _ := net.Dial("tcp", "localhost:5900")
// Tunnel all traffic through Control Plane WebSocket
go func() {
buffer := make([]byte, 32768)
for {
n, _ := vncConn.Read(buffer)
a.sendVNCData(sessionID, buffer[:n])
}
}()
// Receive VNC data from Control Plane and write to local connection
go func() {
for data := range a.vncDataChannel[sessionID] {
vncConn.Write(data)
}
}()
}What It Is:
- Brand new agent for Docker platform
- Similar to K8s Agent but uses Docker API
- Manages sessions as Docker containers
Responsibilities:
- Connect to Control Plane via WebSocket
- Listen for commands
- Translate generic session specs → Docker containers
- Report session status
- Tunnel VNC traffic from containers to Control Plane
Architecture:
┌─────────────────────────────────────────────────────────┐
│ Docker Agent (Running on Docker Host) │
│ │
│ ┌────────────────────────────────────┐ │
│ │ Agent Manager (Main Loop) │ │
│ │ │ │
│ │ - Connects to Control Plane WSS │ │
│ │ - Sends heartbeats every 10s │ │
│ │ - Listens for commands │ │
│ └────────────────────────────────────┘ │
│ │ │ │
│ │ │ │
│ ▼ ▼ │
│ ┌───────────────┐ ┌──────────────────┐ │
│ │ Docker Client │ │ VNC Tunnel Mgr │ │
│ │ │ │ │ │
│ │ - Run Contnrs │ │ - Connect to VNC │ │
│ │ - Watch Status│ │ - Tunnel to CP │ │
│ └───────────────┘ └──────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────────────────────────┐ │
│ │ Session Containers │ │
│ │ - Application + VNC │ │
│ │ - VNC on port 5900 │ │
│ └──────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
Command Handlers:
func (a *DockerAgent) startSession(spec SessionSpec) {
// 1. Translate generic spec → Docker container config
containerConfig := a.buildContainerConfig(spec)
// 2. Create container
container, err := a.dockerClient.ContainerCreate(
ctx,
containerConfig,
nil,
nil,
nil,
spec.SessionID,
)
// 3. Start container
a.dockerClient.ContainerStart(ctx, container.ID, types.ContainerStartOptions{})
// 4. Start VNC tunnel
a.startVNCTunnel(spec.SessionID, container.ID)
// 5. Report status
a.sendStatus(spec.SessionID, "running")
}VNC Viewer Update:
Current (Direct connection to pod):
// ui/src/components/VNCViewer.jsx
const vncUrl = `ws://${podIP}:5900`;
const rfb = new RFB(canvas, vncUrl);New (Proxy through Control Plane):
// ui/src/components/VNCViewer.jsx
const vncUrl = `/vnc/${sessionId}`; // Control Plane proxy endpoint
const rfb = new RFB(canvas, vncUrl);Session Creation Update:
// User selects platform when creating session (optional)
const createSession = async (template, platform = "auto") => {
const response = await fetch('/api/v1/sessions', {
method: 'POST',
body: JSON.stringify({
user: currentUser,
template: template,
platform: platform, // "auto", "kubernetes", "docker"
resources: {
memory: "2Gi",
cpu: "1000m"
}
})
});
};- Status: In Progress
- Tasks:
- ✅ Document target architecture
- ✅ Define WebSocket protocol
- ✅ Design database schema
- Create sequence diagrams
- Update API specifications
- Duration: 3-5 days
- Tasks:
- Add
agentstable to database - Implement
POST /api/v1/agents/registerendpoint - Implement
GET /api/v1/agents(list/get agents) - Add agent heartbeat tracking
- Add agent status monitoring
- Add
- Duration: 5-7 days
- Tasks:
- Implement WebSocket hub for agent connections
- Add command queue (
agent_commandstable) - Implement command dispatcher
- Add command acknowledgment tracking
- Handle agent reconnection logic
- Duration: 5-7 days
- Tasks:
- Implement
/vnc/{session_id}WebSocket endpoint - Add VNC traffic multiplexer
- Route VNC traffic between UI and appropriate agent
- Handle connection failures and reconnection
- Add bandwidth throttling (optional)
- Implement
- Duration: 7-10 days
- Tasks:
- Extract current controller logic
- Implement agent connection to Control Plane
- Convert reconciliation loop → command handlers
- Translate generic session spec → K8s Pod
- Report session status to Control Plane
- Handle agent reconnection
- Duration: 3-5 days
- Tasks:
- Implement port-forwarding to pod VNC port
- Tunnel VNC traffic through WebSocket to Control Plane
- Handle VNC connection lifecycle
- Add error handling and reconnection
- Duration: 7-10 days
- Tasks:
- Create Docker agent skeleton
- Implement Docker client integration
- Translate generic session spec → Docker container
- Implement container lifecycle management
- Implement VNC tunneling for Docker containers
- Add Docker-specific features (volumes, networks)
- Duration: 2-3 days
- Tasks:
- Update VNC viewer to use Control Plane proxy
- Add platform selection to session creation
- Update session list to show platform/agent info
- Handle VNC connection errors gracefully
- Duration: 2-3 days
- Tasks:
- Create migration for
agentstable - Update
sessionstable (addagent_id,platform,platform_metadata) - Create
agent_commandstable - Create indexes for performance
- Test migrations
- Create migration for
- Duration: 5-7 days
- Tasks:
- Test Control Plane with K8s Agent
- Test Control Plane with Docker Agent
- Test multi-agent scenarios
- Test VNC streaming across network boundaries
- Load testing (100+ concurrent sessions)
- Create migration guide from v1.x
- Document deployment patterns
- Phase 9: Database Schema (foundation)
- Phase 2: Agent Registration (basic infrastructure)
- Phase 3: WebSocket Command Channel (core communication)
- Phase 5: K8s Agent (convert existing, validate architecture)
- Phase 4: VNC Proxy (enable VNC streaming)
- Phase 6: K8s Agent VNC Tunneling (complete K8s support)
- Phase 8: UI Updates (user-facing changes)
- Phase 7: Docker Agent (add second platform)
- Phase 10: Testing & Migration (validation)
- Phase 9: Database Schema
- Phase 2: Agent Registration
- Phase 3: WebSocket Command Channel
- Phase 7: Docker Agent (new platform, clean slate)
- Phase 5: K8s Agent (convert existing)
- Phase 4: VNC Proxy
- Phase 6: K8s Agent VNC Tunneling
- Phase 8: UI Updates
- Phase 10: Testing & Migration
- Multiple agents (K8s + Docker minimum) can register with Control Plane
- Control Plane can dispatch session commands to agents
- Agents can create sessions on their respective platforms
- VNC streaming works across network boundaries
- UI can connect to sessions on any platform
- Sessions can be hibernated and woken across agents
- System handles agent failures gracefully
- VNC latency < 100ms (with reasonable network)
- Support 100+ concurrent sessions across agents
- Agent reconnection within 30 seconds of network failure
- Zero downtime for Control Plane upgrades
- Backward compatibility with existing sessions (migration path)
- Architecture documentation (this document)
- API specification updates
- Agent development guide
- Deployment guide (multi-platform)
- Migration guide from v1.x
- Deploy Control Plane (v2.0 API)
- Deploy K8s Agent in existing cluster (replaces controller)
- Migrate existing sessions (optional, can recreate)
- Update UI to use Control Plane proxy
- Test VNC connectivity
- Decommission old controller
- v2.0 API remains compatible with v1.x UI (with feature flags)
- Existing sessions can continue running during migration
- Gradual rollout: Run v1.x and v2.0 side-by-side temporarily
- Impact: High latency, choppy user experience
- Mitigation:
- Use binary WebSocket frames (not base64)
- Implement compression for VNC traffic
- Add bandwidth throttling to prevent congestion
- Benchmark early in Phase 4
- Impact: Lost sessions during network failures
- Mitigation:
- Implement robust reconnection logic with exponential backoff
- Persist command queue in database
- Resume commands after reconnection
- Test network failure scenarios extensively
- Impact: Slow command dispatch at scale
- Mitigation:
- Use database connection pooling
- Implement in-memory command cache
- Consider Redis for command queue (future optimization)
- Load test with 1000+ agents
- Impact: Difficult migration, user frustration
- Mitigation:
- Maintain v1.x API compatibility with feature flags
- Provide automated migration tools
- Document migration path clearly
- Offer migration support
-
Additional Platforms
- AWS EC2 Agent
- Azure VM Agent
- GCP Compute Agent
- LXC/LXD Agent
-
Advanced Features
- Session migration between agents
- Load balancing across agents
- Geo-aware agent selection
- Multi-tenant agent isolation
-
Performance Optimizations
- Direct agent-to-agent VNC routing (bypass Control Plane)
- UDP-based VNC tunneling for lower latency
- Hardware acceleration for VNC encoding
-
Monitoring & Operations
- Agent health dashboard
- Real-time VNC traffic metrics
- Agent auto-scaling
- Anomaly detection
Before we proceed with implementation:
- Implementation Order: Option A (Bottom-Up) or Option B (Top-Down)?
- VNC Tunneling: Binary WebSocket or base64? Compression?
- Database: PostgreSQL only or add Redis for command queue?
- Docker Agent Priority: High (build early) or Low (after K8s Agent proven)?
- Testing: Unit tests only, or also integration/E2E tests?
- Migration: Support v1.x API compatibility or break compatibility cleanly?
Next Steps: Waiting for user decision on implementation approach, then begin Phase 2 (Control Plane - Agent Registration).