Ubuntu Server 18.04 – Managing system processes

How to build a Docker Compose YAML files

System processes, also known as daemons, are programs that run in the background on your server and are typically started automatically when it boots. We don’t usually manage these services directly as they run in the background to perform their duty, with or without needing our input. For example, if our server is a DHCP server and runs the isc-dhcp-server process, this process will run in the background, listening for DHCP requests and providing new IP assignments to them as they come in. Most of the time, when we install an application that runs as a service, Ubuntu will configure it to start when we boot our server, so we don’t have to start it ourselves. Assuming the service doesn’t run into an issue, it will happily continue performing its job forever until we tell it to stop. In Linux, services are managed by its init system, also referred to as PID 1 since the init system of a Linux system always receives that PID.

In the past several years, the way in which processes are managed in Ubuntu Server has changed considerably. Ubuntu has switched to systemd for its init system, which was previously Upstart until a few years ago. Ubuntu 16.04 was the first LTS release of Ubuntu with systemd, and this is also the case in Ubuntu 18.04. Even though Ubuntu 18.04 uses systemd, and that is the preferred init system going forward, Ubuntu 14.04 is still supported at the time of writing, and it’s very possible that you may have a mix of both as the older systems age out. For that reason, I’ll go over both init systems in this section.

First, let’s take a look at the way in which you manage services in modern Ubuntu releases with systemd. With systemd, services are known as units, though, for all intents and purposes, the terms mean the same thing. The systemd suite features the systemctl command, which allows you to start, stop, and view the status of units on your server. To help illustrate this, I’ll use OpenSSH as an example, though you’ll use the same command if you’re managing other services, as all you would need to do is change the unit name.

The systemctl command, with no options or parameters, assumes the list-units option, which dumps a list of units to your shell. This can be a bit messy, though, so if you already know the name of a unit you’d like to search for, you can pipe the output into grep and search for a string. This is handy in a situation where you may not know the exact name of the unit, but you know part of it:

systemctl |grep ssh 

If you want to check a service, the best way is to actually use the status keyword, which will show you some very useful information regarding the unit. This information includes whether or not the unit is running, if it’s enabled (meaning it’s configured to start at boot time), as well as the most recent log entries for the unit:

systemctl status ssh 
Checking the status of a unit with systemctl

In my screenshot, you can see that I used sudo in order to run the systemctl status ssh command, but I didn’t have to. You can actually check the status of most units without needing root access, but you may not see all the information available. Some units do not show the recent log entries without sudo. The ssh unit shows the same output either way, though.

Another thing you may notice in the screenshot is that the name of the ssh unit is actually ssh.service, but you don’t need to include the .service part of the name, since that is implied by default. Sometimes, while viewing the status of a process with systemctl, the output may be condensed to save space on the screen. To avoid this and see the full log entries, add the -l option:

systemctl status -l ssh 

Another thing to pay attention to is the vendor preset of the unit. As I’ve mentioned before, most packages in Ubuntu that include a service will enable it automatically, but other distributions which feature systemd may not. In the case of the ssh example, you can see that the vendor preset is set to enabled. This means that once you install the openssh-server package, the ssh.service unit will automatically be enabled. You can confirm this by checking the Active line (where the example output says active (running)), which tells us that the unit is running. The Loaded line clarifies that the unit is enabled, so we know that the next time we start the server, ssh will be loaded automatically. A unit automatically becoming enabled and starting automatically may vary in packages that are configured differently, so make sure you check this output whenever you install a new application.

Starting and stopping a unit is just as easy; all you have to do is change the keyword you use with systemctl to start or stop in order to have the desired effect:

sudo systemctl stop ssh 
sudo systemctl start ssh 

There are additional keywords, such as restart (which takes care of the previous two command examples at the same time), and some units even feature reload, which allows you to activate new configuration settings without needing to bring down the entire application. An example of why this is useful is with Apache, which serves web pages to local or external users. If you stop Apache, all users will be disconnected from the website you’re serving. If you add a new site, you can use reload rather than restart, which will activate any new configuration you may have added without disturbing the existing connections. Not all units feature a reload option, so you should check the documentation of the application that provides the unit to be sure.

If a unit is not currently enabled, you can enable it with the enable keyword:

sudo systemctl enable ssh 

It’s just as easy to disable a unit as well:

sudo systemctl disable ssh 

The systemd suite includes other commands as well, such as journalctl. The reason I refer to systemd as a suite (and not just as an init system) is because it handles more than just starting and stopping processes, with more features being added every year. The journalctl command allows us to view log files, but I’ll wait until Chapter 16, Troubleshooting Ubuntu Servers, which is where I’ll give you an introduction on how that works. For the purposes of this chapter, however, if you understand how to start, stop, enable, disable, and check the status of a unit, you’re good to go for now.

If you have a server with an older version of Ubuntu Server installed, commands from the systemd suite will not work, as systemd is still relatively new. Older versions of Ubuntu use Upstart, which we will take a look at now. If you don’t manage any older Ubuntu installations, feel free to skip the rest of this section.

Managing running services with Upstart is done with the service command. To check the status of a process with Upstart, we can do the following:

service ssh status 

In my case, I get the following output:

ssh start/running, process 907 

As you can see, we don’t get as much output as we do with systemctl on systemd systems, but it at least tells us that the process is running and provides us with its PID. Stopping the process and starting it again gives us similar (limited) output:

sudo service ssh stop 
ssh stop/waiting 
sudo service ssh start 
ssh start/running, process 1304 

While the Upstart method of managing services may not give us as verbose information as systemd, it’s fairly straightforward. We can start, stop, restart, reload, and check the status of a service of a given name. For the purposes of managing processes, that’s pretty much it when it comes to Upstart.

If you’re curious, Upstart stores the configuration for its services in the /etc/init/ directory, with each service having its own file with a .config extension. Feel free to open one of these files to see how Upstart services are configured.

Some services are started using init scripts stored in /etc/init.d, rather than with Upstart or systemd commands. The /etc/init.d directory is used primarily with another init system, sysvinit, which is very old now by today’s standards. However, some distributions that are still supported feature this even older init system, such as Debian 7 and Gentoo to name but two. In the early days, Ubuntu used sysvinit as well, before eventually replacing it with Upstart, so some of these init scripts remain, while some applications that have yet to be updated for newer init systems still use them. In most cases, Upstart and systemd can still manage these processes, but will call their init scripts in /etc/init.d if there is no built-in Upstart or systemd service file. Even if there is, you are still able to utilize this older method even on newer systems, but there’s no telling how long this compatibility layer will remain. At the time of writing, though, the legacy init scripts are still well supported.

The older methods of starting, stopping, restarting, reloading, and checking the status of services with the older sysvinit style is performed with the following commands respectively (again, using ssh as an example):

/etc/init.d/ssh start 
/etc/init.d/ssh stop 
/etc/init.d/ssh restart 
/etc/init.d/ssh reload 
/etc/init.d/ssh status 

At this point, with multiple init systems, it may be confusing as to which methods you should be using. But it breaks down simply. If you’re using a version of Ubuntu that’s 16.04 or newer, go with the systemd examples, since that is the new init system in use nowadays. If your server is using an Ubuntu version older than 16.04, use the upstart commands. In either case, if the normal commands don’t work for a particular service, try the older sysvinit commands. 99.9% of the time, though, the init system that your version of Ubuntu Server ships with will work since just about any application worth using has been ported over.

The systemd init system actually has additional features that its predecessors didn’t have. For example, you can enable a service to start as a particular user, rather than system-wide. To do so, the application has to support being started as a user, which would allow you to enable it with a command similar to the following:

sudo systemctl enable myservice@myuser 

In the hypothetical example I just provided, I’m enabling a unit called myservice for user myuser. A real-life example of why enabling a service to run as a user is useful is syncthing. Although an in-depth walk-through of syncthing is beyond the scope of this tutorial, it’s a great example since it supports being enabled system-wide as well as per user. This is a great thing, since syncthing is a file synchronization application, and each user on a system will have different files to sync, so each user can have his or her own configuration that won’t affect other users. As usual, check the documentation that comes with the application you want to install to see what it supports as far as how to enable it.

Comments are closed.