# 3. Using crun-vm as a Kubernetes runtime It is possible to use crun-vm as a [Kubernetes] runtime, allowing you to run VMs as regular pods. ## Preparation To enable crun-vm on a Kubernetes cluster, follow these steps: 1. Ensure that the cluster is using the [CRI-O] container runtime. Refer to the Kubernetes docs on [container runtimes]. 2. Install crun-vm on all cluster nodes where pods may be scheduled. Refer to the [installation instructions]. 3. Append the following to `/etc/crio/crio.conf` (adjust the `runtime_path` if necessary): ```toml [crio.runtime.runtimes.crun-vm] runtime_path = "/usr/local/bin/crun-vm" ``` 4. Create a `RuntimeClass` that references crun-vm: ```yaml apiVersion: node.k8s.io/v1 kind: RuntimeClass metadata: name: crun-vm handler: crun-vm ``` ## Using the runtime > Under [examples/minikube] you can find a script that sets up a local minikube > Kubernetes cluster with crun-vm available as a runtime. You can use it to > easily try out the examples below. From then on, you can run VM images packaged in container images by creating pods that use this `RuntimeClass`: ```yaml 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 ``` ### Logging The VM's console output is logged: ```console $ kubectl logs my-vm ``` ### SSH'ing into the pod/VM Assuming the VM supports cloud-init or Ignition, you can also SSH into it using `kubectl exec`: ```console $ kubectl exec my-vm -- --as fedora whoami fedora $ kubectl exec -it my-vm -- --as fedora bash [fedora@my-vm ~]$ ``` ### Port forwarding The pod/VM defined above actually exposes an HTTP server on port 80. To talk to it, we must first forward a local port to the pod/VM: ```console $ 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: ```console $ curl localhost:8000 Directory listing for / [...] ``` ### cloud-init and Ignition When using crun-vm as a Kubernetes runtime, paths given to `--cloud-init` and `--ignition` are interpreted in the context of the container/VM, instead of the host. This means that config files can be retrieved from mounted volumes. For instance, you could store your cloud-init config in a `ConfigMap`: ```yaml 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 pass it to your VMs like so: ```yaml 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 ``` [container runtimes]: https://kubernetes.io/docs/setup/production-environment/container-runtimes/#cri-o [CRI-O]: https://cri-o.io/ [examples/minikube]: /examples/minikube [installation instructions]: 1-installing.md [Kubernetes]: https://kubernetes.io/ [`localhost:8000`]: http://localhost:8000/ [SSH'ing into the VM]: 2-podman-docker.md#sshing-into-the-vm