Skip to main content
FlexInfer docs

1. Node Agent (flexinfer-agent)

FlexInfer Component Reference

Detailed reference for the six cooperating executables. For the quick-start overview, see AGENTS.md.

ComponentBinaryRuns onKey responsibility
Node Agentflexinfer-agentEvery GPU-capable nodeDetect hardware & emit labels
Benchmarkerflexinfer-benchJob pod (ephemeral)Measure tokens/s per model-device pair
Controller Managerflexinfer-managerControl-planeReconciles Model (v1alpha2) and legacy v1alpha1 CRDs
Scheduler Extenderflexinfer-schedControl-planeFilters & scores nodes during scheduling
Global Proxyflexinfer-global-proxyControl-planeRoutes traffic across healthy cluster-local proxies
Metrics Exporterbuilt-inAll componentsCollects Prometheus metrics for all of the above

1. Node Agent (flexinfer-agent)

What it detects

The node agent performs comprehensive hardware discovery and applies labels to nodes:

LabelExampleNotes
flexinfer.ai/gpu.vendorAMD / NVIDIAPopulated from PCI ID detection
flexinfer.ai/gpu.vram24GiTotal VRAM per GPU in GiB
flexinfer.ai/gpu.archgfx90a / sm_89GPU architecture identifier
flexinfer.ai/gpu.int4trueINT4 quantization support capability
flexinfer.ai/gpu.count4Number of GPUs detected on the node
flexinfer.ai/cpu.avx512falseCPU feature detection for fallback

The node agent also applies node annotations that the scheduler can use as heuristic inputs:

AnnotationExampleNotes
flexinfer.ai/gpu.util12.34Average GPU utilization (%) across all GPUs
flexinfer.ai/gpu-free-memory24550Sum of free VRAM across GPUs (MB)
flexinfer.ai/kv-cache-usage0.1234Best-effort KV-cache usage ratio from backend pod metrics

Implementation Details

  • Hardware Detection: Uses system calls and PCI enumeration to identify GPU hardware
  • Label Management: Automatically applies and updates node labels based on detected capabilities
  • Error Handling: Robust error handling for hardware detection failures
  • Caching: Efficient caching of hardware information to reduce system load

GPU Detection Sources (gfx1100 + Maxwell focus)

  • NVIDIA: uses nvidia-smi (direct, then chroot /host nvidia-smi for glibc compatibility) to get architecture (sm_52 for Maxwell), VRAM, and utilization.
  • AMD: prefers rocm-smi + rocminfo (direct, then chroot /host ... as a fallback). If those utilities are unavailable, it falls back to sysfs VRAM detection and may omit flexinfer.ai/gpu.arch.

When multiple GPUs are present, the agent chooses the "best" representative values (highest major gfx* generation / highest sm_*, and max VRAM) so scheduling stays stable on mixed or heterogeneous nodes.

If the agent cannot list pods in flexinfer-system, it will still label hardware but may set telemetry annotations like flexinfer.ai/gpu-free-memory or flexinfer.ai/kv-cache-usage to 0, which reduces scheduler placement quality.

Config flags

FlagDefaultDescription
--interval30sHow often to re-probe hardware
--metrics-port9100Prometheus scrape port
--label-prefixflexinfer.ai/Customize if conflicts with other labelers
--dry-runfalseLog actions without applying labels
--node-nameauto-detectedOverride node name for labeling

2. Benchmarker (flexinfer-bench)

Execution Model

The benchmarker runs as a Kubernetes Job, executed once per unique model × device class combination:

  1. Model Acquisition: Pulls the model artifact into the node's shared cache path
  2. Container Launch: Starts the specified backend container with configured resources
  3. Performance Testing: Executes benchmark runs with configurable parameters
  4. Result Storage: Publishes results to a ConfigMap for scheduler consumption

Implementation Features

  • Real Benchmarking: Runs real inference requests through flexinfer-proxy and records tokens/sec into a ConfigMap (used by the scheduler extender)
  • Extensible Backend: Designed to support multiple inference backends (Ollama, vLLM, etc.)
  • Resource Management: Proper cleanup of test resources after completion
  • Error Recovery: Robust error handling and retry logic

Configuration Options

Available through the ModelDeployment CRD spec:

CRD FieldDefaultPurpose
spec.benchmark.warmupIterations2Number of warm-up runs before measurement
spec.benchmark.minDuration30sMinimum benchmark duration
spec.benchmark.batchSize128Tokens per benchmark batch
spec.benchmark.iterations5Number of measurement iterations

3. Controller Manager (flexinfer-manager)

Core Functionality

A comprehensive Kubernetes controller built with controller-runtime that provides:

  • CRD Reconciliation: Complete lifecycle management of ModelDeployment resources
  • Status Management: Detailed status tracking with conditions and phases
  • Event Recording: Comprehensive event logging for debugging and monitoring
  • Finalizer Handling: Proper cleanup of dependent resources
  • Benchmark Orchestration: Automatic triggering of benchmarking jobs

Status Tracking

The controller maintains detailed status information:

type ModelDeploymentStatus struct {
    Phase      ModelDeploymentPhase `json:"phase,omitempty"`
    Conditions []metav1.Condition   `json:"conditions,omitempty"`
    Replicas   int32                `json:"replicas,omitempty"`
    Endpoints  []Endpoint           `json:"endpoints,omitempty"`
}

Supported Phases

PhaseDescription
PendingInitial state, awaiting scheduling
BenchmarkingPerformance measurement in progress
DeployingCreating underlying Kubernetes resources
RunningDeployment is active and serving requests
FailedDeployment has encountered an error
TerminatingCleanup in progress

Environment variables

NameDefaultDescription
MODEL_CACHE_PATH/modelsShared model storage location
DEFAULT_BACKEND_IMAGEollama/ollama:latestLegacy: Default NVIDIA backend (deprecated)
DEFAULT_BACKEND_IMAGE_NVIDIAollama/ollama:latestNVIDIA (CUDA) inference backend
DEFAULT_BACKEND_IMAGE_AMDollama/ollama:rocmAMD (ROCm) inference backend
DEFAULT_BACKEND_IMAGE_INTELollama/ollama:latestIntel inference backend
BENCHMARK_IMAGEflexinfer/benchmarker:latestBenchmarker container image
METRICS_PORT8080Controller metrics endpoint

4. Scheduler Extender (flexinfer-sched)

Scheduling Algorithm

The scheduler extender implements a sophisticated two-phase approach:

Filter Phase

Eliminates nodes that cannot satisfy the workload requirements:

  • GPU Requirements: Matches requested GPU count and type
  • VRAM Requirements: Ensures sufficient memory for the model
  • Quantization Support: Verifies hardware supports requested quantization
  • Architecture Compatibility: Matches model requirements with GPU architecture

Score Phase

Ranks suitable nodes using a weighted scoring algorithm:

score = (TPS_normalized × TPS_weight) - (GPU_util × Util_weight) - (Cost × Cost_weight) - (KV_cache × Cache_weight) + (FreeVRAMRatio × VRAMFree_weight)

Scoring Factors

FactorWeightDescription
Tokens/Second0.7Benchmarked performance for model-device pair
GPU Utilization0.2Current GPU resource usage
Node Cost0.1Cost per hour (from node annotations)
Free VRAM Ratio10.0Bonus: free_vram / total_vram headroom (uses agent labels + annotations)

Configuration

Scoring weights can be configured via Helm values:

scheduler:
  weights:
    tps: 0.8      # Performance weight
    util: 0.1     # Utilization weight
    cost: 0.1     # Cost weight
  port: 8000      # Extender webhook port

Implementation Details

  • Webhook Server: HTTP server implementing Kubernetes scheduler extender protocol
  • Concurrent Processing: Efficient handling of multiple scheduling requests
  • Caching: Performance data caching for improved response times
  • Fallback Logic: Graceful degradation when benchmark data is unavailable

5. Metrics Exporter

Architecture

The metrics exporter is implemented as a shared Go module embedded in every binary, providing consistent observability across all components.

Available Metrics

MetricLabelsDescription
flexinfer_tokens_per_secondmodel, backend, nodeModel performance metrics
flexinfer_model_load_secondsmodel, nodeModel loading time
flexinfer_gpu_temperature_celsiusgpu, nodeGPU temperature monitoring
flexinfer_controller_reconciles_totalresultController reconciliation count
flexinfer_scheduler_requests_totalphase, resultScheduler extender request count
flexinfer_benchmark_duration_secondsmodel, device_classBenchmark execution time

Prometheus Configuration

scrape_configs:
- job_name: 'flexinfer-agent'
  kubernetes_sd_configs:
  - role: node
  relabel_configs:
  - source_labels: [__meta_kubernetes_node_label_flexinfer_ai_enabled]
    regex: "true"
    action: keep

- job_name: 'flexinfer-controller'
  static_configs:
  - targets: ['flexinfer-controller:8080']

- job_name: 'flexinfer-scheduler'
  static_configs:
  - targets: ['flexinfer-scheduler:8000']

Communication Flow

sequenceDiagram
    participant User
    participant Controller
    participant Benchmarker
    participant Scheduler
    participant K8sScheduler
    participant Agent

    User->>Controller: kubectl apply ModelDeployment
    Controller->>Controller: Validate and set status to Pending

    alt Benchmark data missing
        Controller->>Benchmarker: Create benchmark Job
        Benchmarker->>Benchmarker: Run performance tests
        Benchmarker->>Controller: Store results in ConfigMap
    end

    Controller->>Controller: Create underlying Deployment
    Controller->>Controller: Update status to Deploying

    K8sScheduler->>Scheduler: Filter/Score request
    Scheduler->>Scheduler: Apply filters and scoring
    Scheduler->>K8sScheduler: Return ranked nodes

    K8sScheduler->>Agent: Schedule pod to selected node
    Agent->>Agent: Validate hardware compatibility

    Controller->>Controller: Update status to Running

Advanced Features

Status Conditions

The controller maintains detailed condition information:

  • Available: Deployment is ready to serve traffic
  • Progressing: Deployment is being updated
  • ReplicaFailure: Unable to create desired replicas
  • BenchmarkComplete: Performance measurement finished
  • NodeSelected: Scheduling completed successfully

Event Recording

Comprehensive event logging covers:

  • Deployment lifecycle events
  • Benchmark execution status
  • Scheduling decisions and outcomes
  • Error conditions and recovery actions

Resource Management

  • Finalizers: Proper cleanup ordering with flexinfer.ai/finalizer
  • Owner References: Garbage collection of dependent resources
  • Resource Quotas: Integration with Kubernetes resource management

Troubleshooting

Common Issues

  1. Node labels not appearing: Check agent logs and RBAC permissions
  2. Benchmarks not triggering: Verify benchmark job creation and ConfigMap access
  3. Scheduling failures: Check scheduler extender logs and webhook connectivity
  4. Status not updating: Verify controller reconciliation loops and event recording
  5. Helm upgrades stuck / DaemonSet not ready: In homelabs, a NotReady/unreachable node can leave old pods stuck Terminating, which can block rollouts. Force-delete the stuck pods in flexinfer-system to unblock upgrades.

Debug Commands

# Check node labels
kubectl get nodes --show-labels | grep flexinfer

# View controller logs
kubectl logs -n flexinfer-system deployment/flexinfer-controller

# Check benchmark results
kubectl get configmaps -n flexinfer-system -l app=flexinfer-benchmarks

# View scheduler decisions
kubectl logs -n kube-system deployment/flexinfer-scheduler

# If rollouts are stuck, look for pods stuck Terminating on a dead node
kubectl -n flexinfer-system get pods -o wide | rg Terminating
# Force-delete a stuck pod to unblock the rollout
kubectl -n flexinfer-system delete pod <pod-name> --force --grace-period=0

Future Roadmap

Phase 2 (Production Ready)

  • KV-Cache tiering: GPU HBM to host DDR memory management
  • Harbor model OCI plugin: Direct model registry integration
  • Advanced monitoring: Detailed performance analytics
  • Multi-tenancy: Namespace isolation and resource quotas

Phase 3 (Enterprise Features)

  • Autoscaling: HPA integration with custom metrics
  • Cost optimization: Advanced cost-aware scheduling
  • Security: Enhanced RBAC and admission controllers
  • Compliance: Audit logging and policy enforcement

Feedback & Support