crun-vm/docs/3-kubernetes.md

154 lines
3.5 KiB
Markdown

# 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
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Directory listing for /</title>
</head>
<body>
[...]
```
### 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