This article is dedicated to the open source project KubeVirt.io, which allows you to bring your virtual machine workloads to Kubernetes. A second part will explain how to use it with Kubermatic Kubernetes Platform.
What Is KubeVirt?
KubeVirt allows your virtual machine workloads to be run as pods inside a Kubernetes cluster. This allows you to manage them with Kubernetes without having to convert them to containers.
Why Do We Need KubeVirt?
Do you have a project running in VMs which you don’t want to convert to containers? Perhaps because it’s a legacy project for which you don’t want to go through the effort and expense of converting, but you’d like to orchestrate them with Kubernetes anyway?
Do you have a project for which you require the special features of VMs?
In these cases, KubeVirt is the answer for you!
Trying It Out
This tutorial will guide you through the installation of KubeVirt with Minikube. Minikube allows you to run Kubernetes on your local computer. A second part will show you how to use KubeVirt with Kubermatic Kubernetes Platform.
Install minikube
First, you have to follow the installation instructions to install minikube. Then start it with:
minikube start
You should see this output:
😄 minikube v1.17.1 on Darwin 11.2.3
✨ Using the docker driver based on user configuration
👍 Starting control plane node minikube in cluster minikube
🚜 Pulling base image ...
💾 Downloading Kubernetes v1.20.2 preload ...
> preloaded-images-k8s-v8-v1....: 491.22 MiB / 491.22 MiB 100.00% 3.84 MiB
🔥 Creating docker container (CPUs=2, Memory=1989MB) ...
🐳 Preparing Kubernetes v1.20.2 on Docker 20.10.2 ...
▪ Generating certificates and keys ...
▪ Booting up the control plane ...
▪ Configuring RBAC rules ...
🔎 Verifying Kubernetes components...
🌟 Enabled addons: storage-provisioner, default-storageclass
▪ Want kubectl v1.20.2? Try 'minikube kubectl -- get pods -A'
🏄 Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
You can use kubectl as usual in minikube, but you have to preface any command with minikube and put a – after kubectl. Example: the regular kubectl get pods
becomes minikube kubectl -- get pods
.
Enable Addon
Now you have to enable the KubeVirt addon:
minikube addons enable kubevirt
- Using image bitnami/kubectl:1.17
* The 'kubevirt' addon is enabled
You can now use KubeVirt! Check if the resources have been created correctly:
minikube kubectl -- get all -n kubevirt
You should see 7 pods, 3 services, 1 daemonset, 3 deployment apps, and 3 replica sets. It might take some time for all the objects to be ready and running.
NAME READY STATUS RESTARTS AGE
pod/virt-api-6bb566bbc7-crspt 1/1 Running 0 28m
pod/virt-api-6bb566bbc7-fh5jg 1/1 Running 0 28m
pod/virt-controller-5d6975c644-j4mbp 1/1 Running 2 28m
pod/virt-controller-5d6975c644-r6w7r 1/1 Running 3 28m
pod/virt-handler-brxxs 1/1 Running 2 28m
pod/virt-operator-976969b94-hsrpb 1/1 Running 2 30m
pod/virt-operator-976969b94-k78wh 1/1 Running 2 30m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubevirt-operator-webhook ClusterIP 10.102.7.174 <none> 443/TCP 28m
service/kubevirt-prometheus-metrics ClusterIP 10.102.43.88 <none> 443/TCP 28m
service/virt-api ClusterIP 10.111.29.61 <none> 443/TCP 28m
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE
daemonset.apps/virt-handler 1 1 1 1 1
NODE AGE
kubernetes.io/os=linux 28m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/virt-api 2/2 2 2 28m
deployment.apps/virt-controller 2/2 2 2 28m
deployment.apps/virt-operator 2/2 2 2 30m
NAME DESIRED CURRENT READY AGE
replicaset.apps/virt-api-6bb566bbc7 2 2 2 28m
replicaset.apps/virt-controller-5d6975c644 2 2 2 28m
replicaset.apps/virt-operator-976969b94 2 2 2 30m
NAME AGE PHASE
kubevirt.kubevirt.io/kubevirt 30m Deployed
Install virtctl
Run the following to install virtctl, a tool to explore graphical ports of the VM:
VERSION=$(kubectl get kubevirt.kubevirt.io/kubevirt -n kubevirt -o=jsonpath="{.status.observedKubeVirtVersion}")
ARCH=$(uname -s | tr A-Z a-z)-$(uname -m | sed 's/x86_64/amd64/') || windows-amd64.exe
echo ${ARCH}
curl -L -o virtctl https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/virtctl-${VERSION}-${ARCH}
chmod +x virtctl
sudo install virtctl /usr/local/bin
Create a VM Resource
Now create a file locally named vm.yaml, then copy and paste the below configuration into the file. Use minikube kubectl create -f vm.yaml
to create the VM resource on the cluster:
apiVersion: kubevirt.io/v1alpha3
kind: VirtualMachine
metadata:
name: testvm
spec:
running: false
template:
metadata:
labels:
kubevirt.io/size: small
kubevirt.io/domain: testvm
spec:
domain:
devices:
disks:
- name: containerdisk
disk:
bus: virtio
- name: cloudinitdisk
disk:
bus: virtio
interfaces:
- name: default
bridge: {}
resources:
requests:
memory: 64M
networks:
- name: default
pod: {}
volumes:
- name: containerdisk
containerDisk:
image: quay.io/kubevirt/cirros-container-disk-demo
- name: cloudinitdisk
cloudInitNoCloud:
userDataBase64: SGkuXG4=
Alternatively, you can download the manifest directly from Github using:
wget https://raw.githubusercontent.com/kubevirt/kubevirt.github.io/master/labs/manifests/vm.yaml
Then apply it to the cluster using the command:
minikube kubectl -- apply -f https://raw.githubusercontent.com/kubevirt/kubevirt.github.io/master/labs/manifests/vm.yaml
virtualmachine.kubevirt.io "testvm" created
virtualmachineinstancepreset.kubevirt.io "small" created
Use kubectl get
to check the VM status:
$ kubectl get vms
NAME AGE VOLUME
testvm 12m
You can get more information about the created “testvm” using:
$ kubectl get vms -o yaml testvm
Starting a Virtual Machine
You can start a virtual machine by using virtctl:
./virtctl start testvm
Alternatively, you can use kubectl patch
:
'{"spec":{"running":true}}'
Check if the virtual machines are running:
minikube kubectl -- get vms
NAME AGE RUNNING VOLUME
testvm 5s false
Peradventure the “Running” column is missing, you can use kubectl describe to check if the VM is running. The output will look like this:
$ kubectl describe vm
Spec:
Running: true
Template:
Metadata:
Creation Timestamp: <nil>
Labels:
kubevirt.io/domain: testvm
kubevirt.io/size: small
Now that the vm is running, you can check the status. The status could come in three phases which are:
$ kubectl get vmis
NAME AGE PHASE IP NODENAME
testvm 50s Scheduling
$ kubectl get vmis
NAME AGE PHASE IP NODENAME
testvm 3m43s Scheduled minikube
$ kubectl get vmis
NAME AGE PHASE IP NODENAME
testvm 14m Running 172.17.0.11 minikube
Scheduling: This is the beginning of the phases where the VM components are provisioned.
Scheduled: The status changes to “scheduled” after a few minutes which also signals that the node is ready by outputting the node name.
Running: This is the final stage where all the components have been provisioned by outputting the IP address.
As seen above, you are able to access your virtual machines with kubectl just like you would be able to with pods.
Clean-Up: Shutdown and delete To stop your virtual machine run:
./virtctl stop testvm
VM testvm was scheduled to stop
To delete the VM entirely, execute:
virtualmachine.kubevirt.io "testvm" deleted
Stop minikube after you are done with the tutorial:
minikube stop
Delete minikube: minikube delete –all
- Successfully deleted all profiles
Conclusion
This is the first part of this blog post. The next part will guide you through using KubeVirt with Kubermatic Kubernetes Platform.
Where to Learn More
- Read more on how to use KubeVirt on the official documentation page
- Learn more on KubeVirt here
- Read more on how the KubeVirt upgrade works