Hi, dear readers I am starting a new series of blog posts called Learning Kubernetes with different complementing the traditional knowledge of Kubernetes. In this first post that I am going to share with my students in the university is about how to use KubeVirt in Kubernetes. One of my main topics in my course is virtualization so let me summarize my goals for writing this blog post:
- Use VMs in container environments
- Test how easy to use is KubeVirt
- Customize my own VMs on a Kubernetes environment
- Install KubeVirt on any Cloud Provider(GCP in specific) So let's start with the tutorial using KubeVirt. Let's have fun.
What you will learn
In this blog post you will learn how to:
- Install KubeVirt bypassing the default requirements
- Create a custom VM image in qcow2 with Qemu
- Package your qcow2 image in a container image
- Create a VM and expose VM services in KubeVirt
Requirements
- A GKE cluster (Kubernetes cluster managed by Google Cloud)
- Access to the cluster using kubectl
- Preinstalled qemu in your distro (Let's asume Ubuntu) So let's get started with this tutorial. :)
Install KubeVirt bypassing the default requirements
To install KubeVirt get the KubeVirt latest stable version running the following steps:
1. Download the kubevirt-operator.yaml file and remove the affinity and tolerations:
export VERSION=$(curl -s https://storage.googleapis.com/kubevirt-prow/release/kubevirt/kubevirt/stable.txt)
wget https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-operator.yaml
Note: This downloads the kubevirt-operator.yaml file that you have to change to install the operator in any cloud provider like GKE, AKS or EKS. You have to change this file to remove the affinity and tolerations that the operator looks to deploy its components. KubeVirt looks for a control-plane node for security reason to deploy the operator.
2. Install the operator with the modified kubevirt-operator.yaml file
kubectl create -f "https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-operator.yaml"
3. Create a KubeVirt definition to deploy the custom resource definitions:
cat << END > kubevirt-cr.yaml
apiVersion: kubevirt.io/v1
kind: KubeVirt
metadata:
name: kubevirt
namespace: kubevirt
spec:
certificateRotateStrategy: {}
configuration:
developerConfiguration:
featureGates: []
customizeComponents: {}
imagePullPolicy: IfNotPresent
workloadUpdateStrategy: {}
infra:
nodePlacement: {}
workloads:
nodePlacement: {}
END
4. Deploy the definitions
kubectl apply -f kubevirt-cr.yaml
5. Wait for the deployments to be ready you
kubectl get all -n kubevirt
Create a custom VM image in qcow2 with Qemu
Assuming that you have an Ubuntu OS run the following steps:
1. Install Qemu:
sudo apt install qemu-kvm qemu-utils libvirt-daemon-system libvirt-clients bridge-utils
2. In a directory create a disk for your VM, we are going to use Alpine for our VM:
qemu-img create -f qcow2 alpine_disk.qcow2 1G
3. Download the ISO image for your Alpine VM
wget https://dl-cdn.alpinelinux.org/alpine/v3.23/releases/x86_64/alpine-standard-3.23.2-x86_64.iso
4. Start the new Qemu VM and install the OS:
sudo qemu-system-x86_64 -enable-kvm -m 2G -cpu host -smp 2 -cdrom alpine-standard-3.22.0-x86_64.iso -drive file=alpine_disk.qcow2,format=qcow2 -boot d
5. Boot from disk instead of the CD-ROM and install your software:
sudo qemu-system-x86_64 -enable-kvm -m 2G -cpu host -smp 2 -drive file=alpine_disk.qcow2,format=qcow2
6. Your new image alpine_disk.qcow2 its ready to be used.
Package your qcow2 image in a container image
Assuming that you have a Docker Hub user and you are login in your account run the following steps:
1. Create the Dockerfile to package for image
cat << END > Dockerfile
FROM scratch
ADD --chown=107:107 alpine_disk.qcow2 /disk/
END
2. Tag you image with your Docker user
docker build -t <docker_hub_user>/alpineimage:latest .
docker push <docker_hub_user>/alpineimage:latest
Create a VM a expose VM services in KubeVirt
To create a basic KubeVirt VM follow the next steps:
1. Create the KubeVirt VM definition
cat << END > vm.yaml
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: alpinevm
spec:
runStrategy: Halted
template:
metadata:
labels:
kubevirt.io/size: small
kubevirt.io/domain: alpineso1
spec:
domain:
devices:
disks:
- name: containerdisk
disk:
bus: virtio
interfaces:
- name: default
masquerade: {}
resources:
requests:
memory: 200M
networks:
- name: default
pod: {}
volumes:
- name: containerdisk
containerDisk:
image: <docker_hub_user>/alpineimage
END
2. Apply the definition
kubectl apply -f vm.yaml
3. Check for the vm to be created
kubectl get vms
You will see the VM in the stopped state
4. Install virtctl CLI
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}
sudo install -m 0755 virtctl /usr/local/bin
5. Start the VM
virtctl start alpinevm
6. Expose any service you have on the VM
virtctl expose vm alpinevm--port=<PORT_NUMBER>--name=<NEW_SERVICE_NAME> --type=ClusterIP
7. Now you can access the service of your VM in any Kubernetes Pod, Deployment, etc.
Conclusion about KubeVirt
KubeVirt is a technology that can be used when your applications are difficult to convert to containers or there is an specific situation where containers are not suitable to be used. Also for security reasons some systems prefer the use of VMs instead of containers and already have a Kubernetes environment that should interact with this VMs.
KubeVirt its an option option for VMs. In the university, we are testing KubeVirt to run some experiments with cloud native technologies. It was nice to create a VM using Qemu again and see that virtual machines needs to be used also in containerized environments. So it was a nice experience playing with KubeVirt a little bit.
See you on my next post with something interesting again.
Follow me
These are my social networks:
https://www.linkedin.com/in/sergioarmgpl
https://sergiops.xyz
https://x.com/sergioarmgpl
https://www.instagram.com/sergioarmgpl/
Please contribute to this awesome project:
Top comments (0)