crun-vm can also be used as a Kubernetes runtime, allowing you to run VMs as regular pods.
Note that there is already a very featureful project, KubeVirt, that enables using Kubernetes to run VMs with great configurability. However, for simple use cases, crun-vm may be a good fit.
Navigation
You can use the util/minikube-start.sh script to set up a local minikube
Kubernetes cluster with crun-vm available as a runtime, and use it to easily try
out the examples below (note that this also points kubectl
at the minikube
cluster):
$ ./minikube-start.sh
Compiling crun-vm v0.2.0 (/home/afaria/crun-vm)
Finished dev [unoptimized + debuginfo] target(s) in 1.70s
😄 [crun-vm-example] minikube v1.32.0 on Fedora 40
[...]
🏄 Done! kubectl is now configured to use "crun-vm-example" cluster and "default" namespace by default
runtimeclass.node.k8s.io/crun-vm created
Once you're done, you can delete the cluster with:
$ minikube -p crun-vm-example delete
To enable crun-vm on a real Kubernetes cluster, follow the instructions in 1. Installing crun-vm.
To run a VM in your cluster, simply create a pod that references the
RuntimeClass
corresponding to crun-vm (here we assume it is named crun-vm
):
apiVersion: v1
kind: Pod
metadata:
name: my-vm
spec:
containers:
- name: my-vm
image: quay.io/crun-vm/example-http-server:latest
ports:
- containerPort: 80
runtimeClassName: crun-vm
All the image formats supported by crun-vm when using Podman or Docker are also supported here. See 2. Running VMs with Podman or Docker to know more.
You can inspect the VM's console output with the standard kubectl logs
command:
$ kubectl logs my-vm
Assuming a VM supports cloud-init or Ignition, you can ssh
into it using
kubectl exec
:
$ kubectl exec my-vm -- --as fedora whoami
fedora
$ kubectl exec -it my-vm -- --as fedora bash
[fedora@my-vm ~]$
The supported crun-vm specific options like --as fedora
are the same as when
using crun-vm with Podman or Docker. See 2. Running VMs with Podman or
Docker to know more.
The VM pod defined above actually exposes an HTTP server on port 80. To talk to it, we must first forward a local port to the VM:
$ kubectl port-forward my-vm 8000:80
Forwarding from 127.0.0.1:8000 -> 80
Forwarding from [::1]:8000 -> 80
With this command running, navigate to localhost:8000
on your browser, or
run the following on a second terminal:
$ curl localhost:8000
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Directory listing for /</title>
</head>
<body>
[...]
Options supported when using crun-vm with Podman or Docker, like --password
,
--cloud-init
, and --ignition
, are also supported here (see 2. Running VMs
with Podman or Docker
for more information).
However, paths given to --cloud-init
and --ignition
are interpreted in the
context of the VM, instead of the host. This means that first-boot configuration
files can be retrieved from mounted volumes. For instance, you could store your
cloud-init configuration in a ConfigMap
:
apiVersion: v1
kind: ConfigMap
metadata:
name: my-cloud-init-config
data:
meta-data: ""
user-data: |
#cloud-config
runcmd:
- echo 'Hello, world!' > /home/fedora/hello-world
And apply it to your VMs like so:
apiVersion: v1
kind: Pod
metadata:
name: my-other-vm
spec:
containers:
- name: my-other-vm
image: quay.io/containerdisks/fedora:40
args:
- --cloud-init=/etc/cloud-init
volumeMounts:
- name: cloud-init-vol
mountPath: /etc/cloud-init
volumes:
- name: cloud-init-vol
configMap:
name: my-cloud-init-config
runtimeClassName: crun-vm