crun-vm/docs/2-podman-docker.md

332 lines
10 KiB
Markdown

# 2. Running VMs with **Podman** or **Docker**
Here, we outline how to use crun-vm to run VMs using the Podman or Docker
container engines. See [crun-vm(1)] for a full reference and additional details
on crun-vm specific options.
We use `podman` in the example commands below. Unless otherwise noted, the same
commands also with `docker`.
<details open>
<summary><b>Navigation</b></summary>
1. [Installing crun-vm](1-installing.md)
2. **Running VMs with **Podman** or **Docker****
- [**Booting VMs**](#booting-vms)
- [From containerdisks](#from-containerdisks)
- [From VM image files](#from-vm-image-files)
- [From bootable containers](#from-bootable-containers)
- [**Configuring VMs on first boot**](#configuring-vms-on-first-boot)
- [Default user password](#default-user-password)
- [cloud-init](#cloud-init)
- [Ignition](#ignition)
- [**Interacting with VMs**](#interacting-with-vms)
- [Exec'ing into VMs](#execing-into-vms)
- [Port forwarding](#port-forwarding)
- [**Sharing resources with VMs**](#sharing-resources-with-vms)
- [Files](#files)
- [Directories](#directories)
- [Block devices](#block-devices)
3. [Running VMs as **systemd** services](3-systemd.md)
4. [Running VMs in **Kubernetes**](4-kubernetes.md)
5. [**crun-vm(1)** man page](5-crun-vm.1.ronn)
</details>
## Booting VMs
### From containerdisks
A "containerdisk" is a container image that packages a sole VM image file under
`/` or `/disk/`. This is how you would boot a VM from the
quay.io/containerdisks/fedora:40 containerdisk using crun-vm:
```console
$ podman run --runtime crun-vm -it quay.io/containerdisks/fedora:40
Booting `Fedora Linux (6.8.5-301.fc40.x86_64) 40 (Cloud Edition)'
[...]
```
> Several regularly-updated containerdisks may be found at
> https://quay.io/organization/containerdisks. You can also easily build your
> own:
>
> ```dockerfile
> FROM scratch
> COPY my-vm-image.qcow2 /
> ENTRYPOINT ["no-entrypoint"]
> ```
The VM console should take over your terminal. This VM image has no users that
you may log in as using a password, so although you can interact with the VM's
login screen, you will be unable to access a command prompt for now. To abort
the VM, press `ctrl-]`.
You can also detach from the VM without terminating it by pressing `ctrl-p,
ctrl-q`. Afterwards, reattach by running:
```console
$ podman attach --latest
```
This command also works when you start the VM in detached mode using
podman-run's `-d`/`--detach` flag.
It is also possible to omit flags `-i`/`--interactive` and `-t`/`--tty` to
podman-run, in which case you won't be able to interact with the VM but can
still observe its console. Note that pressing `ctrl-]` will have no effect, but
you can always use the following command to terminate the VM:
```container
$ podman stop --latest
```
### From VM image files
> This feature is only supported with Podman.
It is also possible to boot VMs directly from disk image files by using Podman's
`--rootfs` option to point at a directory containing a sole image file. For
instance, these commands download and boot a Fedora 40 VM:
```console
$ mkdir my-vm-image/ && curl -LO --output-dir my-vm-image/ https://download.fedoraproject.org/pub/fedora/linux/releases/40/Cloud/x86_64/images/Fedora-Cloud-Base-Generic.x86_64-40-1.14.qcow2
$ podman run --runtime crun-vm -it --rootfs my-vm-image/
Booting `Fedora Linux (6.8.5-301.fc40.x86_64) 40 (Cloud Edition)'
[...]
```
### From bootable containers
crun-vm can also launch VMs from [bootc bootable container images], which are
containers that package a full operating system:
```console
$ podman run --runtime crun-vm -it quay.io/crun-vm/example-fedora-bootc:40
Converting quay.io/crun-vm/example-fedora-bootc:40 into a VM image...
[...]
Caching VM image as a containerdisk...
[...]
Booting VM...
[...]
```
crun-vm generates a VM image from the bootable container and then boots it. The
generated VM image is packaged as a containerdisk and cached in the host's
container storage, so that subsequent runs will boot faster:
```console
$ podman run --runtime crun-vm -it quay.io/crun-vm/example-fedora-bootc:40
Retrieving cached VM image...
[...]
Booting VM...
[...]
```
## Configuring VMs on first boot
### Default user password
In the examples above, you were able to boot a VM but not to log in. An easy way
to fix this when a VM has [cloud-init] installed is to use the [`--password`]
option, which sets the password for the VM's "default" user (as determined in
the image's cloud-init configuration). For quay.io/containerdisks/fedora:40,
that is the `fedora` user:
```console
$ podman run --runtime crun-vm -it quay.io/containerdisks/fedora:40 --password pass
Booting `Fedora Linux (6.8.5-301.fc40.x86_64) 40 (Cloud Edition)'
[...]
3b0232a04046 login: fedora
Password: pass
[fedora@3b0232a04046 ~]$
```
Like all crun-vm specific options, [`--password`] must be passed in *after* the
image specification.
### cloud-init
You can provide a full [cloud-init] NoCloud configuration to a VM by passing in
the crun-vm specific option [`--cloud-init`] *after* the image specification:
```console
$ ls my-cloud-init-config/
meta-data user-data
$ cat my-cloud-init-config/meta-data # empty
$ cat my-cloud-init-config/user-data
#cloud-config
write_files:
- path: $home/file
content: |
hello
$ podman run --runtime crun-vm -it quay.io/containerdisks/fedora:40 \
--cloud-init $PWD/my-cloud-init-config/ # path must be absolute
```
### Ignition
You can also provide an [Ignition] configuration to a VM using the crun-vm
specific [`--ignition`] option:
```console
$ cat my-ignition-config.ign
{
"ignition": {
"version": "3.0.0"
},
"passwd": {
"users": [
{
"name": "core",
"passwordHash": "$y$j9T$USdd8CBvFNVU1xKwQUnsU/$aE.3arHcRxD0ZT3vkvsSpEsteUj6vC4ZdRHY8eOj1f4"
}
]
}
}
$ podman run --runtime crun-vm -it quay.io/crun-vm/example-fedora-coreos:40 \
--ignition $PWD/my-ignition-config.ign # path must be absolute
```
## Interacting with VMs
### Exec'ing into VMs
Assuming a VM supports cloud-init or Ignition and exposes an SSH server on port
22, you can `ssh` into it as root using podman-exec:
```console
$ podman run --runtime crun-vm --detach quay.io/containerdisks/fedora:40
8068a2c180e0f4bf494f5e0baa37d9f13a9810f76b361c0771b73666e47ec383
$ podman exec --latest whoami
Please login as the user "fedora" rather than the user "root".
```
This particular VM image does not allow logging in as root. To `ssh` into the VM
as a different user, specify its username using the [`--as`] option immediately
before the command (if any). You may need to pass in `--` before this option to
prevent podman-exec from trying to interpret it:
```console
$ podman exec --latest -- --as fedora whoami
fedora
```
If you just want a login shell, pass in an empty string as the command. The
following would be the output if this VM image allowed logging in as root:
```console
$ podman exec -it --latest ""
[root@8068a2c180e0 ~]$
```
You may also log in as a specific user:
```console
$ podman exec -it --latest -- --as fedora
[fedora@8068a2c180e0 ~]$
```
When a VM supports cloud-init, `authorized_keys` is automatically set up to
allow SSH access by podman-exec for users `root` and the default user as set in
the image's cloud-init configuration. With Ignition, this is set up for users
`root` and `core`.
### Port forwarding
You can use podman-run's standard `-p`/`--publish` option to enable TCP and/or
UDP port forwarding:
```console
$ podman run --runtime crun-vm --detach -p 8000:80 quay.io/crun-vm/example-http-server:latest
36c8705482589cfc4336a03d3802e7699f5fb228123d18e693488ac7b80116d1
$ curl localhost:8000
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Directory listing for /</title>
</head>
<body>
[...]
```
## Sharing resources with VMs
### Files
You can bind mount regular files into a VM:
```console
$ podman run --runtime crun-vm -it \
-v ./README.md:/home/fedora/README.md:z \
quay.io/containerdisks/fedora:40
```
Regular files currently appear as block devices in the VM, but this is subject
to change.
### Directories
It is also possible to bind mount directories into a VM:
```console
$ podman run --runtime crun-vm -it \
-v ./util:/home/fedora/util:z \
quay.io/containerdisks/fedora:40
```
If the VM supports cloud-init or Ignition, the volume will automatically be
mounted at the given destination path. Otherwise, you can mount it manually with
the following command, where `<index>` is the 0-based index of the volume
according to the order the `-v`/`--volume` or `--mount` flags where given in:
```console
$ mount -t virtiofs virtiofs-<index> /home/fedora/util
```
### Block devices
If cloud-init or Ignition are supported by a VM, it is possible to pass block
devices through to it and make them appear at a specific path using podman-run's
`--device` flag. For instance, assuming `/dev/ram0` exists on the host and is
accessible by the current user:
```console
$ podman run --runtime crun-vm -it \
--device /dev/ram0:/home/fedora/my-disk \
quay.io/containerdisks/fedora:40
```
You can also use the more powerful, crun-vm specific [`--blockdev`]
`source=<path>,target=<path>,format=<fmt>` option to this effect. This option
also allows you to specify a regular file as the source, and the source may be
in any disk format known to QEMU (*e.g.*, raw, qcow2; when using `--device`, raw
format is assumed):
```console
$ podman run --runtime crun-vm -it \
quay.io/containerdisks/fedora:40 \
--blockdev source=$PWD/my-disk.qcow2,target=/home/fedora/my-disk,format=qcow2 # paths must be absolute
```
[`--as`]: 5-crun-vm.1.ronn#exec-options
[`--blockdev`]: 5-crun-vm.1.ronn#createrun-options
[`--cloud-init`]: 5-crun-vm.1.ronn#createrun-options
[`--ignition`]: 5-crun-vm.1.ronn#createrun-options
[`--password`]: 5-crun-vm.1.ronn#createrun-options
[bootc bootable container images]: https://containers.github.io/bootable/
[cloud-init]: https://cloud-init.io/
[crun-vm(1)]: 5-crun-vm.1.ronn
[domain XML definition]: https://libvirt.org/formatdomain.html
[Ignition]: https://coreos.github.io/ignition/
[KubeVirt `containerDisk`s]: https://kubevirt.io/user-guide/virtual_machines/disks_and_volumes/#containerdisk
[libvirt]: https://libvirt.org/