"Booting" Silverblue/Kinoite using Podman/Docker

Hello

Fedora Silverblue and Kinoite is preparing for an enablement of ostree native container feature. It changes the way that the system is distributed from ostree repo to the OCI images compatible with docker and podman. More details: Tracker for ostree native container conversion · Issue #359 · fedora-silverblue/issue-tracker · GitHub

@siosm prepared simple infrastructure that builds the Silverblue and Kinoite images every day, and you can rebase into it and try it today: https://github.com/fedora-silverblue/issue-tracker/issues/334#issuecomment-1315737913

I played with these images for a while and found that the system can beeasily “booted” inside Docker/Podman with the whole userspace (kernel is shared with the host of course). It has a much better performance than a virtual machine. It can be done by using one command:

[jakub@localhost ~]$ sudo podman run --privileged -v /var/:/var/ -v /etc/passwd:/etc/passwd -v /etc/shadow:/etc/shadow -v /etc/group:/etc/group -it quay.io/fedora-ostree-desktops/kinoite:37 /usr/lib/systemd/systemd rhgb --system --runlevel 3
[sudo] hasło użytkownika jakub: 
systemd 251.8-586.fc37 running in system mode (+PAM +AUDIT +SELINUX -APPARMOR +IMA +SMACK +SECCOMP -GCRYPT +GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN -IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK +PCRE2 +PWQUALITY +P11KIT +QRENCODE +TPM2 +BZIP2 +LZ4 +XZ +ZLIB +ZSTD +BPF_FRAMEWORK +XKBCOMMON +UTMP +SYSVINIT default-hierarchy=unified)
Detected virtualization podman.
Detected architecture x86-64.

Welcome to Fedora Linux 37 (Kinoite)!

Initializing machine ID from container UUID.
bpf-lsm: BPF LSM hook not enabled in the kernel, BPF LSM not supported
Queued start job for default target multi-user.target.
Unnecessary job was removed for dev-sda3.device - /dev/sda3.
[  OK  ] Created slice system-modprobe.slice - Slice /system/modprobe.
[  OK  ] Created slice user.slice - User and Session Slice.
[  OK  ] Started systemd-ask-password-wall.path - Forward Password Requests to Wall Directory Watch.
[  OK  ] Set up automount proc-sys-fs-binfmt_misc.automount - Arbitrary Executable File Formats File System Automount Point.
[  OK  ] Reached target integritysetup.target - Local Integrity Protected Volumes.
[  OK  ] Reached target slices.target - Slice Units.
[  OK  ] Reached target swap.target - Swaps.
[  OK  ] Reached target veritysetup.target - Local Verity Protected Volumes.
[  OK  ] Listening on dm-event.socket - Device-mapper event daemon FIFOs.
[  OK  ] Listening on lvm2-lvmpolld.socket - LVM2 poll daemon socket.
[  OK  ] Listening on systemd-coredump.socket - Process Core Dump Socket.
[  OK  ] Listening on systemd-initctl.socket - initctl Compatibility Named Pipe.
[  OK  ] Listening on systemd-journald-audit.socket - Journal Audit Socket.
[  OK  ] Listening on systemd-journald-dev-log.socket - Journal Socket (/dev/log).
[  OK  ] Listening on systemd-journald.socket - Journal Socket.
[  OK  ] Listening on systemd-udevd-control.socket - udev Control Socket.
[  OK  ] Listening on systemd-udevd-kernel.socket - udev Kernel Socket.
         Mounting dev-hugepages.mount - Huge Pages File System...
         Mounting sys-kernel-debug.mount - Kernel Debug File System...
         Mounting sys-kernel-tracing.mount - Kernel Trace File System...
         Starting kmod-static-nodes.service - Create List of Static Device Nodes...
         Starting lvm2-monitor.service - Monitoring of LVM2 mirrors, snapshots etc. using dmeventd or progress polling...
         Starting modprobe@configfs.service - Load Kernel Module configfs...
         Starting modprobe@drm.service - Load Kernel Module drm...
         Starting modprobe@fuse.service - Load Kernel Module fuse...
         Starting systemd-journald.service - Journal Service...
         Starting systemd-modules-load.service - Load Kernel Modules...
         Starting systemd-remount-fs.service - Remount Root and Kernel File Systems...
         Starting systemd-udev-trigger.service - Coldplug All udev Devices...
[  OK  ] Mounted dev-hugepages.mount - Huge Pages File System.
[  OK  ] Mounted sys-kernel-debug.mount - Kernel Debug File System.
[  OK  ] Mounted sys-kernel-tracing.mount - Kernel Trace File System.
[  OK  ] Finished kmod-static-nodes.service - Create List of Static Device Nodes.
modprobe@configfs.service: Deactivated successfully.
[  OK  ] Finished modprobe@configfs.service - Load Kernel Module configfs.
modprobe@drm.service: Deactivated successfully.
[  OK  ] Finished modprobe@drm.service - Load Kernel Module drm.
modprobe@fuse.service: Deactivated successfully.
[  OK  ] Finished modprobe@fuse.service - Load Kernel Module fuse.
[  OK  ] Finished systemd-modules-load.service - Load Kernel Modules.
[  OK  ] Finished systemd-remount-fs.service - Remount Root and Kernel File Systems.
         Mounting sys-fs-fuse-connections.mount - FUSE Control File System...
         Mounting sys-kernel-config.mount - Kernel Configuration File System...
         Starting systemd-hwdb-update.service - Rebuild Hardware Database...
         Starting systemd-sysctl.service - Apply Kernel Variables...
         Starting systemd-sysusers.service - Create System Users...
[  OK  ] Mounted sys-fs-fuse-connections.mount - FUSE Control File System.
[  OK  ] Mounted sys-kernel-config.mount - Kernel Configuration File System.
[  OK  ] Finished systemd-sysctl.service - Apply Kernel Variables.
[  OK  ] Finished systemd-sysusers.service - Create System Users.
         Starting systemd-tmpfiles-setup-dev.service - Create Static Device Nodes in /dev...
[  OK  ] Finished systemd-tmpfiles-setup-dev.service - Create Static Device Nodes in /dev.
[  OK  ] Started systemd-journald.service - Journal Service.
         Starting systemd-journal-flush.service - Flush Journal to Persistent Storage...
[  OK  ] Finished systemd-journal-flush.service - Flush Journal to Persistent Storage.
[  OK  ] Finished systemd-udev-trigger.service - Coldplug All udev Devices.
         Starting systemd-udev-settle.service - Wait for udev To Complete Device Initialization...
[  OK  ] Finished systemd-hwdb-update.service - Rebuild Hardware Database.
         Starting systemd-udevd.service - Rule-based Manager for Device Events and Files...
[  OK  ] Started systemd-udevd.service - Rule-based Manager for Device Events and Files.
[  OK  ] Started systemd-ask-password-console.path - Dispatch Password Requests to Console Directory Watch.
[  OK  ] Finished lvm2-monitor.service - Monitoring of LVM2 mirrors, snapshots etc. using dmeventd or progress polling.
[  OK  ] Finished systemd-udev-settle.service - Wait for udev To Complete Device Initialization.
         Starting dmraid-activation.service - Activation of DM RAID sets...
[  OK  ] Finished dmraid-activation.service - Activation of DM RAID sets.
[  OK  ] Created slice system-systemd\x2dbacklight.slice - Slice /system/systemd-backlight.
[  OK  ] Reached target cryptsetup.target - Local Encrypted Volumes.
[  OK  ] Reached target local-fs-pre.target - Preparation for Local File Systems.
[  OK  ] Reached target local-fs.target - Local File Systems.
[  OK  ] Listening on systemd-rfkill.socket - Load/Save RF Kill Switch Status /dev/rfkill Watch.
         Starting ldconfig.service - Rebuild Dynamic Linker Cache...
         Starting plymouth-read-write.service - Tell Plymouth To Write Out Runtime Data...
         Starting selinux-autorelabel-mark.service - Mark the need to relabel after reboot...
         Starting systemd-backlight@backlight:intel_backlight.service - Load/Save Screen Backlight Brightness of backlight:intel_backlight...
         Starting systemd-boot-update.service - Automatic Boot Loader Update...
         Starting systemd-tmpfiles-setup.service - Create Volatile Files and Directories...
[  OK  ] Finished plymouth-read-write.service - Tell Plymouth To Write Out Runtime Data.
[  OK  ] Finished selinux-autorelabel-mark.service - Mark the need to relabel after reboot.
[  OK  ] Finished systemd-backlight@backlight:intel_backlight.service - Load/Save Screen Backlight Brightness of backlight:intel_backlight.
[  OK  ] Finished systemd-boot-update.service - Automatic Boot Loader Update.
         Starting systemd-rfkill.service - Load/Save RF Kill Switch Status...
[  OK  ] Started systemd-rfkill.service - Load/Save RF Kill Switch Status.
[  OK  ] Finished systemd-tmpfiles-setup.service - Create Volatile Files and Directories.
         Starting auditd.service - Security Auditing Service...
         Starting systemd-journal-catalog-update.service - Rebuild Journal Catalog...
         Starting systemd-resolved.service - Network Name Resolution...
[  OK  ] Finished systemd-journal-catalog-update.service - Rebuild Journal Catalog.
[FAILED] Failed to start auditd.service - Security Auditing Service.
See 'systemctl status auditd.service' for details.
         Starting systemd-update-utmp.service - Record System Boot/Shutdown in UTMP...
[  OK  ] Finished ldconfig.service - Rebuild Dynamic Linker Cache.
         Starting systemd-update-done.service - Update is Completed...
[  OK  ] Finished systemd-update-utmp.service - Record System Boot/Shutdown in UTMP.
[  OK  ] Finished systemd-update-done.service - Update is Completed.
[  OK  ] Started systemd-resolved.service - Network Name Resolution.
[  OK  ] Reached target nss-lookup.target - Host and Network Name Lookups.
[  OK  ] Reached target sysinit.target - System Initialization.
[  OK  ] Started cups.path - CUPS Scheduler.
[  OK  ] Started ostree-finalize-staged.path - OSTree Monitor Staged Deployment.
[  OK  ] Started logrotate.timer - Daily rotation of log files.
[  OK  ] Started plocate-updatedb.timer - Update the plocate database daily.
[  OK  ] Started raid-check.timer - Weekly RAID setup health check.
[  OK  ] Started rpm-ostree-countme.timer - Weekly rpm-ostree Count Me timer.
[  OK  ] Started systemd-tmpfiles-clean.timer - Daily Cleanup of Temporary Directories.
[  OK  ] Started unbound-anchor.timer - daily update of the root trust anchor for DNSSEC.
[  OK  ] Reached target paths.target - Path Units.
[  OK  ] Reached target timers.target - Timer Units.
[  OK  ] Listening on avahi-daemon.socket - Avahi mDNS/DNS-SD Stack Activation Socket.
[  OK  ] Listening on cups.socket - CUPS Scheduler.
[  OK  ] Listening on dbus.socket - D-Bus System Message Bus Socket.
[  OK  ] Listening on pcscd.socket - PC/SC Smart Card Daemon Activation Socket.
[  OK  ] Listening on sssd-kcm.socket - SSSD Kerberos Cache Manager responder socket.
[  OK  ] Reached target sockets.target - Socket Units.
[  OK  ] Reached target basic.target - Basic System.
         Starting alsa-restore.service - Save/Restore Sound Card State...
         Starting avahi-daemon.service - Avahi mDNS/DNS-SD Stack...
         Starting bluetooth.service - Bluetooth service...
         Starting chronyd.service - NTP client/server...
         Starting dracut-shutdown.service - Restore /run/initramfs on shutdown...
         Starting iio-sensor-proxy.service - IIO Sensor Proxy service...
[  OK  ] Started mcelog.service - Machine Check Exception Logging Daemon.
         Starting polkit.service - Authorization Manager...
[  OK  ] Reached target nss-user-lookup.target - User and Group Name Lookups.
         Starting systemd-logind.service - User Login Management...
[  OK  ] Finished alsa-restore.service - Save/Restore Sound Card State.
[  OK  ] Finished dracut-shutdown.service - Restore /run/initramfs on shutdown.
[  OK  ] Reached target sound.target - Sound Card.
         Starting dbus-broker.service - D-Bus System Message Bus...
[  OK  ] Stopped auditd.service - Security Auditing Service.
         Starting auditd.service - Security Auditing Service...
[  OK  ] Started dbus-broker.service - D-Bus System Message Bus.
[FAILED] Failed to start auditd.service - Security Auditing Service.
See 'systemctl status auditd.service' for details.
[  OK  ] Started chronyd.service - NTP client/server.
[  OK  ] Started bluetooth.service - Bluetooth service.
[  OK  ] Reached target bluetooth.target - Bluetooth Support.
[  OK  ] Started avahi-daemon.service - Avahi mDNS/DNS-SD Stack.
[  OK  ] Started polkit.service - Authorization Manager.
         Starting firewalld.service - firewalld - dynamic firewall daemon...
[  OK  ] Started iio-sensor-proxy.service - IIO Sensor Proxy service.
[  OK  ] Started systemd-logind.service - User Login Management.
[  OK  ] Stopped auditd.service - Security Auditing Service.
         Starting auditd.service - Security Auditing Service...
[FAILED] Failed to start auditd.service - Security Auditing Service.
See 'systemctl status auditd.service' for details.
[  OK  ] Started firewalld.service - firewalld - dynamic firewall daemon.
[  OK  ] Reached target network-pre.target - Preparation for Network.
         Starting NetworkManager.service - Network Manager...
[  OK  ] Started NetworkManager.service - Network Manager.
[  OK  ] Reached target network.target - Network.
         Starting cups.service - CUPS Scheduler...
         Starting systemd-user-sessions.service - Permit User Sessions...
[  OK  ] Stopped auditd.service - Security Auditing Service.
         Starting auditd.service - Security Auditing Service...
         Starting systemd-hostnamed.service - Hostname Service...
[  OK  ] Finished systemd-user-sessions.service - Permit User Sessions.
         Starting plymouth-quit-wait.service - Hold until boot process finishes up...
         Starting plymouth-quit.service - Terminate Plymouth Boot Screen...
[  OK  ] Started cups.service - CUPS Scheduler.
[  OK  ] Finished plymouth-quit-wait.service - Hold until boot process finishes up.
[  OK  ] Started console-getty.service - Console Getty.
[  OK  ] Reached target getty.target - Login Prompts.
[  OK  ] Finished plymouth-quit.service - Terminate Plymouth Boot Screen.
[  OK  ] Reached target multi-user.target - Multi-User System.
         Starting systemd-update-utmp-runlevel.service - Record Runlevel Change in UTMP...
[FAILED] Failed to start auditd.service - Security Auditing Service.
See 'systemctl status auditd.service' for details.
[  OK  ] Finished systemd-update-utmp-runlevel.service - Record Runlevel Change in UTMP.
[  OK  ] Started systemd-hostnamed.service - Hostname Service.

Fedora Linux 37 (Kinoite)
Kernel 6.0.8-300.fc37.x86_64 on an x86_64 (console)

d2aaeac29e76 login: jakub
Password: 
Last login: Mon Nov 28 21:40:38 on console
[jakub@d2aaeac29e76 ~]$ 

To quit from the “booted” system just use sudo poweroff.

Bind mount of /var is optional, it is just for sharing the home directory and flatpak apps with host, so you can ommit it if you don’t want to share these things. But mounting /etc/passwd, etc/group and etc/shadow is necessary because in the container there is only a root account that is disabled, so you will not able to log in without these bind mounts. When the bind mounts are used, you can login with the same user and password as the host system

--runlevel 3 is also not necessary, but if you ommit it, the system will try to initialize the whole graphic stack.

“Booting” with the whole graphic stack

I successfully “booted” the Fedora Kinoite inside Docker with a fully working graphical Plasma Desktop session and was able to e.g watch Youtube inside it or launch installed flatpak apps. That’s how I did it:

  • I was on Fedora Kinoite (didn’t work on Silverblue) and tried to boot Fedora Kinoite (was not able to boot Silverblue because I cannot debug why gdm didn’t start)
  • The host system was on Wayland (it didn’t work with X.org)
  • I used docker instead of Podman (It didn’t worked with podman), To install docker run rpm-ostree install moby-engine and reboot, after reboot run sudo systemctl start docker and sudo systemctl enable docker

The command to run is:

sudo docker run --privileged -v /var/:/var/ -v /etc/passwd:/etc/passwd -v /etc/shadow:/etc/shadow -v /etc/group:/etc/group -it quay.io/fedora-ostree-desktops/kinoite:37 /usr/lib/systemd/systemd rhgb --system

The system will start “booting” and sddm will take over the screen, and you will get a login screen like usual. Log in into the account like usual and Plasma will start on full screen. The internet connection is working, and the sound is working. Flatpak apps from the host are also working.

To exit from the system, just select “Shut down” in the Plasma session and the host system will appear on the screen.

The image is huge, so it will take a while to download for the first time. Happy playing with this.

7 Likes

Interesting.

I tried with Fedora 37 Workstation as host.

I can load both Silverblue and Kinioite to level 3 with both Podman and Docker .

With Docker,

sudo docker run --privileged -v /var/:/var/ -v /etc/passwd:/etc/passwd -v /etc/shadow:/etc/shadow -v /etc/group:/etc/group -it quay.io/fedora-ostree-desktops/kinoite:37 /usr/lib/systemd/systemd rhgb --system

SDDM reached, but Plasma cannot start after login

sudo docker run --privileged -v /var/:/var/ -v /etc/passwd:/etc/passwd -v /etc/shadow:/etc/shadow -v /etc/group:/etc/group -it quay.io/fedora-ostree-desktops/silverblue:37 /usr/lib/systemd/systemd rhgb --system

Graphical cannot start with Silverblue.

Thank you for sharing.

You probably trying with Fedora Workstation Gnome version. I described that I was also unable to get graphic work when booted on Silverblue (Gnome). Probably if you use Workstation Plasma as host, it should work

1 Like

On top of Workstation’s default Gnome environment, I added Plasma. Reboot. Login to Plasma.

And using the Docker command for Kinoite.

I reach the Plasma logon screen - but cannot reach Plasma desktop.

Ok, the next problem is that Workstatnion does not have /home inside /var, so your home directory is not shared into the container. So, plasma does not have nesessary configs to start. I think, in workstation you should type -v /home:/var/home instead of /var:/var and then it should work.

1 Like

Tested with a fresh install of F37 KDE spin, and it works.

(with the original /var:/var, logon with normal user do not work - it return to logon screen immediately, but with root user is OK)

Thank you very much, it is really interesting.

Whoah, cool trick!

Indeed, we should make it easy to test and run our bootable userspace as a container. This is actually a whole aspect of this that we haven’t focused on much, but does make sense in some cases. It’s not clear to me yet we should think of this as really a production use case, but for testing it’s very powerful.

There’s definitely overlap between this and installing packages in the “application” container as I’d call it (e.g. quay.io/fedora/fedora). But on the other hand, how we generate bootable containers today via rpm-ostree compose image is significantly more intelligent, and has the powerful advantage that one can seamlessly move to booting them for real (using the included kernel).

It’s funny how history repeats itself in some ways. A long time ago, I wanted to test the latest GNOME on Debian, and did this: Colin Walters' Debian homepage

Containerization has come a long way since chroot, but…in some ways it’s basically the same thing too.