📜 ⬆️ ⬇️

Systemd in five minutes

Our company administers CentOS-based web servers. Quite often, our clients use python, ruby ​​or java web applications. For autorun of such applications there are ready-made templates for writing startup scripts. But progress does not stand still, the second release of CentOS 7 has already been released, and following the old tradition of “not putting dot-zero releases on production”, we are starting to offer CentOS 7.1 (1503) based servers to clients.

In CentOS7, as well as in its parent RHEL7, systemd is the system and services manager for Linux, compatible with SysV and LSB initialization scripts. systemd provides aggressive parallelization and much more.

image
')
A huge monster with a lot of features, flexible settings and megabytes of documentation ...

But what to do if the task is to quickly, quickly, just yesterday, to auto-start a certain service?
Let's squeeze the minimum required set of information from the documentation for creating simple start-stop scripts.

Systemd starts the services described in its configuration.
The configuration consists of a set of files, which are called units in a fashionable way.

All these units are laid out in three directories:

/ usr / lib / systemd / system / - units from installed RPM packages - all sorts of nginx, apache, mysql, etc.
/ run / systemd / system / - units created in runtime - also probably the right thing
/ etc / systemd / system / - units created by the system administrator - and here we will put our unit.

A unit is a text file with a format similar to Microsoft Windows .ini files.

[Section name in square brackets]
variable_name = value


To create a simple unit, you need to describe three sections: [Unit], [Service], [Install]

In the Unit section we describe what kind of unit it is:
Variable names are enough to say:

Description of the unit:
Description = MyUnit

The following is a block of variables that affect the order of loading services:

Run a unit after any service or group of services (for example, network.target):
After = syslog.target
After = network.target
After = nginx.service
After = mysql.service

To start the service, you need a running mysql service:
Requires = mysql.service

To start the service, the started service redis is desirable:
Wants = redis.service

As a result, the variable Wants is obtained purely descriptive.
If the service is in Requires, but not in After, then our service will be launched in parallel with the required service, and not after successfully loading the required service

In the Service section, we indicate which commands and under which user the service should be started:

Type of service:
Type = simple
(default): systemd assumes that the service will start immediately. The process should not be branched. Do not use this type if other services depend on the order in which the service starts.

Type = forking
systemd assumes that the service is started once and the process forks with the completion of the parent process. This type is used to run classic daemons.

You should also define PIDFile = so that systemd can monitor the main process:
PIDFile = / work / www / myunit / shared / tmp / pids / service.pid

The working directory, it is made current before running startup commands:
WorkingDirectory = / work / www / myunit / current

User and group under which the service should be started:
User = myunit
Group = myunit


Environment variables:
Environment = RACK_ENV = production

The ban on killing the service due to lack of memory and the triggering of the OOM mechanism:
-1000 complete ban (this is what sshd has), -100 lower probability.
OOMScoreAdjust = -100

Commands for start / stop and reload service

ExecStart = / usr / local / bin / bundle exec service -C /work/www/myunit/shared/config/service.rb --daemon
ExecStop = / usr / local / bin / bundle exec service -S /work/www/myunit/shared/tmp/pids/service.state stop
ExecReload = / usr / local / bin / bundle exec service -S /work/www/myunit/shared/tmp/pids/service.state restart

There is a subtlety - systemd insists that the team point to a specific executable file. It is necessary to specify the full path.

Timeout in seconds, how long to wait for the system working out start / stop commands.
TimeoutSec = 300


Ask systemd to automatically restart our service if it suddenly stops working.
Control is conducted by the presence of a process from the PID file
Restart = always


In the [Install] section we describe in what level of launch the service should start.

Startup Level:
WantedBy = multi-user.target

multi-user.target or runlevel3.target corresponds to our usual runlevel = 3 “Multi-user mode without graphics. Users typically log in using multiple consoles or via the network. ”

Here is the simplest startup script, also unit for systemd:
myunit.service

[Unit] Description=MyUnit After=syslog.target After=network.target After=nginx.service After=mysql.service Requires=mysql.service Wants=redis.service [Service] Type=forking PIDFile=/work/www/myunit/shared/tmp/pids/service.pid WorkingDirectory=/work/www/myunit/current User=myunit Group=myunit Environment=RACK_ENV=production OOMScoreAdjust=-1000 ExecStart=/usr/local/bin/bundle exec service -C /work/www/myunit/shared/config/service.rb --daemon ExecStop=/usr/local/bin/bundle exec service -S /work/www/myunit/shared/tmp/pids/service.state stop ExecReload=/usr/local/bin/bundle exec service -S /work/www/myunit/shared/tmp/pids/service.state restart TimeoutSec=300 [Install] WantedBy=multi-user.target 

Put this file in the / etc / systemd / system / directory

We look at its status systemctl status myunit

 myunit.service - MyUnit Loaded: loaded (/etc/systemd/system/myunit.service; disabled) Active: inactive (dead) 

We see that it is disabled - we allow it
systemctl enable myunit
systemctl -l status myunit

If there are no errors in the unit, then the output will be like this:

 myunit.service - MyUnit Loaded: loaded (/etc/systemd/system/myunit.service; enabled) Active: inactive (dead) 


We start service
systemctl start myunit

We look beautiful status:
systemctl -l status myunit

If there are errors, we read the output in status, correct it, do not forget, after the fixes in the unit, overload the systemd daemon

systemctl daemon-reload

Now, after introductory dipping in systemd, you can begin independent swims.
If any questions arise, we will be glad to answer your emails at ask@centos-admin.ru

Source: https://habr.com/ru/post/255845/


All Articles