183 lines
4.9 KiB
Markdown
183 lines
4.9 KiB
Markdown
# 4. Running VMs in **Kubernetes**
|
|
|
|
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.
|
|
|
|
<details open>
|
|
<summary><b>Navigation</b></summary>
|
|
|
|
1. [Installing crun-vm](1-installing.md)
|
|
2. [Running VMs with **Podman** or **Docker**](2-podman-docker.md)
|
|
3. [Running VMs as **systemd** services](3-systemd.md)
|
|
4. **Running VMs in **Kubernetes****
|
|
- [**Setting up**](#setting-up)
|
|
- [**Creating VMs**](#creating-vms)
|
|
- [**Interacting with VMs**](#interacting-with-vms)
|
|
- [Exec'ing into VMs](#execing-into-vms)
|
|
- [Port forwarding](#port-forwarding)
|
|
- [**First-boot configuration**](#first-boot-configuration)
|
|
5. [**crun-vm(1)** man page](5-crun-vm.1.ronn)
|
|
|
|
</details>
|
|
|
|
## Setting up
|
|
|
|
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):
|
|
|
|
```console
|
|
$ ./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:
|
|
|
|
```console
|
|
$ minikube -p crun-vm-example delete
|
|
```
|
|
|
|
To enable crun-vm on a real Kubernetes cluster, follow the instructions in [1.
|
|
Installing crun-vm].
|
|
|
|
## Creating VMs
|
|
|
|
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`):
|
|
|
|
```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
|
|
```
|
|
|
|
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**](2-podman-docker.md#booting-vms) to know more.
|
|
|
|
You can inspect the VM's console output with the standard [`kubectl logs`]
|
|
command:
|
|
|
|
```console
|
|
$ kubectl logs my-vm
|
|
```
|
|
|
|
## Interacting with VMs
|
|
|
|
### Exec'ing into VMs
|
|
|
|
Assuming a VM supports cloud-init or Ignition, you can `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 ~]$
|
|
```
|
|
|
|
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**](2-podman-docker.md#execing-into-vms) to know more.
|
|
|
|
### Port forwarding
|
|
|
|
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:
|
|
|
|
```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>
|
|
[...]
|
|
```
|
|
|
|
## First-boot configuration
|
|
|
|
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**](2-podman-docker.md#configuring-vms-on-first-boot)
|
|
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`:
|
|
|
|
```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 apply 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
|
|
```
|
|
|
|
[`kubectl logs`]: https://kubernetes.io/docs/reference/kubectl/
|
|
[`localhost:8000`]: http://localhost:8000/
|
|
[1. Installing crun-vm]: 1-installing.md
|
|
[Kubernetes]: https://kubernetes.io/
|
|
[KubeVirt]: https://kubevirt.io/
|
|
[minikube]: https://minikube.sigs.k8s.io/
|
|
[util/minikube-start.sh]: ../util/minikube-start.sh
|