Systemd is the "init" system for RHEL 8 (and 7 for that matter). It replaces Upstart, the SysV "init" system used in prior releases of RHEL. Systemd is more than just a facility to bring up user space, it is a system manager that offers:
-
service parallelization
-
socket and D-Bus activation
-
on-demand starting of services
-
track services and child processes via cgroups
-
and much more
For these exercises, you will be using the host node1
as user root
.
From host bastion
, ssh to node1
.
ssh node1
Use sudo
to elevate your priviledges.
sudo -i
Verify that you are on the right host for these exercises.
workshop-systemd-checkhost.sh
You are now ready to proceed with these exercises.
Let’s collect some initial data about the boot process
systemd-analyze
Startup finished in 3.783s (kernel) + 6.526s (initrd) + 14.723s (userspace) = 25.033s
multi-user.target reached after 10.540s in userspace
Next let’s inspect further details about all running units, ordered by the time they took to initialize.
systemd-analyze blame
4.205s kdump.service
3.308s firewalld.service
3.108s dnf-makecache.service
2.991s NetworkManager-wait-online.service
2.182s dracut-initqueue.service
1.562s sssd.service
...<output truncated>...
This helps to learn the “cost” of some of the default services. To speed up boot-time, unnecessary services could potentially be removed or disabled.
The fundamental building block that systemd manages is called a "unit". A "unit" can describe different types of objects, but the most common type is a "service".
A "unit file" is the configuration file that describes a unit and tells systemd what dependencies exist and how to start, stop and monitor the object.
"unit files" are stored in 2 different directories. One location is reserved for the default configurations as shipped by Red Hat and the other is for customization by the local administrators.
-
Red Hat unit files: /usr/lib/systemd/system/…
-
Customizations: /etc/systemd/system/…
systemd has a concept similar to SysV init runlevels, called targets. systemd will boot to the “default target” which can be configured using the systemctl set-default command. Some common targets and their equivalent SysV runlevels are:
-
multi-user.target == runlevel 3
-
graphical.target == runlevel 5
Let’s view the current default target.
systemctl get-default
multi-user.target
As mentioned above, systemd has another concept called a service. A service is a type of unit which defines the traditional daemon or process. Now let us look at what services are running on the system:
systemctl -t service
UNIT LOAD ACTIVE SUB DESCRIPTION auditd.service loaded active running Security Auditing Service chronyd.service loaded active running NTP client/server crond.service loaded active running Command Scheduler dbus.service loaded active running D-Bus System Message Bus dracut-shutdown.service loaded active exited Restore /run/initramfs on s firewalld.service loaded active running firewalld - dynamic firewal ...<output truncated>...
Next let’s view all of the services available (ie: everything installed, running or not) on the system. The following command is similar to the older chkconfig --list as it will show both enabled and disabled services:
systemctl list-unit-files -t service
UNIT FILE STATE arp-ethers.service disabled auditd.service enabled [email protected] enabled blk-availability.service disabled [email protected] static chrony-wait.service disabled chronyd.service enabled ...<output truncated>...
The state will be enabled, disabled, static, or masked. Static indicates that the unit file does not contain an "install" section used to enable the unit. In this case, the unit typically performs a one-off action or is used as a dependency of another unit and should not be run by itself.
Now that we have a good idea of what’s installed on our system, let’s get a basic lamp stack up and running. If you prefer not to type all of these commands, there is a workshop script below to save you some time.
Let us install some packages.
yum install -y httpd mariadb-server mariadb
...snip ... Package httpd-2.4.37-16.module+el8.1.0+4134+e6bad0ed.x86_64 is already installed. Package mariadb-server-3:10.3.17-1.module+el8.1.0+3974+90eded84.x86_64 is already installe d. Package mariadb-3:10.3.17-1.module+el8.1.0+3974+90eded84.x86_64 is already installed. Dependencies resolved. Nothing to do. Complete!
Now it’s time to enable the relevant system services.
ℹ️
|
The "enable --now" syntax was introduced in a recent release of RHEL 7 and of course is now availbale in RHEL 8. The option permanently enables AND immediately starts the specified services in a single command. |
systemctl enable --now httpd mariadb
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service → /usr/lib/systemd/system/httpd.service. Created symlink /etc/systemd/system/mysql.service → /usr/lib/systemd/system/mariadb.service. Created symlink /etc/systemd/system/mysqld.service → /usr/lib/systemd/system/mariadb.service. Created symlink /etc/systemd/system/multi-user.target.wants/mariadb.service → /usr/lib/systemd/system/mariadb.service.
Now let’s check the status. You should see two separate sections in the output, one for httpd and one for mariadb.
systemctl status httpd mariadb
● httpd.service - The Apache HTTP Server Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled) Active: active (running) since Wed 2019-05-01 21:37:54 EDT; 12s ago Docs: man:httpd.service(8) Main PID: 5135 (httpd) Status: "Running, listening on: port 80" Tasks: 213 (limit: 24007) Memory: 26.5M CGroup: /system.slice/httpd.service ├─5135 /usr/sbin/httpd -DFOREGROUND ├─5163 /usr/sbin/httpd -DFOREGROUND ...<output truncated>...
Last but not least, you need to enable a firewall port.
firewall-cmd --add-service=http
success
So as promised, here is a workshop script that performs all of the above steps.
workshop-systemd-lamp.sh
systemd controls more than daemons or services. For this lab, we will primarily be working with service units but it’s important to know that systemd is handling the dependencies between other types: sockets, timers, mounts, swap, slices, etc.
Unit files are stored in one of three places:
-
'/usr/lib/systemd/system' - default configs that ship with the RHEL and are updated by regular maintenance
-
'/etc/systemd/system' - custom configs that persist and replace (or augment) default configs
-
'/run/systemd/system' - runtime changes that won’t persist
While the defaults for unit files won’t need to be altered most of the time, there will be circumstances where changing the defaults is quite beneficial. These could include hardware or software watchdog monitoring, tunings, resource management, or many other reasons.
Create a drop-in configuration file to extend the default httpd.service unit
workshop-systemd-httpdconfig.sh
Contents of /etc/systemd/system/httpd.service.d/50-httpd.conf [Service] Restart=always OOMScoreAdjust=-1000
OOMScoreAdjust is used by the Kernel’s Out Of Memory killer and is an integer between -1000 (to disable OOM killing for this process) and 1000 (to make killing of this process under memory pressure very likely).
Notify systemd of the changes.
systemctl daemon-reload
Similar to what you did in the last step, extend the mariadb.service unit with Restart=always.
This time we’ll use systemctl to create the drop-in and notify systemd of the changes.
systemctl edit
allows inserting the content for the drop-in and also handles the systemctl daemon-reload
automatically.
systemctl edit mariadb
[Service]
Restart=always
Save and quit the editor, and view the unit
systemctl cat
is a quick and easy way to view the contents of a unit & and it’s drop-ins.
systemctl cat mariadb
...snip... # Restart crashed server only, on-failure would also restart, for example, when # my.cnf contains unknown option Restart=on-abort RestartSec=5s UMask=007 # Give a reasonable amount of time for the server to start up/shut down TimeoutSec=300 # Place temp files in a secure directory, not /tmp PrivateTmp=true # /etc/systemd/system/mariadb.service.d/override.conf [Service] Restart=always
systemctl status httpd
● httpd.service - The Apache HTTP Server Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled) Drop-In: /etc/systemd/system/httpd.service.d └─50-httpd.conf Active: active (running) since Wed 2019-05-01 21:37:54 EDT; 11min ago Docs: man:httpd.service(8) Main PID: 5135 (httpd) Status: "Running, listening on: port 80" Tasks: 213 (limit: 24007) Memory: 26.5M CGroup: /system.slice/httpd.service ├─5135 /usr/sbin/httpd -DFOREGROUND ├─5163 /usr/sbin/httpd -DFOREGROUND
Notice that systemctl status displays that the unit has been extended with a drop-in file.
systemctl status mariadb
● mariadb.service - MariaDB 10.3 database server Loaded: loaded (/usr/lib/systemd/system/mariadb.service; enabled; vendor preset: disab> Drop-In: /etc/systemd/system/mariadb.service.d └─override.conf Active: active (running) since Thu 2020-04-16 13:10:45 EDT; 9s ago Docs: man:mysqld(8) https://mariadb.com/kb/en/library/systemd/ Process: 28674 ExecStartPost=/usr/libexec/mysql-check-upgrade (code=exited, status=0/SU> Process: 28325 ExecStartPre=/usr/libexec/mysql-prepare-db-dir mariadb.service (code=exi> Process: 28300 ExecStartPre=/usr/libexec/mysql-check-socket (code=exited, status=0/SUCC> Main PID: 28642 (mysqld) Status: "Taking your SQL requests now..." Tasks: 30 (limit: 23999) Memory: 84.5M CGroup: /system.slice/mariadb.service └─28642 /usr/libexec/mysqld --basedir=/usr