Replacing rc.local in systemd linux systems
Содержание:
Автозапуска скриптов и сервисов с помощью rc.local
Для запуска различных скриптов при загрузке Linux чаще всего используется rc.local.
Но помимо скриптов, через rc.local так же можно и запускать сервисы, даже те, которые запускаются через systemd. Не могу ответить на вопрос, для чего использовать в таком случае rc.local, если есть systemd, но пару примеров я приведу.
Начнем с того, что файл /etc/rc.local должен быть исполняемым:
Rc.local должен быть добавлен в автозагрузку systemd:
И на примере того же nginx, мы можем добавить в rc.local команду запуска веб-сервера:
Но я редко использую rc.local для запуска сервисов. Чаще rc.local используется, когда нужно запустить скрипт, либо выполнить разово какую-то команду.
К примеру, я создал скрипт /root/test.sh который выполняет некоторые действия, и хочу запустить его сразу после запуска системы. Добавляем в файл rc.local строку:
Начиная с CentOS 7, разработчики указывают на то, что rc.local устаревший демон и осуществлять автозапуск скриптов или сервисов через него, это прошлый век. Но пока он работает, я пользуюсь им, так как он очень прост в эксплуатации.
Cron @reboot
If the above method does not work for you, or you just want some simple commands to be executed on system boot, then you can also use the @reboot feature in cron to automatically execute command on system boot. For example, I want my shadowsocks client to auto start, so I open the root user’s cron file:
sudo crontab -e
And put the following line at the end of it.
@reboot /usr/bin/sslocal -c /etc/shadowsocks.json -d start
Save and close the file.
In some Linux distributions such as archlinux, the cron daemon is not enabled by default. So you have to manually enable it. To enable it on archlinux, enter the following command in the terminal.
sudo systemctl enable cronie
Shadowsocks is a socks5 proxy that can be used to bypass Internet firewalls, If you are interested, click the link below to learn how to setup your own shadowsocks server.
Как работает автозагрузка?
Чтобы понять как работает автозагрузка, сначала нужно вспомнить, что происходит во время процесса загрузки Linux. Как только ядро завершит свою инициализацию и будет готово к дальнейшей работе, оно передаст управление системе инициализации. Система инициализации — это основной процесс, именно он запускает все другие процессы в системе.
Есть процессы, которые система инициализации, например, systemd, запускает по умолчанию, но также вы можете настроить чтобы она запускала нужные вам процессы. Также многими дочерними процессами выполняются файлы скриптов или имеется та или иная возможность запускать необходимые вам программы. Такая возможность есть и у большинства окружений рабочего стола.
Рассмотрим основные уровни автозагрузки которые вы можете использовать:
- Автозагрузка на уровне ядра — вы можете указать любую программу, которая будет запускаться после старта ядра вместо системы инициализации;
- Автозагрузка системы инициализации — запуск основных системных сервисов, дополнительных сервисов, а также ваших скриптов на этапе инициализации системы;
- Автозагрузка rc.local — устаревший метод загрузки скриптов, выполняется перед запуском графического окружения;
- Автозагрузка менеджера входа — вы можете выполнять свои скрипты или команды после запуска менеджера входа, но перед запуском окружения;
- Автозагрузка X сервера — запуск нужных программ или скрпитов сразу после старта X сервера;
- Автозагрузка окружения — большинство окружений поддерживают автозагрузку программ, там даже можно настроить отложенный запуск и другие параметры;
- Автозагрузка bash — самый последний вариант — это автозагрузка на уровне отдельной командной оболочки, вы можете выполнять нужные команды автоматически, как только будет запущен терминал.
Дальше мы рассмотрим более подробно как использовать каждый из пунктов для автозагрузки программ, скриптов или выполнения команд в Linux.
Автозагрузка скриптов в Linux
Раньше было принято размещать все скрипты, которые запускаются по умолчанию в файле /etc/rc.local. Этот файл все еще существует, но это пережиток системы инициализации SysVinit и теперь он сохраняется только для совместимости. Скрипты же нужно загружать только с помощью Systemd.
Для этого достаточно создать простой юнит-файл и добавить его в автозагрузку, как любой другой сервис. Сначала создадим этот файл:
$ sudo vi /lib/systemd/system/runscript.service
Description=My Script Service After=multi-user.target
Type=idle ExecStart=/usr/bin/local/script.sh
WantedBy=multi-user.target
В секции Unit мы даем краткое описание нашему файлу и говорим с помощью опции After, что нужно запускать этот скрипт в многопользовательском режиме (multi-user). Секция Service самая важная, здесь мы указываем тип сервиса — idle, это значит, что нужно просто запустить и забыть, вести наблюдение нет необходимости, а затем в параметре ExecStart указываем полный путь к нашему скрипту.
Осталось выставить правильные права:
$ sudo chmod 644 /lib/systemd/system/runscript.service
Затем обновить конфигурацию и добавить в автозагрузку Linux новый скрипт:
$ sudo systemctl daemon-reload $ sudo systemctl enable myscript.service
После следующей перезагрузки этот скрипт будет запущен автоматически
Обратите внимание, что для каждого скрипта, который вы собираетесь запускать должны быть правильно выставлены права, а именно нужно установить флаг выполнения. Для этого используйте команду chmod:
$ sudo chmod u+x /usr/local/bin/script
В параметрах мы передаем утилите адрес файла скрипта. Исполняемость — это обязательный параметр для всех способов.
Common hints
root passwords
In LXC releases prior to 2.0.8 containers might be created with a random root password, a static password or without a password at all.
From 2.0.8 onward no root passwords are set by default.
If you need to set the password of a container (because you forgot the random one, or want to adjust the default), you can do so with lxc-attach -n <container> passwd.
Caveats
-
containers not running with full device permissions (which is the default, restricted) spew out systemd errors in the container as systemd tries to set all devices as available (or even not-available); these messages can be turned off by setting /etc/systemd/journald.conf to «?MaxLevelStore=6», if that doesn’t work the cgroup also needs to be auto-mounted as «ro» (instead of «mixed») (needs confirmation).
-
lxc-checkconfig Multiple /dev/pts instances: missing? Don’t be alarmed: https://edmondscommerce.github.io/fedora-24-lxc-multiple-/dev/pts-instances-missing/
- defaults.conf has no mechanism to substitute the hostname in to configuration files. That means while networking can have automatically assigned values for hwaddr its impossible to for default.conf to express «containers should be logged to /var/log/lxc-container-$HOSTNAME.log».
-
Use of lxc on Debian hosts in the unified CGroup hierarchy (pure CGroup V2 hierarchy) is explained in CGroupV2.
Управление службами Linux
Теперь, когда вы уже знаете все основы, команды и параметры можно переходить к делу. Со всеми остальными тонкостями разберемся по пути. Сначала давайте посмотрим запущенные службы linux. Нас будут интересовать только программы, а не все эти дополнительные компоненты, поэтому воспользуемся опцией type:
Команда отобразила все службы, которые известны systemd, они сейчас запущены или были запущены. Программа не пересматривает все файлы, поэтому будут показаны только те службы, к которым уже обращались. Состояние loaded — означает, что конфигурационный файл был успешно загружен, следующая колонка active — служба была запущена, а running или exited значит выполняется ли сейчас служба или она успешно завершила свою работу. Листать список можно кнопками вверх/вниз.
Следующая команда позволяет получить список служб linux, в который входят все службы, даже не запущенные, те, которые не запускались, но известны systemd, но это еще не все службы в системе:
Дальше больше. Вы можете отсортировать список служб systemctl по состоянию. Например, только выполняющиеся:
Или те, которые завершились с ошибкой:
Для фильтрации можно брать любой показатель состояния из любой колонки. Другой командой мы можем посмотреть все файлы конфигурации служб на диске. Тут не будем фильтровать по типу, пусть программа покажет все:
Теперь отфильтруем только службы linux:
Здесь вы тоже можете использовать фильтры по состоянию. Теперь вы знаете как посмотреть запущенные службы linux, идем дальше.
Чтобы запустить службу используется команда start, например:
Причем расширение service можно опустить, оно и так подставляется по умолчанию. Если запуск прошел хорошо, программа ничего не выведет.
Остановить службу linux можно командой:
Посмотреть состояние службы позволяет команда status:
Здесь вы можете видеть, состояние running, exited, dead, failed и т д. А также несколько последних строчек вывода программы, которые очень помогут решить проблему с запуском если она возникнет.
CentOS
CentOS 7
Вывести список всех сервисов
# systemctl list-unit-files --type=service
Проверить статус httpd
# systemctl status httpd
Добавить сервис в автозагрузку (аналог chkconfig on)
# systemctl enable httpd
Убрать сервис из автозагрузки
# systemctl disable httpd
Проверить добавлен ли httpd в автозагрузку
# systemctl is-enabled httpd
Проверить какие сервисы не смогли запуститься при старте системы
# systemctl --failed UNIT LOAD ACTIVE SUB DESCRIPTION ip6tables.service loaded failed failed IPv6 firewall with ip6tables LOAD = Reflects whether the unit definition was properly loaded. ACTIVE = The high-level unit activation state, i.e. generalization of SUB. SUB = The low-level unit activation state, values depend on unit type.
Более подробный список доступных команд
Ниже представлены основные команды systemctl:
Команда | Описание |
---|---|
systemctl start name.service | запуск сервиса |
systemctl stop name.service | остановка сервиса |
systemctl restart name.service | перезапуск сервиса |
systemctl try-restart name.service | перезапуск сервиса только, если он запущен |
systemctl reload name.service | перезагрузка конфигурации сервиса |
systemctl status name.service | проверка, запущен ли сервис с детальным выводом состояния сервиса |
systemctl is-active name.service | проверка, запущен ли сервис с простым ответом: active или inactive |
systemctl list-units –type service –all | отображение статуса всех сервисов |
systemctl enable name.service | активирует сервис (позволяет стартовать во время запуска системы) |
systemctl disable name.service | деактивирует сервис |
systemctl reenable name.service | деактивирует сервис и сразу активирует его |
systemctl is–enabled name.service | проверяет, активирован ли сервис |
systemctl list-unit-files –type service | отображает все сервисы и проверяет, какие из них активированы |
systemctl mask name.service | заменяет файл сервиса симлинком на /dev/null, делая юнит недоступным для systemd |
systemctl unmask name.service | возвращает файл сервиса, делая юнит доступным для systemd |
chkconfig
Вывести список всех сервисов
# chkconfig --list acpid 0:off 1:off 2:on 3:on 4:on 5:on 6:off atd 0:off 1:off 2:off 3:on 4:on 5:on 6:off auditd 0:off 1:off 2:on 3:on 4:on 5:on 6:off crond 0:off 1:off 2:on 3:on 4:on 5:on 6:off htcacheclean 0:off 1:off 2:off 3:off 4:off 5:off 6:off httpd 0:off 1:off 2:on 3:on 4:on 5:on 6:off ip6tables 0:off 1:off 2:off 3:off 4:off 5:off 6:off ipset 0:off 1:off 2:on 3:on 4:on 5:on 6:off iptables 0:off 1:off 2:on 3:on 4:on 5:on 6:off memcached 0:off 1:off 2:on 3:on 4:on 5:on 6:off munin-node 0:off 1:off 2:on 3:on 4:on 5:on 6:off mysql 0:off 1:off 2:on 3:on 4:on 5:on 6:off named 0:off 1:off 2:on 3:on 4:on 5:on 6:off netconsole 0:off 1:off 2:off 3:off 4:off 5:off 6:off netfs 0:off 1:off 2:off 3:off 4:off 5:off 6:off network 0:off 1:off 2:on 3:on 4:on 5:on 6:off nginx 0:off 1:off 2:on 3:on 4:on 5:on 6:off ntpd 0:off 1:off 2:on 3:on 4:on 5:on 6:off ntpdate 0:off 1:off 2:off 3:off 4:off 5:off 6:off portreserve 0:off 1:off 2:on 3:on 4:on 5:on 6:off postfix 0:off 1:off 2:on 3:on 4:on 5:on 6:off rdisc 0:off 1:off 2:off 3:off 4:off 5:off 6:off restorecond 0:off 1:off 2:off 3:off 4:off 5:off 6:off rsyslog 0:off 1:off 2:on 3:on 4:on 5:on 6:off saslauthd 0:off 1:off 2:off 3:off 4:off 5:off 6:off sshd 0:off 1:off 2:on 3:on 4:on 5:on 6:off svnserve 0:off 1:off 2:off 3:off 4:off 5:off 6:off sysstat 0:off 1:on 2:on 3:on 4:on 5:on 6:off udev-post 0:off 1:on 2:on 3:on 4:on 5:on 6:off vnstat 0:off 1:off 2:on 3:on 4:on 5:on 6:off xinetd 0:off 1:off 2:off 3:off 4:off 5:off 6:off
Показать информацию по сервису httpd
# chkconfig --list httpd httpd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
Добавить сервис в автозагрузку
# chkconfig httpd on или # chkconfig --level 345 httpd on
Чтобы отключить
# chkconfig httpd off
Local startup
Sysadmins sometimes add commands to the startup sequence that are locally useful. These additions may aim to start or run local processes that are not part of the standard startup. It is possible to add a new service unit to launch each program needed at startup, but the old method provided a single executable file for any and all local startup needs. We, too, can use this single file approach with . The elegance of this solution is that it makes it easy to add more startup commands at a later time, without the need to add more service units to .
Our solution is to create a single service unit and place any needed Linux commands into the executable file. There are two parts to this solution. One is obvious: We need an executable file. And two, we need to create a service unit for that runs the executable.
Create the executable file
This is a trivial exercise for any sysadmin familiar with Bash programming. In fact, we will create a Bash program and place it in the Linux Filesystem Hierarchical Standard (FHS) location for local executable files, . An argument could be made for placing this executable file in another location, but is the one that makes the most sense to me since this location makes it easy for the sysadmin to run the script from the command line if necessary. The directory is always in every user’s , including that of the root user.
Create the file shown here and place it in (be sure to make it executable):
Note: The comments in the included files tell you where they need to be located.
Be sure to test this executable by running it from the command line. The first time you run this shell script, you should see a new file, , with a time and date along with the text, . We create this log file and add lines to it every time the script is run as a simple test to ensure that our script is working.
Run the script a couple more times. Your results should be similar to those here:
That is all we need to do to create the file that may eventually contain our local startup commands. Just add anything that needs to run at startup to this file.
Create the systemd service
The service unit we will now create is a standard service unit file. This simple file is used only to run the script at startup.
Create a new file, , and add the contents shown below:
This file does not need to be executable. This file could also be located in , but as a local file it is better placed in the branch of the directory structure, with a link to it from .
Now, go to and create the symbolic link in the service unit file:
Test the service unit
We should test the final service unit file before rebooting the Linux host for the final test. First, let’s verify that sees the service:
This result tells us that the service is recognized by . Now, let’s start the service. Doing so will run the script but will not configure the new service to run at boot time:
Check the log file’s contents to verify the new line was added.
Final test
Before we reboot, let’s look the command and how we can use it to view the journal entries that relate to . We can also use the command to verify this because keeps a journal of everything it does.
In the following command, the option shows only entries for the unit:
Now, reboot the Linux host and check the log file to ensure that a new line was added: