How to install KubeOps Virtualization (kubevirt)
Categories:
5 minute read
KubeVirt provides a powerful way to run virtual machines on top of Kubernetes, creating a unified platform for both containerized and traditional workloads. This guide walks through the essential steps for getting KubeVirt up and running using the KOSI package manager - from pulling and preparing the KubeVirt package, to creating a custom configuration file with your credentials, and finally verifying a successful installation in the kubevirt-namespace. Once these steps are complete, you’ll be ready to deploy and manage virtual machines alongside your existing container infrastructure - all within a single Kubernetes cluster.
KubeVirt is a specialized package that extends the capabilities of the KubeOps platform to support machine virtualization.
Requirements
To follow the next steps, make sure you have your credentials ready from your KubeOps.net account.
Make sure you have prepared the following points:
- A KubeOps cluster with one master node.
- Access to the master node with root privileges.
Step 1 - Download KubeOpsVM
- Log in to the master node remotely. For example, using
ssh. - If necessary, switch to your cluster user. If you forgot your cluster user, check your
cluster-values.yaml.
su <your linux username>
- Log in to KOSI using your KOSI username.
kosi login -u [USERNAME]
- Search for available software packages by using the KOSI package manager.
In this case, we restrict the search to KubeOps virtualization using
kubeops-vm.
kosi search --hub kubeops-vm

- Log in to the local container registry on the master node using
podman. Replace<master-ip>with the IP address of your master node.
podman login <master-ip>:30002 -u admin -p <harbor admin password> --tls-verify=false
- The package is named
kubeops/kubevirt:2.2.0_Beta0and lies on the hubkubeops-vm. Download the package using thekosi pullcommand and save it with the desired file name. In this example, the file is saved askubevirt-2.2.0_Beta0.tgz. The-rflag sets the source registry the container images are pulled from, and-tsets the local target registry the images are pushed to.
kosi pull --hub kubeops-vm kubeops/kubevirt:2.2.0_Beta0 -o kubevirt-2.2.0_Beta0.tgz -r <master-ip>:30002/kubeops -t 127.0.0.1:30002/kubeops
Step 2 - Remove the Taint of the Master Node (only necessary on single node cluster)
This step is only required for a single-node cluster.
If your cluster consists of only one node, you must remove the taint from the master node so that workloads can be scheduled on it.
Replace [NODENAME] with the name of you master node.
kubectl taint nodes [NODENAME] node-role.kubernetes.io/control-plane:NoSchedule-
Step 3 - Create Kubevirt Configuration File
Before installing the package, create a YAML configuration file. Save the following content in the same directory as the package file and name the file kubevirt-values.yaml.
Replace
[your username]and[your harbor cli secret]with your KOSI username and your Harbor CLI secret.
The harbor-values must be adapted to your harbor instance.
apiVersion: kubeops/kubeopsctl/enterprise/beta/v1
deleteNs: false
localRegistry: true
packages:
- name: kubevirt-manager
enabled: true
values:
standard:
namespace: kubevirt
hostname: kubeops-vms.local
nodeport: 30733
ingressName: nginx
advanced: {}
- name: kubevirt
enabled: true
hub: kubeops-vm
values:
standard:
namespace: kubevirt
imagePullSecretCred:
registry: 127.0.0.1:30002/kubeops
user: [your username]
password: [your harbor cli secret] # must be CLI Token from harbor
kubevirtobject:
spec:
configuration:
developerConfiguration:
logVerbosity:
virtLauncher: 2
virtHandler: 3
virtController: 4
virtAPI: 5
virtOperator: 6
featureGates:
- ExpandDisks
- CPUManager
- ExperimentalIgnitionSupport
- HypervStrictCheck
- Sidecar
- HostDevices
- Snapshot
- VMExport
- HotplugVolumes
- HostDisk
- ExperimentalVirtiofsSupport
- DownwardMetricsFeatureGate
- Root
- ClusterProfiler
- WorkloadEncryptionSEV
- VSOCK
- DisableCustomSELinuxPolicy
- KubevirtSeccompProfile
- DisableMDEVConfiguration
- PersistentReservation
- VMPersistentState
- MultiArchitecture
- AutoResourceLimitsGate
- AlignCPUs
- VolumesUpdateStrategy
- VolumeMigration
- InstancetypeReferencePolicy
useEmulation: false
cdiobject:
spec:
config:
insecureRegistries:
- registry.preprod.kubeops.net
scratchSpaceStorageClass: rook-cephfs # Optional; Default: rook-cephfs
- name: harbor
enabled: false
values:
standard:
namespace: harbor # optional, default is harbor
ingressClassName: nginx # optional, default is nginx; set to "traefik" to route via Traefik
harborpass: "password" # required: set password for harbor access
databasePassword: "Postgres_Password" # required: set password for database access
redisPassword: "Redis_Password" # required: set password for redis access
externalURL: http://10.2.10.11:30002 # required, the ip address and port, from which harbor is accessable outside of the cluster
nodePort: 30002 # required
hostname: harbor.local # required
harborPersistence:
persistentVolumeClaim:
registry:
size: 40Gi # optional, default is 40Gi
storageClass: "rook-cephfs" #optional, default is rook-cephfs
jobservice:
jobLog:
size: 1Gi # optional, default is 1Gi
storageClass: "rook-cephfs" #optional, default is rook-cephfs
database:
size: 1Gi # optional, default is 1Gi
storageClass: "rook-cephfs" #optional, default is rook-cephfs
redis:
size: 1Gi # optional, default is 1Gi
storageClass: "rook-cephfs" #optional, default is rook-cephfs
trivy:
size: 5Gi # optional, default is 5Gi
storageClass: "rook-cephfs" #optional, default is rook-cephfs
advanced: # All values from https://artifacthub.io/packages/helm/harbor/harbor/1.8.1#configuration are overwritable
Step 4 - Install KubeOps-VM
- Install the KubeVirt package using the prepared configuration file you created.
kosi install -p kubevirt-2.2.0_Beta0.tgz -f kubevirt-values.yaml
- Verify the installation by checking the pods in the
kubevirtnamespace.
kubectl get pods -n kubevirt
The installation is complete when the status of all pods show the status “Running”. For example:

ImagePullBackOff error, recreate the image pull secret
the following example, the kubevirt namespace is used. If KubeVirt is deployed in a different namespace, replace the value passed to the -n parameter.
kubectl -n kubevirt create secret docker-registry kubeops-vm --docker-server=127.0.0.1:30002 --docker-username=admin --docker-password=<admin password - see harborpass value in kubeopsctl.yaml>
Step 5 - Pull and Install KubeVirt Manager Package
- Pull the KubeVirt Manager package.
kosi pull --hub kubeops kubeops/kubevirt-manager:2.2.0_Beta0 -o kubevirt-manager-2.2.0_Beta0.tgz -r master-ip:30002/kubeops -t 127.0.0.1:30002/kubeops
- Install the KubeVirt Manager package.
kosi install -p kubevirt-manager-2.2.0_Beta0.tgz -f kubevirt-values.yaml
Next Steps
After the installation is complete, you can start creating and deploying a custom virtual machine. For more information, see How to create and deploy a Custom Virtual Machine using KubeOps.