====== Installing Kubevirt ======
===== Using a Helm TGZ =====
# Rebuild TGZ with your new path change
helm package /Users/mcalero/working-folder/helm/kubevirt --destination /Users/mcalero/working-folder/helm
helm upgrade --install kubevirt /Users/mcalero/working-folder/helm/kubevirt-0.1.0.tgz \
-n default \
--create-namespace \
--set localStorage.enabled=true \
--set localStorage.zededaPatch.enabled=true
===== Install Manually =====
# 1. Get the latest version string
export VERSION=$(curl -s https://api.github.com/repos/kubevirt/kubevirt/releases/latest | grep tag_name | cut -d '"' -f 4)
# 2. Deploy the Operator
kubectl create -f "https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-operator.yaml"
# 3. Deploy the KubeVirt Custom Resource (this starts the actual pods)
kubectl create -f "https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-cr.yaml"
kubectl get pods -n kubevirt -w
NAME READY STATUS RESTARTS AGE
kubevirt-cb56b74f311a9b7b360559903dba10b3cd6ec516-job4h7m7fpv97 1/1 Running 0 20s
virt-operator-584bd468cd-fbsxn 1/1 Running 0 39s
virt-operator-584bd468cd-fvprb 1/1 Running 0 39s
==== Install CDI ====
export VERSION=$(curl -s https://api.github.com/repos/kubevirt/containerized-data-importer/releases/latest | grep tag_name | cut -d '"' -f 4)
kubectl create -f https://github.com/kubevirt/containerized-data-importer/releases/download/$VERSION/cdi-operator.yaml
kubectl create -f https://github.com/kubevirt/containerized-data-importer/releases/download/$VERSION/cdi-cr.yaml
==== Local Storage Provisioner ====
If you are deploying on a 3-node cluster with **no shared store**, you need the Local Storage Provisioner:
kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml
**What this does:**
* Creates a StorageClass named ''local-path''
* When you request a 10Gi disk, it automatically picks a node, creates a folder under ''/opt/local-path-provisioner'' (on standard Linux) or whatever path you configure, and binds the VM there
==== Configure for ZEDEDA (''/persist/'') ====
kubectl patch configmap local-path-config -n local-path-storage --type merge -p '{"data":{"config.json":"{\n \"nodePathMap\": [\n {\n \"node\": \"DEFAULT_PATH_FOR_NON_LISTED_NODES\",\n \"paths\": [\"/persist/local-path-storage\"]\n }\n ]\n}"}}'
To check if validation failed:
kubectl logs -l cdi.kubevirt.io=importer
===== Deploying VMs =====
==== Console Access ====
virtctl console ubuntu-noble -n default
==== Monitor VM Coming Up ====
kubectl get vmi -w
kubectl get dv -w
# 1) NetworkAttachmentDefinition exists
kubectl get net-attach-def -n default
kubectl describe net-attach-def eth1-macvlan -n default
# 2) VM lifecycle
kubectl get vm -n default -w
kubectl get vmi -n default -w
# 3) Import/storage progress
kubectl get dv -n default -w
kubectl get pvc -n default -w
# 4) See real-time errors/events
kubectl get events -n default --sort-by=.lastTimestamp -w
==== Confirm NIC/IPs Once VM Is Up ====
kubectl get vmi ubuntu-noble -n default -o jsonpath='{range .status.interfaces[*]}{.name}{" ip="}{.ipAddress}{"\n"}{end}'