Treat VMs as a Kubernetes Object Using KubeVirt
KubeVirt provides a unified development platform where developers can build, modify, and deploy applications residing in both Containers and Virtual Machines in a common environment. This lesson guides the user through all the steps required to install KubeVirt on a Kubernetes cluster and run a Virtual Machine. On completing this lesson, the user will learn the following skills:
- Installation of the latest KubeVirt using operators and the KubeVirt Custom Resource
- Installation of virtctl, the command-line client for managing Virtual Machines
- Use of kubectl and virtctl commands to create, start, stop, and report status of Virtual Machines
Deploy KubeVirt
Deploy the KubeVirt operator using the latest KubeVirt version. An Operator is a method of packaging, deploying and managing a Kubernetes application. A Kubernetes application is an application that is both deployed on Kubernetes and managed using the Kubernetes APIs and kubectl tooling. You can think of Operators as the runtime that manages this type of application on Kubernetes. If you want to learn more about Operators you can check here.
We query GitHub's API to get the latest available release. Assuming that you're connected to some Kubernetes cluster, execute the following code on your terminal:
export KUBEVIRT_VERSION=$(curl -s https://api.github.com/repos/kubevirt/kubevirt/releases/latest | jq -r .tag_name)
echo $KUBEVIRT_VERSION
Run the following command to deploy the KubeVirt Operator:
kubectl create -f https://github.com/kubevirt/kubevirt/releases/download/${KUBEVIRT_VERSION}/kubevirt-operator.yaml
Now let's deploy KubeVirt by creating a Custom Resource that will trigger the 'operator' reaction and perform the deployment:
kubectl create -f https://github.com/kubevirt/kubevirt/releases/download/${KUBEVIRT_VERSION}/kubevirt-cr.yaml
Next, we need to configure KubeVirt to use software emulation for virtualization. This is necessary for the development environment, but results in poor performance, so avoid this step in production environments.
kubectl -n kubevirt patch kubevirt kubevirt --type=merge --patch '{"spec":{"configuration":{"developerConfiguration":{"useEmulation":true}}}}'
Let's check the deployment:
kubectl get pods -n kubevirt
Once it's ready, it will show something similar to:
~~~
controlplane $ kubectl get pods -n kubevirt
NAME READY STATUS RESTARTS AGE
virt-api-7fc57db6dd-g4s4w 1/1 Running 0 3m
virt-api-7fc57db6dd-zd95q 1/1 Running 0 3m
virt-controller-6849d45bcc-88zd4 1/1 Running 0 3m
virt-controller-6849d45bcc-cmfzk 1/1 Running 0 3m
virt-handler-fvsqw 1/1 Running 0 3m
virt-operator-5649f67475-gmphg 1/1 Running 0 4m
virt-operator-5649f67475-sw78k 1/1 Running 0 4m
~~~
Install Virtctl
`virtctl` is a client utility that helps interact with VM's (start/stop/console, etc):
wget -O virtctl https://github.com/kubevirt/kubevirt/releases/download/${KUBEVIRT_VERSION}/virtctl-${KUBEVIRT_VERSION}-linux-amd64
chmod +x virtctl
Now everything is ready to continue and launch a VM.
Deploy a VM
The command below applies a YAML definition of a virtual machine into our current Kubernetes environment, defining the VM name, the resources required (disk, CPU, memory), etc. You can take a look at the vm.yaml file if you have interest in knowing more about a virtual machine definition:
kubectl apply -f https://kubevirt.io/labs/manifests/vm.yaml
We are creating a Virtual Machine in the same way as we would create any other Kubernetes resource thanks to what KubeVirt has enabled in our environment. Now we have a Virtual Machine as a Kubernetes resource.
After the vm resource has been created, you can manage the VMs with standard 'kubectl' commands:
kubectl get vms
kubectl get vms -o yaml testvm
Check that the VM is defined (using commands above):
kubectl get vms
Notice from the output that the VM is not running yet.
To start a VM, `virtctl` should be used:
./virtctl start testvm
Alternatively you can use `kubectl edit vm testvm` to set `.spec.running: true`.
Now you can check again the VM status:
kubectl get vms
A `VirtualMachine` resource contains a VM's definition and status. An instance of a running VM has an additional associated resource, a `VirtualMachineInstance`.
Once the VM is running you can inspect its status:
kubectl get vmis
kubectl get vmis -o yaml testvm
kubectl get vmis
Once it's ready, the command above will print something like:
~~~ controlplane $ kubectl get vmis
NAME AGE PHASE IP NODENAME
testvm 1m Running 10.32.0.11 controlplane
~~~
Accessing VMs (serial console & vnc)
Now that a VM is running you can access its serial console:
~~~ # Connect to the serial console $ ./virtctl console testvm ~~~
In environments where VNC client access is available, the graphical console of a VM can be accessed with the virtctl vnc command.
Shutdown and cleanup
Shutting down a VM works by either using `virtctl` or editing the VM.
./virtctl stop testvm
Finally, the VM can be deleted using:
kubectl delete vms testvm
Reference
This lesson is referenced from this public GitHub repository.