Introduction To Systemd

  • Post author:
  • Post category:Linux
  • Reading time:9 mins read

I came across systemd while working with Ubuntu and other linux distributions on AWS. Its main aim is to unify service configuration and behaviour across Linux distributions and is used widely in software development. If you go through Kubernetes The Hard Way tutorial, you will find that all of the key services, e.g. Kubernetes api server, control manager, kubelet, etc. are managed using systemd.

Units

The basic object in systemd is Unit. Units can be, for example, services (.service), mount points (.mount), devices (.device) or sockets (.socket). You can see the full list of unit types using the following man command.

man systemd.unit

Custom unit files are typically put inside /etc/systemd/system folder, with the unit definition file named unit_name.service. Along with the unit file, a “drop-in” directory unit_name.service.d/ may exist. All files with the suffix “.conf” from this directory will be parsed after the unit file itself is parsed. This is useful to alter or add configuration settings for a unit, without having to modify unit files. 

A service unit file usually looks like the following:

[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/kubernetes/kubernetes
After=docker.service
Requires=docker.service

[Service]
ExecStart=/usr/local/bin/kubelet \
  --bootstrap-kubeconfig="/var/lib/kubelet/bootstrap-kubeconfig" \
  --config=/var/lib/kubelet/kubelet-config.yaml \
  --image-pull-progress-deadline=2m \
  --kubeconfig=/var/lib/kubelet/kubeconfig \
  --cert-dir=/var/lib/kubelet/pki/ \
  --rotate-certificates=true \
  --network-plugin=cni \
  --register-node=true \
  --v=2
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

The internal structure of unit files are organized with sections. Sections are denoted by a pair of square brackets with the section name enclosed within. Each section extends until the beginning of the subsequent section or until the end of the file. In the example, Unit, Service and Install are sections and inside sections we have key value pairs defining different directives.

For details on directives of different unit types, you can use the following commands to view more details.

man systemd.unit # View [Unit] and [Install] directives
man systemd.service # View [Service] directives

Note that unit dependencies can be defined in the Install section using WantedBy and RequiredBy directives.

Targets

Targets are basically synchronization points that the server can used to bring the server into a specific state. Service and other unit files can be tied to a target and multiple targets can be active at the same time. Target is used for grouping units and as well-known synchronization points during start-up.

systemd targetstarget aliasesDescription
default.target This target is always aliased with a symbolic link to either multi-user.target or graphical.target. systemd always uses the default.target to start the system. The default.target should never be aliased to halt.targetpoweroff.target, or reboot.target.
graphical.targetrunlevel5.targetMulti-user.target with a GUI
 runlevel4.targetUnused. Runlevel 4 was identical to runlevel 3. This target could be created and customized to start local services without changing the default multi-user.target.
multi-user.targetrunlevel3.targetAll services running, but command-line interface (CLI) only
 runlevel2.targetMulti-user, without NFS, but all other non-GUI services running
rescue.targetrunlevel1.targetA basic system, including mounting the filesystems with only the most basic services running and a rescue shell on the main console
emergency.target Single-user mode—no services are running; filesystems are not mounted. This is the most basic level of operation with only an emergency shell running on the main console for the user to interact with the system.
halt.target Halts the system without powering it down
reboot.targetrunlevel6.targetReboot
poweroff.targetrunlevel0.targetHalts the system and turns the power off
Targets in systemd

Managing System Services Using Systemctl

We mainly use systemctl command to manage services on a systemd enabled server.

To view the current status of a service:

systemctl status kubelet.service

To start a service:

sudo systemctl start kubelet.service

To stop a service:

sudo systemctl stop kubelet.service

To restart a service:

sudo systemctl restart kubelet.service

To attempt to reload the service without interrupting normal functionality:

sudo systemctl reload kubelet.service

By default, most systemd unit files are not started automatically at boot. To configure this functionality, you need to enable to unit.

To enable a service:

sudo systemctl enable kubelet.service

To disable a service:

sudo systemctl disable kubelet.service

To view all active systemd units:

systemctl list-units

To include all units loaded (active + inactive):

systemctl list-units --all

View Logs Using Journalctl

systemd component called journald collects and manages journal entries from all parts of the system. This is basically log information from applications and the kernel. We use journalctl to query logs.

To see all log entries, starting at the oldest entry:

journalctl

This will include all logs for all services therefore is not very helpful, so you will need the following commands.

To view log since the current boot:

journalctl -b

To view all logs for a service:

journalctl -u kubelet.service

To view all logs for a service during the current boot:

journalctl -b -u kubelet.service