Logically Bound Images
About logically bound images
This feature enables an association of container "app" images to a base bootc system image. Use cases for this include:
- Logging (e.g. journald->remote log forwarder container)
- Monitoring (e.g. Prometheus node_exporter)
- Configuration management agents
- Security agents
These types of things are commonly not updated outside of the host, and there's a secondary important property: We always want them present and available on the host, possibly from very early on in the boot. In contrast with default usage of tools like podman
or docker
, images may be pulled dynamically after the boot starts; requiring functioning networking, etc. For example if the remote registry is unavailable temporarily, the host system may run for a longer period of time without log forwarding or monitoring, which can be very undesirable.
Another simple way to say this is that logically bound images allow you to reference container images with the same confidence you can with ExecStart=
in a systemd unit.
The term "logically bound" was created to contrast with physically bound images. There are some trade-offs between the two approaches. Some benefits of logically bound images are:
- The bootc system image can be updated without re-downloading the app image bits.
- The app images can be updated without modifying the bootc system image, this would be especially useful for development work
Using logically bound images
Each image is defined in a Podman Quadlet .image
or .container
file. An image is selected to be bound by creating a symlink in the /usr/lib/bootc/bound-images.d
directory pointing to a .image
or .container
file.
With these defined, during a bootc upgrade
or bootc switch
the bound images defined in the new bootc image will be automatically pulled into the bootc image storage, and are available to container runtimes such as podman by explicitly configuring them to point to the bootc storage as an "additional image store", via e.g.:
podman --storage-opt=additionalimagestore=/usr/lib/bootc/storage run <image> ...
An example Containerfile
FROM quay.io/myorg/myimage:latest
COPY ./my-app.image /usr/share/containers/systemd/my-app.image
COPY ./another-app.container /usr/share/containers/systemd/another-app.container
RUN ln -s /usr/share/containers/systemd/my-app.image /usr/lib/bootc/bound-images.d/my-app.image && \
ln -s /usr/share/containers/systemd/another-app.container /usr/lib/bootc/bound-images.d/another-app.container
In the .container
definition, you should use:
GlobalArgs=--storage-opt=additionalimagestore=/usr/lib/bootc/storage
Pull secret
Images are fetched using the global bootc pull secret by default (/etc/ostree/auth.json
). It is not yet supported to configure PullSecret
in these image definitions.
Garbage collection
The bootc image store is owned by bootc; images will be garbage collected when they are no longer referenced
by a file in /usr/lib/bootc/bound-images.d
.
Installation
Logically bound images must be present in the default container store (/var/lib/containers
) when invoking
bootc install; the images will be copied into the target system and present
directly at boot, alongside the bootc base image.
Limitations
The only field parsed and honored by bootc currently is the Image
field of a .image
or .container
file.
Other pull-relevant flags such as PullSecret=
for example are not supported (see above).
Another example unsupported flag is Arch
(the default host architecture is always used).
There is no mechanism to inject arbitrary arguments to the podman pull
(or equivalent)
invocation used by bootc. However, many properties used for container registry interaction
can be configured via containers-registries.conf
and apply to all commands operating on that image.
It is not currently supported in general to launch "rootless" containers from system-owned
image stores in general, whether from /var/lib/containers
or the /usr/lib/bootc/storage
.
There is no integration between bootc and "rootless" storage today, and none is planned.
Instead, it's recommended to ensure that your "system" or "rootful" containers drop
privileges. More in e.g. https://github.com/containers/podman/discussions/13728.
Distro/OS installer support
At the current time, logically bound images are not supported by Anaconda.
Comparison with default podman systemd units
In the comparison below, the term "floating" will be used for non-logically bound images. These images are often fetched by e.g. podman-systemd and may be upgraded, added or removed independently of the host upgrade lifecycle.
Lifecycle
- Floating image: The images are downloaded by the machine the first time it starts (requiring networking typically). Tools such as
podman auto-update
can be used to upgrade them independently of the host. - Logically bound image: The images are referenced by the bootable container and are ensured to be available when the (bootc based) server starts. The image is always upgraded via
bootc upgrade
and appears read-only to other processes (e.g.podman
).
Upgrades, rollbacks and garbage collection
- Floating image: Managed by the user (
podman auto-update
,podman image prune
). This can be triggered at anytime independent of the host upgrades or rollbacks, and host upgrades/rollbacks do not affect the set of images. - Logically bound image: Managed exclusively by
bootc
during upgrades. The logically bound images corresponding to rollback deployments will also be retained.bootc
performs garbage collection of unused images.
"rootless" container image
- Floating image: Supported.
- Logically bound image: Not supported (
bootc
cannot be invoked as non-root). Instead, it's recommended to just drop most privileges for launched logically bound containers.