Getting started
Create your first VirtualCluster
This guide assumes a Ready Cell and an existing quota tier. If you have not onboarded a host yet, start with host onboarding.
Before you start
- The target Cell is Ready: OCM
Joined=True, a freshmanaged-cluster-lease, and fresh inventory. - The quota tier (
VirtualNodeClass) you intend to use already exists. - You are applying into
kubecell-systemon the management cluster, where the controller lives.
1. Inspect the Cell before requesting anything
Feasibility conclusions are only as good as the inventory they read. Check freshness first, then look at headroom.
kubectl-n kubecell-system get cell cell1 -o yaml | less# Things to look at in status:# conditions -> InventoryFresh must be true# nodes[] -> per-node capacity, allocatable, active/pending requests# inventory -> aggregated available estimates per resource# storageInventory -> freeCapacityKnown and freshnessStop if inventory is stale
IfInventoryFresh is false or key inventory is unknown, do not create anything. Contact operations; no feasibility conclusion is trustworthy at that point.2. Preflight with a Plan
Write a VirtualClusterPlan with exactly the content you intend to create. Wait for status.decision and read checks when it is rejected.
apiVersion: kubecell.io/v1alpha1kind: VirtualClusterPlanmetadata: name: child-dev-plan namespace: kubecell-systemspec: cellRef: {name: cell1} classRef: {name: ascend-910b-small}kubectl apply-f plan.yamlkubectl-n kubecell-system get vcp child-dev-plan \ -o jsonpath='{.status.decision}{"\n"}'# Rejected? Read the failed items and adjust the request or the Cell.kubectl-n kubecell-system get vcp child-dev-plan \ -o jsonpath='{range .status.checks[*]}{.resource}{"\t"}{.result}{"\n"}{end}'Accepted means buildable under the current snapshot; Rejected means a specific resource is missing; Unknown means the inventory was insufficient to decide. Remember that acceptance is not reservation: the controller rechecks at creation time.
3. Create the VirtualCluster
The Plan and the VirtualCluster are isomorphic — the same file with a different kind. The webhook validates that references exist and quota keys are legal.
apiVersion: kubecell.io/v1alpha1kind: VirtualClustermetadata: name: child-dev namespace: kubecell-systemspec: cellRef: {name: cell1} classRef: {name: ascend-910b-small}kubectl apply-f virtualcluster.yaml# The first Ready transition typically takes 10-20 minutes (image pulls).kubectl-n kubecell-system wait --for=condition=Ready vc/child-dev --timeout=25mkubectl-n kubecell-system get vc child-dev -o wide4. Fetch the admin kubeconfig
The controller reads the K3k-generated kubeconfig through the OCM proxy, rewrites the server address to the discovered host address and NodePort, and publishes it as a Secret in the management plane. The Secret is always published; treat it as a credential.
VC=child-dev# The Secret name embeds the VirtualCluster UIDSECRET=$(kubectl-n kubecell-system get vc $VC \ -o jsonpath='{.status.credential.secretName}')kubectl-n kubecell-system get secret "$SECRET" \ -o jsonpath='{.data.kubeconfig\.yaml}' | base64 -d > $VC.yamlchmod600 $VC.yamlkubectl--kubeconfig $VC.yaml get nodeskubectl--kubeconfig $VC.yaml get ns5. Verify workloads, storage, and ingress
cat<<'EOF' | kubectl --kubeconfig child-dev.yaml apply -f -apiVersion: v1kind: Podmetadata: name: cpu-smokespec: containers: - name: app image: registry.k8s.io/pause:3.10 resources: requests: {cpu: 100m, memory: 128Mi} limits: {cpu: 200m, memory: 256Mi}EOF# Confirm the reflected host Pod and quota accountingkubectl-n kubecell-system get vc child-dev \ -o jsonpath='{.status.host.quotaUsed}{"\n"}'- The child cluster has exactly one node named
kubelet. - A child PVC becomes a host PVC backed by TopoLVM; check that it binds, not just that it is created.
hostPathvolumes are rejected at admission with a replacement hint — this is expected behavior, not a bug.- Ingress: create a standard Ingress with class
kubecellin the child cluster, then reach it athttp://<ingress>.<vc>.apps.example.com.
6. Delete it cleanly
kubectl-n kubecell-system delete vc child-dev# The finalizer removes both ManifestWorks by UID, which removes the host# namespace, quota, policy, and the K3k cluster. Under Retain, PVs become# Released and data is preserved.Next: day-2 operations, or jump to the troubleshooting guide if something is not Ready.