Less is more. This is often the perspective behind requests we see that involve the words "light weight." I’ve come to loosely translate this to mean, "install and/or run only the applications I care about with no fluff."
The motivation can be any number of problems around decreasing the installed footprint for security purposes, maximizing system resources, or perceived stability improvements from using less software (less to go wrong).
Each of these points have their merit in any environment, but they are especially relevant in edge computing which is why we have a new means of deploying RHEL that helps tackle these concerns.
Introducing Kiosk Mode for RHEL Edge Deployments
GNOME, the default desktop environment in RHEL, is full-featured, beautifully designed and provides an intuitive user experience. It is widely used among Linux desktop users. At the heart of GNOME is GNOME Shell, the compositor and window manager that provides the panels, launchers, and task management features that make GNOME amazing for many types of users.
GNOME, though, hasn’t been optimized for single application and kiosk use cases until now. Its focus has been more general purpose. A specialized application meant to display information and not interact with the user doesn’t require an environment with panels, launchers, and task management!
Those features just get in the way and unnecessarily use up resources. The kiosk session in RHEL is tailored for those specialized application use cases. Instead of GNOME Shell, the session spawns a barebones graphical UI using Mutter instead.
This compositing window manager consumes less than half the amount of memory GNOME Shell uses (~85MB versus ~180MB in tests). Update: These numbers were pulled from a virtual machine using
llvmpipe and textures were stored in the host's memory. After redoing the test on bare metal, we can see that both numbers were inflated. The actual numbers are 19MB of anonymous pages with the new kiosk session versus 79MB of traditional GNOME Shell. This means we actually have closer to an 75% reduction in the memory footprint, which makes this even more significant.
Since the session only exists to display a single full screen application, it locks down everything else, including common keyboard shortcuts like Ctrl, Alt, Del and TTY access.
There are no unnecessary background services running to support the environment and it’s, by definition, light weight.
Let’s take a look!
To prototype on an existing RHEL 8 system simply update to the latest version and run:
# yum install -y gnome-session-kiosk-session gdm firefox
If you already have a system with GNOME installed, GNOME Display Manager (GDM) is not required as it will already be on the system.
If GDM was freshly installed, though, then you can tell the system to use it by running
# systemctl set-default graphical.target
If you are new to RHEL or don’t have an active subscription, Red Hat offers a no-cost Developer Subscription that is available here.
Once the new session is installed, it will be available on the login screen. To see it, first select the user, then click the gear icon to change the session type.
The session is configured by default to teach users how to run a single app in a simple shell loop. At this point you will probably feel a bit stuck as not much works on the system besides editing the script.
This is intentional and a feature! Also notice that common keyboard shortcuts are disabled like Ctrl+Alt+Del, Ctrl+Alt+Backspace and accessing other TTY shells. There are no other windows or settings to Alt-Tab to. If you want to see the loop in action simply close the window as many times as you like.
Our example demo will run Firefox, which has its own kiosk mode, to display a single page with status information. We’ll use the National Institute of Standards and Technology homepage (time.gov) as an example, but you can see how this method would work to display any type of website or remote application via a browser. This is a common approach for kiosks, digital displays, smart screens, etc.
We’ll need to tweak a total of three configuration files on the system to ensure it boots directly to the kiosk state we need it to be in.
First, we’ll set the system to automatically login using our unprivileged account named core. Ensure the two following entries exist under the [daemon] section of
[daemon] AutomaticLoginEnable=True AutomaticLogin=core
Next, we need to configure our user’s account to use the kiosk mode session. If you’re prototyping on a system this setting is set and persists automatically once the Kiosk session has been picked at the login screen. Since we want to be able to configure a large number of systems hands-free, we’ll need this file to be preconfigured:
/var/lib/AccountsService/users/core [User] Session=com.redhat.Kiosk SystemAccount=false
Finally, we’ll need to tweak /home/core/.local/bin/redhat-kiosk to execute
firefox with the correct options.
#!/bin/sh while true; do firefox -kiosk https://time.gov done
At this point, you’re probably thinking, "Oh cool! I can now manage a ton of these with Smart Management, Ansible, and Insights!" If so, you’re exactly right.
Deploying RHEL to the Edge
Managing this type of deployment couldn’t be any simpler...but what if you wanted to deploy in harsh environments with intermittent connectivity and don’t have local technical resources if there’s a problem? Now we have a different set of problems where using RHEL’s edge image deployment is designed just for this purpose.
So, let’s take the full screen web page example and package that up inside an edge image and use this for our example deployment. All of the config files are attached to this blog post for easy reference. Here are a couple other posts if you need a refresher on getting started with RHEL for Edge or how to set up an update infrastructure for edge systems.
Start by creating a kiosk blueprint. I simply selected the three packages needed for our example in the webUI and created the core user with the password of "edge." In real life please use SSH keys.
While UI’s are beautiful and great for lowering the barrier of entry, the rest of this post will rely on the CLI to keep everything streamlined. Create a file called
kiosk.toml that contains the following content for our example:
name = "kiosk" description = "Example Kiosk" version = "0.0.3" modules =  groups =  [[packages]] name = "gdm" version = "*" [[packages]] name = "gnome-session-kiosk-session" version = "*" [[packages]] name = "firefox" version = "*" [customizations] [[customizations.user]] name = "core" description = "core" password = "$6$NbvV.SUZh/RVLLkl$MRNbPLjDc7u8Ct6wBDuwUGiWvhyIfkLhkw0HAe2NxpiAmmx10pMfmBfDXRBmCNZbQwt6HspL3KtYomP7JUbqP/"
Let’s import that into Image Builder using the
$ composer-cli blueprints push kiosk.toml
Next create the rpm-ostree commit
$ composer-cli compose start-ostree kiosk rhel-edge-container
Download the container image and import it into the local container storage:
$ composer-cli compose image [UUID] $ skopeo copy oci-archive:[UUID]-rhel84-container.tar containers-storage:localhost/kiosk:latest
Now our ostree image is ready to serve and be provisioned. We won’t be exploring all of the provisioning options in this post. Know that we can embed the ostree content in an ISO image for a flash device using the "RHEL Edge Installer" option in Image Builder.
Also, stay tuned for an even more streamlined provisioning path for edge devices later this year. In the meantime, we’ll use the attached very simple kickstart file that includes the three configurations we need for our kiosk example.
lang en_US.UTF-8 keyboard us timezone UTC --isUtc --ntpservers=rhel.pool.ntp.org reboot text zerombr clearpart --all --initlabel autopart --type=plain --fstype=xfs --nohome network --bootproto=dhcp rootpw --iscrypted $6$3OrUXJfD.64WiZl2$4/oBFyFgIyPI6LdLCbE.h99YBrFa..pC3x3WlHNH8mUf4ssZmhlhy17CHc0n3kAvHvWecpqunVOd/4kOGB7Ms. #Use this line if creating an Edge Installer ISO that includes a local ostree commit #ostreesetup --osname=rhel --url=file:///ostree/repo --ref=rhel/8/x86_64/edge --nogpg #Use this to fetch from a remote URL ostreesetup --osname=rhel --url=http://[REPLACE_WITH_YOUR_IP]:8080/repo --ref=rhel/8/x86_64/edge --nogpg %post #Default to graphical boot target systemctl set-default graphical.target #Enable autologin for the user core sed -i '/^\[daemon\]/a AutomaticLoginEnable=True\nAutomaticLogin=core\n' /etc/gdm/custom.conf #Configure user core to use the kiosk session mkdir -p /var/lib/AccountsService/users cat > /var/lib/AccountsService/users/core << 'EOF' [User] Session=com.redhat.Kiosk SystemAccount=false EOF #Configure the kiosk script to run firefox in kiosk mode and display our example URL mkdir -p /home/core/.local/bin/ cat > /home/core/.local/bin/redhat-kiosk << 'EOF' #!/bin/sh while true; do firefox -kiosk https://time.gov done EOF #Ensure the files are owned by our unprivileged user and the script is executable chown -R 1000:1000 /home/core chmod 755 /home/core/.local/bin/redhat-kiosk %end
Run our container and include the kickstart:
podman run --rm -p 8000:80 -v ./kiosk.ks:/var/www/html/kiosk.ks:z kiosk:latest
Now boot your kiosk system with a RHEL 8.4 minimal boot ISO and append the kickstart to the kernel at the installation prompt:
After it deploys, your system will properly display our example URL:
Running a lightweight operating system at the edge provides a lot of value and can be a critical requirement when system resources are scarce.
The new kiosk mode in RHEL is easy to get started with, as well as take to production. Combining it with the edge image technology in RHEL provides an ideal approach for use cases such as smart screens, digital signage, point of sale, or really any kiosk-style appliance that needs to run at the edge.
Getting started with a free developer subscription is simple and available to everyone. Try it today!
Note: Post updated on September 10, 2021 to update memory usage information.