Rootless vs Rootfull
In the Podman world, non-privileged users can run containers on their own: those are the so-called rootless containers. In NethServer 8, we borrow the same word from Podman and use it in the context of modules, together with its opposite, rootfull.
To inspect a rootless module start Bash with the runagent command to
properly initialize the Systemd runtime environment. For instance, to
check if Traefik is running:
runagent -m traefik1
# A Bash prompt from traefik1's session appears
systemctl --user status traefik
# Systemctl prints its output
If you type the above commands in the same line, runagent executes
systemctl without forking an interactive Bash shell:
runagent -m traefik1 systemctl --user status traefik
# Systemctl prints its output from traefik1's session
Let’s see the differences of rootless modules vs rootfull modules.
Unix user
The main difference between rootless and rootfull modules, as suggested by the adjective, is the Unix user running the module processes and its system privileges.
Rootfull: module containers run as root (EUID 0).
Rootless: module containers run as a normal Unix user. The Unix user account is created by the node agent when the module instance is added. It has session lingering enabled: it automatically starts a persistent Systemd user manager instance at system boot.
To check if a module is rootless or not, in Python write:
import os
if os.geteuid() == 0:
print('ROOTFULL')
else:
print('ROOTLESS')
Same thing, in Bash:
if [[ $EUID == 0 ]]; then
echo ROOTFULL
else
echo ROOTLESS
fi
As alternative print the effective user ID with
id -u
To protect against system configuration errors, starting with Core 3.20,
Unix users created for rootless modules are assigned the /sbin/nologin
shell by default. To upgrade existing modules to the new shell policy, run
a command like this:
runagent -l | xargs -l -t -r -- usermod -s /sbin/nologin
Note that the above command may raise harmless errors for cluster,
node and other rootfull module names, which have no corresponding Unix
user.
An interactive shell is not required by NS8 rootless modules. However, if
you need to enable /bin/bash for any reason (for example, to log in as
the module user and transfer files with ssh+rsync), execute:
usermod -s /bin/bash myapp1
If the new default policy is too strict, customize the shell assigned to
new modules by add-module action. Run this command on each cluster node:
runagent -m node python3 -c 'import agent ; agent.set_env("LOGIN_SHELL", "/bin/bash")'
The above command sets the custom shell executable path in the node’s
LOGIN_SHELL agent environment.
Filesystem paths
The two types of modules have a similar filesystem structure. Rootless
modules are installed to /home/<module_id>/.config, whilst rootfull are
installed to /var/lib/nethserver/<module_id>.
Systemd units
Rootless modules also have Systemd user units installed under
~/.config/systemd/user. Recall that some system-wide user units are
installed by the core under /etc/systemd/user. When running the
systemctl command, add the --user flag. Eg.
systemctl --user status traefik
Rootfull modules share the system-wide Systemd directories. Their units
are installed under /etc/systemd/system. As they share the same
directory, unit files must be named as <module_id> or they must use the
<module_id>- prefix to avoid naming clashes with other instances of the
same module. Eg:
cat /etc/systemd/system/samba1.service
systemctl start samba1
Volumes
Rootfull modules share the same Podman volumes namspace. As consequence,
rootfull modules must use the <module_id>- prefix for their volume names
to avoid volume naming clashes. Eg.
samba1-data
samba1-config
Rootless modules can use any volume name because the Podman volume namespace is private for the module.
This command prints out the filesystem path where Podman stores volumes data:
podman system info --format='{{.Store.VolumePath}}'