KubeVirt Quickstart with Minikube

This guide will help you deploying KubeVirt on Kubernetes, we’ll be using Minikube.

Our recommendation is to always run the latest (*) version of Minikube available for your platform of choice, following their installation intructions. For instance, to write this guide, the Linux version has been used, together with the KVM2 driver.

(*): KubeVirt >=v0.9.2 won’t run on Minikube <v0.35.0 by default because of lack of vhost-net device. (see more details at Issue#2056)

Finally, you’ll need kubectl installed (*), it can be downloaded from here or installed using the means available for your platform.

(*): Ensure that *kubectl* version complies with the supported release skew (The version of kubectl should be close to Kubernetes server version).

Start Minikube

Before starting with Minikube, let’s verify whether nested virtualization is enabled on the host where Minikube is being installed on:

cat /sys/module/kvm_intel/parameters/nested

If you get an N, follow the instructions described here for enabling it.

Note that nested virtualization is not mandatory for testing KubeVirt, but makes things smoother. If for any reason it can’t be enabled, don’t forget to enable emulation as shown in the Check for the Virtualization Extensions section.

Let’s begin, normally, Minikube can be started with default values and those will be enough to run this quickstart guide, that being said, if you can spare few more GiBs of RAM (by default it uses 2GiB), it’ll allow you to experiment further this guide.

We’ll create a profile for KubeVirt so it gets its own settings without interfering what any configuration you might had already, let’s start by increasing the default memory to 4GiB:

minikube config -p kubevirt set memory 4096

Now, set the VM driver to KVM2:

minikube config -p kubevirt set vm-driver kvm2

We’re ready to start the Minikube VM:

minikube start -p kubevirt

Deploy KubeVirt Operator

Having the Minikube VM is up and running, let’s set the version environment variable that will be used on few commands:

export KUBEVIRT_VERSION="v0.15.0"

Now, using the kubectl tool, let’s deploy the KubeVirt Operator:

kubectl create -f https://github.com/kubevirt/kubevirt/releases/download/${KUBEVIRT_VERSION}/kubevirt-operator.yaml

Check it’s running:

kubectl get pods -n kubevirt
NAME                             READY     STATUS              RESTARTS   AGE
virt-operator-6c5db798d4-9qg56   0/1       ContainerCreating   0          12s
...
virt-operator-6c5db798d4-9qg56   1/1       Running   0         28s

We’ll need to execute the command above few times (or add -w for watching the pods), until the operator is Running and Ready (1/1), then it’s time to head to the next section.

Check for the Virtualization Extensions

To check if your VM’s CPU supports virtualization extensions execute the following command:

minikube ssh -p kubevirt "egrep 'svm|vmx' /proc/cpuinfo"

If the command doesn’t generate any output, create the following ConfigMap so that KubeVirt uses emulation mode, otherwise skip to the next section:

kubectl create configmap kubevirt-config -n kubevirt --from-literal debug.useEmulation=true

Deploy KubeVirt

KubeVirt is then deployed by creating a dedicated custom resource:

kubectl create -f https://github.com/kubevirt/kubevirt/releases/download/${KUBEVIRT_VERSION}/kubevirt-cr.yaml

Check the deployment:

kubectl get pods -n kubevirt
NAME                               READY     STATUS    RESTARTS   AGE
virt-api-649859444c-fmrb7          1/1       Running   0          2m12s
virt-api-649859444c-qrtb6          1/1       Running   0          2m12s
virt-controller-7f49b8f77c-kpfxw   1/1       Running   0          2m12s
virt-controller-7f49b8f77c-m2h7d   1/1       Running   0          2m12s
virt-handler-t4fgb                 1/1       Running   0          2m12s
virt-operator-6c5db798d4-9qg56     1/1       Running   0          6m41s

Once we applied the Custom Resource the operator took care of deploying the actual KubeVirt pods (virt-api, virt-controller and virt-handler). Again we’ll need to execute the command until everything is up&running (or use -w).

Install virtctl

An additional binary is provided to get quick access to the serial and graphical ports of a VM, and handle start/stop operations. The tool is called virtctl and can be retrieved from the release page of KubeVirt:

curl -L -o virtctl \
    https://github.com/kubevirt/kubevirt/releases/download/${KUBEVIRT_VERSION}/virtctl-${KUBEVIRT_VERSION}-linux-amd64
chmod +x virtctl

Deploy a VirtualMachine

Now that KubeVirt is ready, let’s deploy our first VM:

kubectl apply -f https://raw.githubusercontent.com/kubevirt/kubevirt.github.io/master/labs/manifests/vm.yaml

Using kubectl we can get the object and its YAML definition:

kubectl get vms
kubectl get vms -o yaml testvm

Note the field running is set to false, that means we’ve only defined the object but it now needs to be instantiated. So let’s start the VM:

./virtctl start testvm

Then again, using kubectl, let’s query for the VM instance:

kubectl get vmis
kubectl get vmis -o yaml testvm

Note the added i, as it stands for VirtualMachineInstance. Now, pay attention to the phase field, its value will be transitioning from one state to the next, indicating VMI progress to finish being set to Running.

Using again virtctl, let’s connect to the VMI consoles interfaces:

./virtctl console testvm
./virtctl vnc testvm

Remember that for exiting from the console to hit Ctrl+] (Control plus closing square bracket).

Note: VNC requires remote-viewer from the virt-viewer package installed on the host.

Clean Up:

Let’s stop the VM instance:

./virtctl stop testvm

Delete the VM:

kubectl delete vm testvm

Delete the VM:

minikube delete -p kubevirt