The Raspberry Pi operating system (Raspberry Pi OS) is one of the most popular Linux distributions for DIY electronics projects. As a Debian-flavored OS, Raspberry Pi OS relies heavily on background system services running to enable functionality. For instance the sshd daemon allows remote logins over the network, while samba facilitates file transfers to Windows devices.

However, uncontrolled services can consume resources even when not actively used. A developer may occasionally need to stop or disable services on a Raspberry Pi to free up memory, storage, CPU cycles and networking bandwidth for other applications. But blindly terminating critical background processes can destabilize Raspbian, harming performance.

This developer‘s guide provides best practices for safely stopping, starting and managing system services on Raspberry Pi OS. Expert techniques covered include:

  • Quantifying resource usage of common services for optimizing what to disable
  • Contrasting systemd vs legacy init systems
  • Following principles of service hardening for improved security
  • Diagnosing crashes through journald logging and metrics monitoring
  • Configuring auto-restart policies through custom unit files
  • Adapting to modern containerized deployment with Docker and Kubernetes

Resource Usage Statistics of Key Raspberry Pi Services

When looking to free up constrained resources on a Raspberry Pi system, a good first step is quantifying which services consume the most memory, CPU time, storage and network bandwidth.

Table 1 shows usage statistics for several common daemons running on Raspberry Pi OS:

Service Memory % CPU Storage Network
sshd 2.8 MB 0.3% 1.2 MB 12 KB/s
samba 15.2 MB 1.1% 58 MB 31 KB/s
mariadb 183 MB 3.2% 1.1 GB 16 KB/s
nginx 21 MB 0.5% 52 MB 102 KB/s
chromium 121 MB 28.3% 209 MB 36 KB/s

From this data, a few interesting observations stand out:

  • The MariaDB SQL server consumes significant memory, storage and CPU resources – stopping this when not needed can reclaim capacity
  • Samba likewise uses a considerable 15MB memory and storage with little CPU usage
  • Chromium web browser guzzles 28% CPU in addition to over 100MB memory
  • sshd is quite lightweight for enabling remote logins

Ideaally production Raspberry Pi servers would run from SSD storage rather than MicroSD cards to accommodate MariaDB and Samba space demands.

But in general, explicitly stopping Chromium when not in active browser use can significantly speed up a Pi by freeing up CPU cycles. Disabling mariadb and samba daemons where feasible can also help other applications access DRAM and storage bandwidth.

Now let‘s explore developer-relevant background on what services actually represent in Linux, contrasting modern systemd initialization to legacy SysV, before covering security hardening and diagnostics.

Linux Services: systemd vs SysV init

The term "service" in Linux refers to programs that start at boot time and then run continuously in the background waiting to handle requests. Services listen on ports, respond to hardware events, execute scheduled tasks, and perform other duties.

For example the Secure Shell sshd daemon listens on TCP port 22 for users logging in remotely via SSH to issue terminal commands. The Apache httpd web server listens on port 80 to respond to HTTP requests from web browsers.

Two competing standards exist for initializing boot services on Linux distributions like Raspberry Pi OS:

1. systemd – Modern service manager used in Debian, Ubuntu, Fedora and RHEL. Raspberry Pi OS uses systemd as its init system for boot process and service control.

2. SysV init – Legacy initialization system originally from Unix System V. Still used in some niche distros. Implements /etc/inittab for boot configuration and scripts in /etc/init.d/ to launch individual daemons.

Back around 2010, systemd began replacing SysV init for better performance and efficiency. However some Linux purists still prefer the simplicity of SysV.

As a developer working on Raspberry Pi OS though, you will exclusively interface with systemd for managing services. Let‘s briefly contrast systemd vs SysV init relevant to stopping and disabling services:

systemd features:

  • Parallel service activation for faster boot
  • Socket and D-Bus activation of daemons
  • Custom executables run on startup and shutdown
  • Config defined in .service unit files under /lib/systemd/
  • Use systemctl [stop | restart | status] to control services
  • journald logging mechanism

SysV init features:

  • Sequential daemon startup based on run levels
  • Shell scripts under /etc/init.d/ launch each service
  • /etc/inittab configures boot process order
  • service [stop | restart | status] to control services
  • Logging to .log files under /var/log

For practical purposes, all you need to know is that systemd is the modern standard – so this article focuses on Linux service management using systemctl.

Principles of Service Hardening for Security

Services are common attack vectors for hackers to compromise Linux systems. The simple best practice security tip is reduce your expose attack surface by only running necessary services, with each daemon configured as safely as possible.

Here is a checklist of hardening principles for securing services on Linux:

  • Only install services that are absolutely needed for functionality
  • Set services to manually start instead of automatic if feasible
  • Follow least privilege principles for file system rights
  • Properly configure each daemon to use TLS encryption if connections are public
  • Utilize security modules like SELinux and AppArmor to enforce protections
  • Create firewall policies with IPtables to block unwanted service traffic
  • Continuously patch known vulnerabilities in services

Adhering to these rules requires some extra work initially setting up a hardened Raspberry Pi system. But doing so drastically reduces risks that a single exposed service vulnerability undermines overall security.

Specific steps like enabling TLS encryption for transports are outside this article‘s scope. But generally be vigilant about restricting access to each running service based on defined operational requirements – with all unnecessary capabilities locked down.

Journald Logging for Diagnosing Service Issues

A key systemd feature we have only glimpsed so far is consolidated logging – replacing SysV init‘s scattered log files. The journald daemon collects log message from all system services, exposed via the journalctl command.

Viewing a service‘s journald output is tremendously useful for diagnosing runtime issues and crashes. Simply invoke:

sudo journalctl -u service-name

For example, to debug why nginx recently stopped serving a website:

sudo journalctl -u nginx 

Would display its logs, perhaps revealing:

nginx[7543]: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx[7543]: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx[7543]: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx[7543]: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)  
nginx[7543]: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx[7543]: [emerg] still could not bind()

Ah ha! Another process is already listening on TCP port 80, causing nginx‘s startup to fail.

Checking journalctl should be an early troubleshooting step before resorting to restarting services. This can reveal the root cause, be it permission issues, missing resources or socket conflicts.

Configuring Restart Policies and Custom Unit Files

Thus far we have mainly covered the basics of stopping and disabling unnecessary services to optimize resource usage on a Raspberry Pi appliance.

However in a production context, resilient and self-recovering services are crucial. Crashing daemons like sshd can cripple remote access, while a downed MariaDB server loses access to live databases.

systemd unit files located under /lib/systemd/system define how each Linux service runs. Unit files configure aspects like:

  • Permissions and directories for execution
  • Execution command line with arguments
  • Environment variables
  • Restart trigger conditions
  • Logging behavior
  • Dependencies on other services

Unit files use a .service extension by convention and are loaded automatically based on filename. For example the ssh daemon‘s unit file is ssh.service.

Restart Policies

Hardcoded unit files ship with default restart policies – but as a system developer you can customize these. For example overriding sshd‘s policy of "no automatic restart" after crashes:

[Service]
Restart=always

Will make sshd daemon automatically relaunch if it halts or exits unexpectedly.

Other valid policy values are on-failure to restart only on nonzero exit codes – good for scripts:

Restart=on-failure

And on-watchdog to restart if main process hangs/stucks, which rarely should occur:

Restart=on-watchdog

So configure restart behaviors wisely based on how critical continuity of a service is.

Custom Unit Files

Beyond config tweaks, developers can define entirely new unit files to launch custom executables as long-running services.

For example, you can make a simple Python daemon service with:

[Unit]    
Description=My Cool Daemon

[Service]
ExecStart=/usr/bin/python3 /opt/mydaemon.py
Restart=always

[Install]
WantedBy=multi-user.target 

Now your mydaemon.py process will initialize during system boot and restart automatically if interrupted.

So through restart policy tuning and custom services, developers wield extensive control over resilient service behaviors.

Containerization of Services: Docker and Kubernetes Direction

So far this guide has covered best practices for service lifecycle management using traditional system administration tools like systemctl. However an ongoing paradigm shift in cloud native application development deserves a mention – transitioning services into Linux containers orchestrated by Kubernetes.

Tools like Docker revolutionized application deployment in Linux environments by allowing complex multi-process services to be neatly encapsulated into OCI standard containers. This brought concepts of immutability, declarative infrastructure, and environment consistency to the Linux world.

Containers built with Dockerfiles could reliably deploy on diverse hosts while avoiding dependency conflicts that plagued vanilla services.

This containerization trend then evolved into sophisticated container orchestrators like Kubernetes to manage full application stacks. Kubernetes empowers declarative deployment of stateless microservices and stateful distributed data services designed as 12 Factor Apps.

So learning to configure Kubernetes YAML manifests supersedes manually starting individual daemon services like nginx or sshd. Kubernetes handles replicating containers across clusters, mounting storage volumes, configuring networking, service discovery, secrets management and gracefully rolling out new versions.

Of course, bare metal single board computers like Raspberry Pis are limited in directly adopting container orchestration standards designed for large production clusters. But virtualization can help bridge this gap:

  • Docker now runs well on 64-bit Pi OS images

  • Open source k3s slimmed down Kubernetes specifically targets IoT and Edge hardware

So while manually systemctl stopping services suffices for simple appliances, treat it as a stopgap before the future of Kubernetes-orchestrated containers and serverless functions.

Architecting an advanced Distributed PI Cluster to host microservices introduces fascinating new challenges around declarative infrastructure, eventually replacing daemon configuration.

Conclusion

This system developer‘s guide provided both breadth and depth around properly managing background services in Linux – with context specific to optimizing Raspberry Pi OS performance.

Key takeaways covered included:

  • Quantifying resource consumption of common daemons to identify heavyweights to disable
  • Contrast between modern systemd and legacy SysV init systems
  • Following principles of service hardening and attack surface reduction
  • Logging and metrics monitoring with journald for diagnosing issues
  • Configuring restart policies and authoring custom unit files
  • Understanding the future direction of Kubernetes container orchestration

Learning to efficiently handle services via systemctl and supplemental commands empowers developers to reliably build Linux-based appliances. Combining these sysadmin techniques with actual application coding unlocks the full potential of versatile platforms like Raspberry Pi for deploying innovative projects!

Similar Posts