KubeVirt Unleashed: Your Ultimate Guide to Running VMs in Kubernetes
Tags: kubernetes, kubevirt, virtualmachine
Published: 2023-10-05 03:49:25

You might be wondering why the buzz about KubeVirt. But first, let's get our basics straight. Kubernetes is an open-source platform for automating container operations. Think of it like a brain for your system that sorts out the heavy lifting behind the scenes. Virtual Machines (VMs), on the other hand, are like mini computers emulated by software, allowing you to run multiple operating systems on one physical server.

So, why KubeVirt? It's simple. KubeVirt extends Kubernetes' awesomeness to include VMs. That means you can manage both containers and VMs using the same set of tools. Imagine having your cake and eating it too—that's KubeVirt for you.

[Setup and Prerequisites](#1-setup-and-prerequisites)
[Basics of KubeVirt](#2-basics-of-kubevirt)
[Deploying Your First VM](#3-deploying-your-first-vm)
[Managing VMs](#4-managing-vms)
[Networking](#5-networking)
[Storage](#6-storage)
[Troubleshooting](#7-troubleshooting)
[Advanced Topics](#8-advanced-topics)
[Conclusion](#9-conclusion)


## 1. Setup and Prerequisites
Alright, let's roll up our sleeves and get started. Before we dive into the fun stuff, we need to make sure your system is prepped and ready to go. I'll walk through installing Kubernetes and KubeVirt, so you're all set for the adventure ahead.
### What you need before you start

#### Hardware Requirements

- 
A computer with enough RAM and CPU (mention specifics if necessary).
- 
Storage space (again, be specific if you can).

#### Software Requirements

- 
Operating system (Linux, macOS, Windows).

- 
Any required software packages or dependencies.

- 
A working Kubernetes cluster or a way to set one up.

#### Skills and Knowledge

- 
Basic understanding of Kubernetes.
- 
Familiarity with command line tools.

- 
Some knowledge of virtual machines could be handy.

### Installing Kubernetes
#### Choose an Installation Method

- 
Minikube for local testing.

- 
Managed Kubernetes for cloud setups (like AWS EKS, Google GKE, etc.).

- 
Kubespray or Kubeadm for more advanced, custom installs.

### Step-by-Step Installation

#### Install Pre-requisites: 
- 
List any software dependencies needed before installing Kubernetes. 

```
sudo apt-get update
sudo apt-get install -y some-package
```


#### Download and Install: 

- 
Provide the commands or links for downloading and installing.
- 
Download and install using Minikube.
```
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
```
#### Configuration: 
- 
Guide them through any initial setup or config files they need to tweak.

#### Start the Cluster: 
- 
Get the cluster up and running.

```
minikube start
```

#### Verify Installation: 
- 
Check that everything's installed correctly.
```
kubectl get nodes
```

### Install KubeVirt
#### Pre-check
- 
Verify that Kubernetes is up and running with `kubectl get nodes`.

#### Add KubeVirt CustomResource (CR)

- 
Install Minikube or use an existing Kubernetes cluster.

- 
Download the KubeVirt CustomResource (CR) file for the version you're installing.
```
export KV_VERSION=$(curl -s https://api.github.com/repos/kubevirt/kubevirt/releases/latest | jq -r .tag_name)
```
#### Install KubeVirt Operator

- Use kubectl to deploy the KubeVirt Operator.

```
kubectl create -f https://github.com/kubevirt/kubevirt/releases/download/${KV_VERSION}/kubevirt-operator.yaml
```
#### Deploy CustomResource (CR)
- Apply the KubeVirt CustomResource (CR)
```
kubectl create -f https://github.com/kubevirt/kubevirt/releases/download/${KV_VERSION}/kubevirt-cr.yaml
```
#### Verify Installation
Use `kubectl get pods -n kubevirt` to confirm the KubeVirt components are running.
```
kubectl get pods -n kubevirt
```
#### Optional: Install virtctl
- 
`virtctl` is a command-line utility to manage KubeVirt VMs. You can download it from the KubeVirt GitHub releases page.


## 2. Basics of KubeVirt
KubeVirt is basically an extension for Kubernetes that lets you do this without breaking a sweat. Before we dive into the how-tos, let's cover some KubeVirt basics to get everyone up to speed.

### KubeVirt architecture
This is the blueprint that makes it possible for KubeVirt to play nice with Kubernetes and let you manage VMs like a pro.

#### Components Overview
- 
After listing components, you can add a YAML code block that shows a simple KubeVirt CustomResource.
```
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: myvm
```

#### How They Work Together
- 
Explain how these components interact with each other and with Kubernetes.

#### Talk About the API
- 
Introduce KubeVirt's API and how it extends Kubernetes' API.

#### Resource Management
- 
How to specify resource limits in a KubeVirt manifest:
```
spec:
  domain:
    resources:
      requests:
        memory: "64M"
        cpu: "1"
```

### How KubeVirt fits into Kubernetes

#### Compatibility
- 
Code block that shows how to deploy a VM using kubectl, highlighting KubeVirt's compatibility.

```
kubectl create -f my-vm.yaml
```

#### Extensibility
- 
Mention how KubeVirt extends Kubernetes to add VM management capabilities.

#### Use Cases
- 
When discussing a use case, include relevant code snippets. For example, if you're talking about scaling VMs, show how to do it.
```
kubectl scale vm myvm --replicas=3
```

#### Community and Ecosystem
- 
Highlight the community around KubeVirt and any additional tools or extensions that make it even more useful.

## 3. Deploying Your First VM

#### Make Sure KubeVirt is Installed
- 
First off, you'll want to make sure KubeVirt is actually installed in your Kubernetes cluster. Run this command to check:
```
kubectl get crd | grep kubevirt.io
```
- 
If you see some output, you're good to go. If not, go back and install KubeVirt.



#### YAML files: What you need
You need a YAML file to define your VM. This is basically a text file where you spell out what resources you want. You save it with a `.yaml` extension. In the steps above, that was the `my-first-vm.yaml file`. Inside it, you define the VM's properties like CPU, memory, and disk.

#### Create a YAML File for Your VM
Next, you need a YAML file to define what the VM should look like. Create a file called `my-first-vm.yaml` and add the following content:

```
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: my-first-vm
spec:
  running: false
  template:
    metadata:
      labels:
        kubevirt.io/vm: my-first-vm
    spec:
      domain:
        devices:
          disks:
          - name: containerdisk
            disk:
              bus: virtio
          - name: cloudinitdisk
            disk:
              bus: virtio
        resources:
          requests:
            memory: 1024M
      volumes:
      - name: containerdisk
        containerDisk:
          image: kubevirt/fedora-cloud-container-disk-demo
      - name: cloudinitdisk
        cloudInitNoCloud:
          userData: |
            #cloud-config
            password: fedora
            chpasswd: { expire: False }
```
#### Deploy the VM

- Finally, deploy the VM by running this command:
```
kubectl create -f my-first-vm.yaml
```

- To start it, switch spec.running from false to true:
```
kubectl patch vm my-first-vm --type merge -p '{"spec":{"running":true}}'
```


#### Commands to get the VM up

To actually get the VM running, you use Kubernetes commands. The key ones are:

- 
`kubectl create -f my-first-vm.yaml`: This takes the YAML file and tells Kubernetes to make a VM out of it.

- 
`kubectl patch vm my-first-vm --type merge -p '{"spec":{"running":true}}'`: This starts the VM you just created.

## 4. Managing VMs
### Starting, stopping, and deleting VMs
#### Start a VM
To start your VM, you can patch its 'running' state to true like this:
```
kubectl patch vm my-first-vm --type merge -p '{"spec":{"running":true}}'
```
#### Stop a VM
Stopping a VM is as simple as setting the 'running' state to false:
```
kubectl patch vm my-first-vm --type merge -p '{"spec":{"running":false}}'
```
#### Delete a VM
To completely remove a VM, use the delete command:
```
kubectl delete vm my-first-vm
```
### Scaling and resource allocation

#### Scale a VM
- 
Kubernetes doesn't natively support VM scaling like it does for pods. But you can create multiple VM instances manually.

#### Allocate more CPU and memory
- 
To allocate more resources to a VM, edit the YAML file to increase CPU and memory, and then apply the changes.
Update your `my-first-vm.yaml` to set new resource requests:
```
spec:
  domain:
    resources:
      requests:
        memory: 2048M
        cpu: 2
```
- 
Apply the changes with:
```
kubectl apply -f my-first-vm.yaml
```


#### Limit Resources
- 
Similarly, you can set limits in the YAML file to prevent a VM from consuming too many resources:

```
spec:
  domain:
    resources:
      limits:
        memory: 2048M
        cpu: 2
```
- 
And then apply these changes:

```
kubectl apply -f my-first-vm.yaml
```

That's your crash course on managing VMs in KubeVirt. Starting, stopping, and tweaking resources should now be a walk in the park.

## 5. Networking
Let's talk networking for your VMs. Here's how to set up internal networking and get your VMs talking to the outside world.

### Setting up networking for your VMs

#### Create a Network Interface
- 
In your VM YAML file, you'll want to define a network interface. Here's how:
```
spec:
  domain:
    devices:
      interfaces:
      - name: mynetwork
        bridge: {}
```
- After updating the YAML, apply the changes:

```
kubectl apply -f my-first-vm.yaml
```

#### Link to a Network

- 
Also in the VM YAML, you'll want to link this interface to a Kubernetes network. Add this to the YAML:

```
spec:
  networks:
  - name: mynetwork
    pod: {}
```
- 
Again, apply the changes:
```
kubectl apply -f my-first-vm.yaml
```

### How to connect VMs to the outside world

#### Use a NodePort

- 
A simple way to expose your VM to the outside world is through a NodePort service.
Create a `nodeport-service.yaml` with the following content:
```
apiVersion: v1
kind: Service
metadata:
  name: my-vm-nodeport
spec:
  type: NodePort
  ports:
  - port: 80
    nodePort: 30080
  selector:
    special: my-vm-label
```
- 
Then, run this command:
```
kubectl apply -f nodeport-service.yaml
```

#### Use an External IP
- 
Another method is to assign an external IP to your VM. This would be done outside of KubeVirt, often directly through your cloud provider's dashboard or APIs.

And that's it! You've got internal networking set up and a couple of ways to connect your VMs to the outside world.

## 6. Storage
Storage is a big deal when you're running VMs. Let's get into how you can attach storage and what options you should consider.
### Attaching storage to VMs
#### Create a Persistent Volume (PV) and Persistent Volume Claim (PVC)
- 
First, let's create a PV and PVC. Make a file called my-pv-pvc.yaml and pop this in:

#### Attach PVC to VM
- 
Open up your VM's YAML file (my-first-vm.yaml) and add a disk and volume for the PVC:

```
spec:
  domain:
    devices:
      disks:
      - name: mypvcdisk
        disk:
          bus: virtio
...
  volumes:
  - name: mypvcdisk
    persistentVolumeClaim:
      claimName: my-pvc
```
Update the VM:
```
kubectl apply -f my-first-vm.yaml
```

### Storage options and best practices

#### Use the Right Storage Class

- Kubernetes supports various types of storage (like SSDs and HDDs). Make sure you specify the type you want in your PVC.

#### Set Access Modes Wisely

- Access modes like ReadWriteOnce and ReadOnlyMany are not just gibberish. They actually tell Kubernetes who can read or write to the volume. Pick what's best for your use case.

#### Size Matters

- Always allocate just as much storage as you need. Overshooting can lead to unused resources, while lowballing can cause issues later on.

#### Backup, Backup, Backup

- Seriously, backup your data. Whether it's snapshots or some other method, make sure you've got copies.

## 7. Troubleshooting
Sometimes things go sideways. Don't sweat it; here's how you can troubleshoot some common issues.

### Check cluster health
#### Check Node Status
- Run the following command to see if all nodes are up and running.
```
kubectl get nodes
```
#### Inspect KubeVirt Components
- Make sure KubeVirt is in good shape:
```
kubectl get pods -n kubevirt
```

### Log Diving

#### Get VM Logs
- When your VM is acting up, check its logs.
```
kubectl logs -f [VM_POD_NAME] -n [NAMESPACE]
```

#### KubeVirt Logs
KubeVirt-specific logs can help too:
```
kubectl logs -f -l 'kubevirt.io= virt-controller' -n kubevirt
```

### Event check
#### Describe the VM
- Use describe to see events related to the VM.
```
kubectl describe vm [VM_NAME]
```
#### Check Cluster Events
- General cluster events can sometimes offer clues.
```
kubectl get events
```

### Common Fixes
#### Restart KubeVirt Components
- Sometimes a good old restart is all you need.
```
kubectl rollout restart deployment virt-controller -n kubevirt
```
#### Delete and Recreate the VM
- As a last resort, you can delete and recreate the VM:
```
kubectl delete vm [VM_NAME]
kubectl apply -f my-first-vm.yaml
```

That should give you a solid start on troubleshooting. Keep those logs and events handy; they're your best friends when things go south

## 8. Advanced Topics
### VM migrations
Migrating VMs allows you to move a virtual machine from one node to another, often for load balancing or hardware maintenance.

#### Prerequisites
- Make sure your cluster supports live migration.
```
kubectl get featuregates -o custom-columns=":metadata.name,:spec.config"
```

#### Initiate Migration
- To move a VM, you first need to create a VirtualMachineInstanceMigration object.
```
kubectl create -f migration.yaml
```
- Here's what migration.yaml might look like:
```
apiVersion: kubevirt.io/v1
kind: VirtualMachineInstanceMigration
metadata:
  name: migration-job
spec:
  vmiName: my-vm
```

#### Monitor Migration
- 
Check the migration status to make sure everything’s going smoothly.
```
kubectl get vmimigration migration-job -o=jsonpath='{.status.phase}'
```

#### Verify Migration
- Confirm the VM is up and running on the new node.
```
kubectl get vmi -o wide
```

#### Rollback (if needed)
- If something’s off, you can cancel the migration:
```
kubectl delete vmimigration migration-job
```

### Integrating with other Kubernetes services
You've got your VMs going, but you can push the envelope by integrating them with other Kubernetes services. Here's how:

#### Service Exposure
- Let's say you've got a web server running on a VM. You can expose it using a Kubernetes Service.
```
kubectl expose vm my-vm --port=80 --target-port=80 --name=my-vm-service
```

#### Ingress Controllers
- If you want to expose your service to the outside world, you can set up an Ingress controller.
```
kubectl apply -f ingress.yaml
```

#### Using ConfigMaps
- You can use ConfigMaps to pass configuration data to your VMs.
```
kubectl create configmap my-config --from-file=config.ini
```

#### Persistent Volumes
- If your VM needs storage that survives reboots, consider using a PersistentVolume.
```
kubectl apply -f my-pv.yaml
```

#### Network Policies
- Control the traffic between your VMs and Pods with Network Policies.
- Example `netpolicy.yaml`:

```
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: my-net-policy
spec:
  podSelector:
    matchLabels:
      role: my-vm
  policyTypes:
  - Ingress
```
Once you get the hang of these integrations, you'll realize how powerful it is to have VMs working alongside your Kubernetes workloads. 

## 9. Conclusion
You've made it through the trenches—from deploying your first VM to scaling it, and even hooking it up with other Kubernetes goodies. The takeaway? KubeVirt isn't just a side gig for Kubernetes; it's a fully integrated player that makes VM management a breeze. Now, you've got the toolkit to level up your Kubernetes game and make those VMs work for you.