Salta ai contenuti

vCluster Cheat Sheet

Overview

vCluster creates fully functional virtual Kubernetes clusters that run inside namespaces of a host cluster. Each virtual cluster has its own API server, control plane, and syncer component but shares the underlying host cluster’s compute resources and worker nodes. This provides strong multi-tenancy isolation — each tenant gets their own cluster experience with full admin access, custom CRDs, and independent RBAC — without the overhead of provisioning separate physical clusters.

vCluster is particularly valuable for development environments, CI/CD pipelines, testing, and multi-tenant platforms where teams need isolated Kubernetes environments that can be created and destroyed in seconds. Virtual clusters support all standard Kubernetes operations including Helm installs, CRD management, and admission webhooks, while the host cluster administrator maintains control over resource quotas and network policies at the namespace level.

Installation

CLI Installation

# macOS
brew install loft-sh/tap/vcluster

# Linux
curl -L -o vcluster "https://github.com/loft-sh/vcluster/releases/latest/download/vcluster-linux-amd64"
chmod +x vcluster
sudo mv vcluster /usr/local/bin/

# Windows
scoop install vcluster

# Verify
vcluster --version

Helm Installation

# Add Loft Helm repo
helm repo add loft https://charts.loft.sh
helm repo update

# Install vCluster operator (optional, for platform mode)
helm install vcluster-platform loft/vcluster-platform \
  --namespace vcluster-platform \
  --create-namespace

Core Commands

Creating Virtual Clusters

# Create a basic vCluster
vcluster create my-vcluster

# Create in specific namespace
vcluster create dev-cluster --namespace team-alpha

# Create with specific K8s distribution
vcluster create my-vcluster --distro k8s    # Full k8s (default)
vcluster create my-vcluster --distro k3s    # Lightweight k3s
vcluster create my-vcluster --distro k0s    # k0s distribution
vcluster create my-vcluster --distro eks    # EKS compatible

# Create with custom values
vcluster create staging --values vcluster-values.yaml

# Create and connect immediately
vcluster create dev-env --connect

# Create with specific Kubernetes version
vcluster create test --kubernetes-version v1.29.0

# Create with resource limits
vcluster create constrained \
  --set syncer.resources.limits.cpu=500m \
  --set syncer.resources.limits.memory=512Mi

Connecting and Managing

# Connect to a virtual cluster (updates kubeconfig)
vcluster connect my-vcluster

# Connect with specific namespace
vcluster connect my-vcluster --namespace team-alpha

# Connect and update specific kubeconfig
vcluster connect my-vcluster --update-current=false --kube-config ./vcluster-kubeconfig.yaml

# List all virtual clusters
vcluster list

# List across all namespaces
vcluster list --all-namespaces

# Disconnect (restore original kubeconfig context)
vcluster disconnect

# Pause a virtual cluster (saves resources)
vcluster pause my-vcluster

# Resume a paused virtual cluster
vcluster resume my-vcluster

# Delete a virtual cluster
vcluster delete my-vcluster
vcluster delete my-vcluster --namespace team-alpha

# Delete and clean up all resources
vcluster delete my-vcluster --delete-namespace

Working Inside a vCluster

# After connecting, use kubectl normally
vcluster connect dev-cluster

# Deploy applications
kubectl create namespace app
kubectl apply -f deployment.yaml -n app

# Install Helm charts
helm install nginx ingress-nginx/ingress-nginx -n ingress

# Create CRDs (isolated from host)
kubectl apply -f custom-crd.yaml

# Full cluster admin access
kubectl get nodes      # Shows synced nodes from host
kubectl get namespaces # Independent namespace list
kubectl get crds       # Independent CRD list

# Check cluster info
kubectl cluster-info

Configuration

Values File

# vcluster-values.yaml
# Syncer configuration
sync:
  # Sync real nodes into the vCluster
  nodes:
    enabled: true
    syncAllNodes: true
  
  # Sync persistent volumes
  persistentvolumes:
    enabled: true
  
  # Sync ingresses to host
  ingresses:
    enabled: true
  
  # Sync network policies
  networkpolicies:
    enabled: true
  
  # Sync storage classes from host
  storageclasses:
    enabled: true

# Control plane configuration
controlPlane:
  distro:
    k8s:
      enabled: true
      apiServer:
        extraArgs:
          - "--audit-log-path=/var/log/audit.log"
      image:
        tag: "v1.29.0"
  
  statefulSet:
    resources:
      limits:
        cpu: "1"
        memory: 2Gi
      requests:
        cpu: 200m
        memory: 256Mi

# Isolation and security
policies:
  resourceQuota:
    enabled: true
    quota:
      requests.cpu: "10"
      requests.memory: 20Gi
      limits.cpu: "20"
      limits.memory: 40Gi
      pods: "100"
      services: "20"
      persistentvolumeclaims: "10"
  
  limitRange:
    enabled: true
    default:
      cpu: 500m
      memory: 512Mi
    defaultRequest:
      cpu: 100m
      memory: 128Mi

# Networking
networking:
  replicateServices:
    fromHost:
      - from: monitoring/prometheus
        to: monitoring/prometheus
    toHost:
      - from: default/my-service
        to: team-alpha/vcluster-service

# Storage
storage:
  persistence: true
  size: 5Gi

Helm-Based Creation

# Create using Helm directly
helm install my-vcluster loft/vcluster \
  --namespace team-alpha \
  --create-namespace \
  --values vcluster-values.yaml \
  --set syncer.extraArgs="{--tls-san=my-vcluster.example.com}"

# Upgrade vCluster configuration
helm upgrade my-vcluster loft/vcluster \
  --namespace team-alpha \
  --values vcluster-values.yaml

# Template to see what will be created
helm template my-vcluster loft/vcluster \
  --namespace team-alpha \
  --values vcluster-values.yaml

Advanced Usage

CI/CD Integration

#!/bin/bash
# ci-vcluster.sh — Ephemeral vCluster for CI/CD testing
set -euo pipefail

CLUSTER_NAME="ci-${CI_PIPELINE_ID:-$(date +%s)}"
NAMESPACE="ci-environments"

cleanup() {
  echo "Cleaning up vCluster: $CLUSTER_NAME"
  vcluster delete "$CLUSTER_NAME" --namespace "$NAMESPACE" || true
}
trap cleanup EXIT

# Create ephemeral cluster
echo "Creating vCluster: $CLUSTER_NAME"
vcluster create "$CLUSTER_NAME" \
  --namespace "$NAMESPACE" \
  --connect=false \
  --set syncer.resources.limits.cpu=500m \
  --set syncer.resources.limits.memory=1Gi

# Connect and get kubeconfig
vcluster connect "$CLUSTER_NAME" \
  --namespace "$NAMESPACE" \
  --update-current=false \
  --kube-config /tmp/vcluster-kubeconfig.yaml

export KUBECONFIG=/tmp/vcluster-kubeconfig.yaml

# Deploy and test
kubectl apply -f manifests/
kubectl wait --for=condition=Ready pods --all --timeout=120s
./run-integration-tests.sh

echo "Tests completed. Cleaning up."

Multi-Tenant Platform

# platform-template.yaml — Template for tenant clusters
apiVersion: management.loft.sh/v1
kind: VirtualClusterTemplate
metadata:
  name: team-cluster
spec:
  template:
    metadata: {}
    instanceTemplate:
      metadata:
        labels:
          managed-by: platform-team
    helmRelease:
      values: |
        sync:
          ingresses:
            enabled: true
          networkpolicies:
            enabled: true
        policies:
          resourceQuota:
            enabled: true
            quota:
              requests.cpu: "8"
              requests.memory: 16Gi
              pods: "50"
          limitRange:
            enabled: true
            default:
              cpu: 500m
              memory: 512Mi

Exposing vCluster Externally

# Expose via LoadBalancer
vcluster create external-cluster \
  --set controlPlane.service.type=LoadBalancer \
  --set syncer.extraArgs="{--tls-san=vcluster.example.com}"

# Expose via Ingress
vcluster create external-cluster \
  --set controlPlane.ingress.enabled=true \
  --set controlPlane.ingress.host=vcluster.example.com

# Get external kubeconfig
vcluster connect external-cluster \
  --server=https://vcluster.example.com \
  --kube-config ./external-kubeconfig.yaml

Sleep Mode (Auto-Pause Idle Clusters)

# Create with auto-sleep after 30 minutes of inactivity
vcluster create dev-env \
  --set policies.autoSleep.afterInactivity=1800

# Or via values file
# policies:
#   autoSleep:
#     afterInactivity: 1800  # seconds
#     autoWakeup: true

Troubleshooting

IssueCauseSolution
vCluster pods CrashLoopBackOffInsufficient resources on hostIncrease syncer resource limits in values
Cannot connect to vClusterPort-forward not establishedRun vcluster connect again or check host connectivity
Pods not scheduling in vClusterHost namespace resource quota exceededIncrease host namespace quota or add more nodes
Services not accessibleService sync not enabledEnable sync.services in values file
PVC not provisioningStorageClass sync disabledEnable sync.storageclasses.enabled: true
CRDs not workingCRD sync not configuredCRDs are isolated by default; this is expected behavior
Ingress not routingIngress sync not enabledEnable sync.ingresses.enabled: true
Node list emptyNode sync disabledEnable sync.nodes.enabled: true
# Debug vCluster syncer logs
kubectl logs -n team-alpha -l app=vcluster,release=my-vcluster -c syncer --tail=50

# Check vCluster status
vcluster list
kubectl get pods -n team-alpha -l app=vcluster

# Debug host-side resources
kubectl get pods -n team-alpha
kubectl get events -n team-alpha --sort-by='.lastTimestamp'

# Check syncer connectivity
kubectl exec -n team-alpha deploy/my-vcluster -- cat /tmp/syncer.log

# Force reconnect
vcluster disconnect
vcluster connect my-vcluster --namespace team-alpha