Управление сетью с NetworkManager. Знакомство с nmtui

В Red Hat Enterprise Linux 8 для управления сетью по умолчанию используется NetworkManager, это демон позволяет динамически управлять сетью, ее конфигурацией и соединениями. Традиционные файлы конфигураций ifcfg также доступны.
Чтобы настроить сеть через NetworkManager можно использовать следующие инструменты:

  • Текстовый пользовательский интерфейс nmtui (консольный, про него написано ниже).
  • Инструмент командной строки nmcli (консольный).
  • Инструменты графического интерфейса пользователя, GNOME GUI.

Чтобы проверить, что NetworkManager запущен, выполните:

systemctl status NetworkManager

Чтобы настроить сетевой интерфейс без использования NetworkManager:

  • Отредактируйте файлы ifcfg вручную.
  • Используйте команды ip. Их можно использовать для назначения IP-адреса интерфейсу, но при перезагрузке вы потеряете все изменения.

Чтобы настроить параметры сети, когда корневая файловая система не является локальной используйте командную строку ядра.

Работа с nmtui

nmtui – это простой текстовый пользовательский интерфейс (text user interface – TUI) для NetworkManager. nmtui используется в терминале. Он включен в пакет NetworkManager-tui. Если он не установлен, выполните:

yum install NetworkManager-tui

Для запуска nmtui просто наберите команду nmtui. Стартовое меню выглядит так:

Здесь вы можете отредактировать настройки соединения, активировать соединение и задать имя хоста. Для навигации используйте стрелки, Tab и Enter.
Чтобы изменить настройки подключения выберите пункт Edit a connection.

Выделите интерфейс, который необходимо сконфигурировать, нажмите Tab и выберите Edit…. Откроются свойства соединения. Для ручной настройки смените значение IPv4 CONFIGURATION на Manual. Чтобы открыть настройки переведите курсор вправо на Show и нажмите Enter.


Здесь же можно поставить крестик на Automatically connect, чтобы соединение поднималось автоматически при загрузке системы и при потере соединения. После того, как необходимые настройки внесены нажмите OK. Далее для применинения настроек необходимо деактивировать соединение, затем заново его активировать. Для этого вернитесь в главное меню и перейдите в раздел Activate a connection, выберите необходимый интерфейс, переведите курсор на Deactivate и нажмите Enter. Значение изменилось на Activate, снова жмем Enter и соединение поднимается с новыми настройками.

Также можно использовать следующие команды:
Для активации соединения nmtui connect connection-name.
Для редактирования настроек соединения nmtui edit connection-name.
Если не задать имя соединения, то появится меню выбора.

Обратите внимание, что nmtui поддерживает не все типы соединений. В частности, не удастся отрелдактировать VPN, беспроводные сетевые соединения с использованием WPA Enterprise или Ethernet-соединения с использованием 802.1X.

Управление виртуальными машинами KVM

Команды, приведенные ниже могут требовать от вас рутовых прав. Это зависит от того, под каким пользователем у вас работают ВМ. У меня они работают подо мной, поэтому и рутовых прав не нужно. Мануал на русском по первоначальной установке и настройке KVM на CentOS 7 (Red Hat Enterprise Linux 7).. А здесь пример установки Red Hat Enterprise Linux 8.0 Beta под KVM.

  1. Основные команды для управления виртуальными машинами под KVM
  2. Клонирование виртуальной машины
  3. Подключение носителей (флэшек) к виртуальной машине
  4. Изменение параметров виртуальной машины
  5. Удаление виртуальной машины

Основные команды для управления виртуальными машинами под KVM

Просмотр списка виртуальных машин
virsh list --all

Запуск виртуальной машины, где vm_name – имя машины.
virsh start vm_name

Запуск окна для подключения к виртуальной машине (окно для просмотра/управления самой ОС). Если virt-viewer не запускается…
virt-viewer

Показывает использование cpu/памяти для всех запущенных VM
virt-top

Выключение VM (выключение ОС)
virsh shutdown vm_name

Помечает VM для автостарта (например, после перезагрузки хоста)
virsh autostart vm_name

Убирает метку автостарта (теперь VM не запустится сама после ребута хоста)
virsh autostart --disable vm_name

Информация о VM
virsh dominfo vm_name

Информация о разделах диска VM (займет несколько минут)
virt-df vm_name

Клонирование виртуальной машины

  1. Приостановите VM для клонирования.
    virsh suspend vm
  2. Запустите команду virt-clone:
    virt-clone \
     --connect qemu:///system \
     --original vm \
     --name vm-clone \
     --file /vm-images/vm-clone.img

    Эта операция займет несколько минут в зависимости от размера машины.

  3. По завершению, возобновите работу исходной VM:
    virsh resume vm1
  4. Клонированная машина выключена. При необходимости запустите ее:
    virsh start vm1-clone

Подключение носителей (флэшек) к виртуальной машине

Сначала определите имя вашего устройства после его подключения к хосту. В нашем случае это /dev/sdb. Затем выполните:
virsh attach-disk vm_name /dev/sdb vdb --driver qemu --mode shareable
здесь vdb – имя устройства в VM. Т.е. путь к устройству внутри VM – /dev/vdb.
Устройство можно примонтировать более чем к одной виртуальной машине. Но тут нет контроля доступа на запись, так что последствия могут быть неожиданными.
Для отключения устройства от VM выполните:
virsh detach-disk vm_name vdb

Изменение параметров виртуальной машины

Управление оперативной памятью (добавление/удаление)

Вы можете нагорячую изменять память в VM, не превышая размер, заданный при установке (параметр ram). Например, если вы создали VM с 1 ГБ памяти, вы можете динамически уменьшить этот объем не выключая VM.
Если вы хотите получить объем памяти больший, чем указывали при установке VM, то VM придется сначала отключить.

Начнем с первого варианта. Уменьшим объем памяти нагорячую с 1Гб до 512 Мб.

  1. Посмотрим какой максимум памяти на машине, выполнив
    virsh dominfo vm_name | grep memory или
    virsh dominfo vm_name | grep память
    У меня так:
  2. Устанавливаем необходимое значение памяти в KB ( 512 х 1024 = 524288 ):
    virsh setmem vm_name 524288
  3. Заглядываем в virsh dominfo vm_name и видим, что максимальный объем памяти остался прежним, а используемый изменился на 524288.

Второй вариант. Увеличение объема памяти сверх установленного при создании VM.

  1. Для этого необходимо будет изменить файл конфигурации, а сначала надо погасить машину:
    virsh shutdown vm_name
  2. Правим файл конфигурации. Выполняем:
    virsh edit vm_name
    и изменяем значение (в KB)
    У кого-то это будет:

    <memory>2097152</memory>

    У меня это:

    <memory unit='KiB'>2097152</memory>
    <currentMemory unit='KiB'>2097152</currentMemory>

    Если у вас так же, то 4й шаг не понадобится.
    Для тех, кто не работал с vi: Чтобы начать править файл нажмите кнопку Insert, когда внесете необходимые изменения нажимайте Esc, а затем ZZ (две большие Z). Язык должен стоять английский, иначе редактор команду не поймет.

  3. Перезапускаем виртуальную машину из обновленного файла конфигурации:
    virsh create ~/.config/libvirt/qemu/vm_name.xml, либо
    virsh create /etc/libvirt/qemu/vm_name.xml
  4. Проверяем память. Max.memory должна измениться, а Used Memory могла остаться прежней:
    virsh dominfo vm_name | grep memory
    Если все изменилось – прекрасно. Если нет, то теперь выполняем:
    virsh setmem vm_name 2097152 и у вас тоже все прекрасно.

Изменение количества cpu

  1. Чтобы изменить количество виртуальных процессоров необходимо отредактировать файл конфигурации VM. Для этого сначала гасим нашу машину, потом открываем файл на редактирование:
    virsh shutdown vm_name
    virsh edit vm_name
  2. Далее изменяем количество в тэгах vcpu:
    <vcpu placement='static'>1</vcpu>
  3. Перезапускаем виртуальную машину из обновленного файла конфигурации:
    virsh create ~/.config/libvirt/qemu/vm_name.xml или
    virsh create /etc/libvirt/qemu/vm_name.xml

Управление объемом диска VM (добавление диска к VM)

Мы всегда можем добавить дополнительные “диски” к своей виртуальной машине на KVM. Давайте добавим еще 10 Гб дискового пространства.

  1. Создадим пустой файл на 10 Гб (естественно, путь выбираем свой):
    dd if=/dev/zero of=/vm-images/vm_name-add.img bs=1M count=10240
  2. Выключаем VM
    virsh shutdown vm_name
  3. Добавим дополнительную запись для «диска» в XML-файл виртуальной машины. Удобно скопировать блок с описанием уже существующего диска и отредактировать значения в тегах target и address:
    virsh edit vm_name
    Например у нас было такое описание диска:

     <disk type='file' device='disk'>
     <driver name='qemu' type='raw' cache='none' io='threads'/>
     <source file='/vm-images/vm1.img'/>
     <target dev='vda' bus='virtio'/>
     <address type='pci' domain='0x0000' bus='0x00' slot='0x04'
    function='0x0'/>
     </disk>

    Мы добавляем после него еще вот такой блок для подключения нашего нового диска:

     <disk type='file' device='disk'>
     <driver name='qemu' type='raw' cache='none' io='threads'/>
     <source file='/vm-images/vm1-add.img'/>
     <target dev='vdb' bus='virtio'/>
     <address type='pci' domain='0x0000' bus='0x00' slot='0x06'
    function='0x0'/>
     </disk>

    В тэге target мы изменили имя устройства. Оно должно следовать за первым в алфавитном порядке (первый наш диск vda, второй будет vdb).
    В тэге address необходимо использовать уникальный адрес слота (здесь это slot=’0x06′). Проверяйте адрес слота ВСЕХ устройств, а не только дисков.

  4. Перезапустим нашу виртуальную машину с обновленным конфигом XML:
    virsh create /etc/libvirt/qemu/vm1.xml, а может
    virsh create ~/.config/libvirt/qemu/vm_name.xml

Удаление виртуальной машины

  1. Удаляем VM с названием vm-clone. Сначала выключите VM:
    virsh shutdown vm-clone
    Если VM не отвечает, либо не может выключиться, выключите ее принудительно:
    virsh destroy vm-clone
  2. Undefine the VMs configuration:
    virsh undefine vm-clone
  3. Наконец, удалите img-файлы машины.
    rm /vm-images/vm-clone.img


Если virt-viewer не запускается, возможно он не установлен. Установите его, и , заодно, virt-manager можно:

yum install virt-manager virt-viewer

Если virt-viewer ругается, что не может найти виртуальные машины, проверьте с помощью команды virsh list --all, что виртуалки есть и запущены.
virt-viewer при запуске отобразит список запущенных виртуалок:

Как скачать и установить Red Hat Enterprise Linux 8

Не так давно стала доступна для скачивания версия RHEL 8 Beta. Естественно, я не могу пройти мимо нее. Получить в пользование 30-дневную версию RHEL 8 можно по этой ссылке. По данной ссылке доступно два варианта скачивания: для тех кто не имеет платной подписки и для тех у кого она есть. У меня нет. И мой старый аккаунт почему-то не подтянулся, может он уже не активный. Пришлось регистрироваться.
Для начала необходимо иметь или завести (это можно сделать по ссылке выше) девелоперскую учетку. После заполнения всех форм на почту придет письмо для верификации аккаунта. И в ссылке выше выбираем какую версию мы хотим качать, соглашаемся на все и ждем. DVD-образ весит 6,5 Гб.
Пока качается, немного из гайда по установке:

  • Бету нельзя использовать в продакшене. Совсем.
  • У Беты нет гарантийной поддержки.
  • RHEL приветствуют отправку баг-репортов и открыты к взаимодействию.
  • Апгрейды Беты и до Беты не поддерживаются и не рекомендуются.

Образ скачан, я ставлю Red Hat 8 на виртуалке KVM. По своему-же мануалу, проблем не возникло)
Создаю виртуалку и запускаю установку:

virt-install \
--name=RHEL8 \
--ram=1024 --vcpus=1 \
--network bridge:br0 \
--disk path=/home/Lector/vm-images/vm_rhel.img,size=30 \
--cdrom /home/Lector/rhel-8.0-beta-1-x86_64-dvd.iso \
--os-variant=Linux

Если вы ставите RHEL с флэшки, то там иногда возникает проблема – инсталлятор не видит саму флэшку как установочный диск. Люди решают проблему как-то хитро и расово-верно, а я делаю все очень просто: после создания загрузочной флэшки кладу туда еще и сам iso. И потом его выбираю как источник установки.
Появляется привычное окно, жмем Install Red Hat Enterprise Linux 8.0

Выбираем язык, который мы хотим использовать в процессе установки. То ли у меня нет глаз, то ли там действительно нет русского языка.

Получаем сообщение:
“Это предварительно выпущенное программное обеспечение, предназначенное только для разработки и тестирования. * Не * используйте это программное обеспечение для любой критической работы или в продакшене.
Нажав «I want to proceed», вы понимаете и принимаете риски, связанные с предварительно выпущенным ПО, которое вы намерены использовать только для целей тестирования и разработки и готовы сообщать о любых ошибках или проблемах, чтобы улучшить эту работу.
Если вы не понимаете или не принимаете эти риски, пожалуйста, выйдите из этой программы, выбрав «I want to exit» из вашей системы.”
Но мы то все понимаем и выбираем «I want to proceed».

Попадаем в окно настроек, которые можно сделать предварительно. Проблем с секцией LOCALIZATION возникнуть не должно ни у кого. Выбираем настройку клавиатуры, язык и установки даты/времени. Чтобы принять изменение, нажмите кнопку Done в левом верхнем углу.


Переходим к разделу SOFTWARE. В моем случае Installation Source – это local media. Секция Software Selection предлагает выбрать вариант установки. В левой части представлены варианты установки: Minimal Install (сделаю в следующем посте), Custom Operating System, Server и Workstation. Я хочу попробовать Workstation.
В правой части мы видим дополнительные пакеты, которые можно сразу установить. Не хочу греть голову ( это ж не минимал))) и выбираю все. Нажимаем Done.


Дальше секция SYSTEM, которой стоит уделить особое внимание. Состоит из 5ти пунктов:

    1. В разделе Installation Destination можно выбрать разбивку диска. Здесь мы выберем авторазбивку.
    2. KDUMP по умолчанию включен, так и оставлю. KDUMP это механизм аварийного дампа ядра. Когда происходит падение системы, он фиксирует содержимое системной памяти. Это может понадобиться для дальнейшего анализа причины сбоя. Когда KDUMP включен, он резервирует небольшой объем оперативной памяти. Эта часть памяти недоступна для основного ядра.
    3. Дальше Network & HostName. Я предпочитаю настроить и включить все сразу здесь. Переводим переключатель в положение on, жмем кнопку Configure. В моем случае настройки сети приходят по DHCP. Слева внизу можно сразу задать hostname.

    1. Далее идет Security Policy. Их можно вообще отключить, переведя переключатель “Apply security policy” в положение off. Либо щелкнуть на один из профилей и нажать кнопку “Select profile”. Применение политик безопасности не является обязательным. При применении какой-либо политики устанавливается пакет openscap-scanner, как инструмент для проверки соответствия и поиска уязвимостей. После завершения установки система будет отсканирована, отчет о результатах будет сохранен в директории /root/openscap_data .


В разделе System Purpose мы можем выбрать, как будем использовать нашу систему.

Итак. Если мы все выбрали, жмем кнопку Begin Installation. Пока система устанавливается, задаем пароль рута (Root password) и заводим себе пользователя (User Creation). Пользователя сразу можно сделать администратором. Это позволит использовать sudo.

После окончания установки нам станет доступна кнопка Reboot. Жмем и наслаждаемся тем же серым цветом загрузочного экрана, но теперь с цифрой 8.))))

После перезагрузки нас ждет приятный сюрприз. Ось сразу и сама предлагает принять лицензию. Уверенно жмем, что мы согласны и попадаем на логин.

Рабочий стол довольно веселый, стоит гном. Отвечаем на несколько вопросов о настройке и идем тестить нашу ось.

Глава 10. Управление сервисами в systemd. 10.6. Создание и изменение файлов юнитов в systemd. Часть 2

10.6.3. Конвертация SysV Init скриптов в файлы юнитов (Unit Files)

Прежде чем заняться преобразованием скрипта SysV (далее – init-скрпт) в файл юнита, убедитесь, что преобразование еще не было выполнено в другом месте. Все основные службы, установленные в Red Hat Enterprise Linux 7, поставляются со стандартными юнит-файлами, и то же самое относится ко многим сторонним программным пакетам.
Преобразование init-скрипта в юнит-файл требует анализа init-скрипта и извлечения из него необходимой информации. На основе полученных данных вы можете создать файл юнита, как описано в разделе 10.6.2 «Создание пользовательских файлов юнита». Поскольку init-скрипты могут сильно различаться в зависимости от типа сервиса, возможно вам потребуется использовать больше параметров конфигурации для конвертации, чем описано в этой главе. Обратите внимание, что некоторые уровни настройки, которые были доступны в init-скриптах, больше не поддерживаются модулями systemd, см. Раздел 10.1.2, «Изменения совместимости».
Большая часть информации, необходимой для конвертации, указана в заголовке скрипта. В следующем примере показан начальный раздел init-скрипта, используемого для запуска службы postfix в Red Hat Enterprise Linux 6 (пример файла юнита для postfix можно найти в предыдущей части):

#!/bin/bash
#
# postfix      Postfix Mail Transfer Agent
#
# chkconfig: 2345 80 30
# description: Postfix is a Mail Transport Agent, which is the program \
#              that moves mail from one machine to another.
# processname: master
# pidfile: /var/spool/postfix/pid/master.pid
# config: /etc/postfix/main.cf
# config: /etc/postfix/master.cf
 
### BEGIN INIT INFO
# Provides: postfix MTA
# Required-Start: $local_fs $network $remote_fs
# Required-Stop: $local_fs $network $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: start and stop postfix
# Description: Postfix is a Mail Transport Agent, which is the program that 
#              moves mail from one machine to another.
### END INIT INFO

В приведенном выше примере обязательны только строки, начинающиеся с #chkconfig и #description, поэтому вы можете не найти остальных в разных init-файлах. Текст, заключенный между строками ### BEGIN INIT INFO и ### END INIT INFO, называется заголовком Linux Standard Base (LSB). Если LSB-заголовок указан, то он содержит директивы, определяющие описание службы, зависимости и уровни запуска (runlevels). Далее следует обзор аналитических задач, направленных на сбор данных, необходимых для нового юнит-файла. В качестве примера используется init-скрипт postfix, см. Итоговый файл модуля postfix в примере 10.17, «Файл юнита postfix.service».

Поиск описания сервиса

Найдите описание скрипта в строке, начинающейся с #description. Используйте это описание вместе с именем сервиса в опции Description секции [Unit] в файле юнита. Заголовок LSB может содержать аналогичные данные в строках #Short-Description и #Description.

Поиск зависимостей сервиса

Заголовок LSB может содержать несколько директив, которые формируют зависимости между сервисами. Большая часть может быть переведена в опции юнита systemd, см. Таблицу 10.12, «Параметры зависимостей из заголовка LSB».

Таблица 10.12, Параметры зависимостей из заголовка LSB
Опция LSB Описание Опция юнита
Provides Задает имя сервиса при загрузке, на которое можно ссылаться в других скриптах (с префиксом “$”). Сейчас это не требуется, т.к. юнит-файлы ссылаются на другие юнит-файлы по их именам.
Required-Start Содержит загрузочные имена необходимых сервисов. Т.е. это зависимости упорядочения, имена необходимых сервисов при переводе заменяются на имена юнит-файлов соответствующих сервисов или таргетов, которым они принадлежат. Например, в случае с postfix зависимость Required-Start: $network была переведена в зависимость After=network.target. After, Before
Should-Start Определяет более слабые зависимости, чем Required-Start. Неудачные зависимости Should-Start не влияют на запуск службы. After, Before
Required-Stop, Should-Stop Определяет негативные зависимости. Conflicts

Определение таргета для запуска сервиса

Строка, начинающаяся с #chkconfig, содержит три числовых значения. Для нас важно первое число, которым представлены уровни запуска по умолчанию для данного сервиса. Используйте Таблицу 10.6, «Сравнение уровней запуска SysV с таргетами systemd», чтобы перевести эти уровни выполнения в таргеты systemd. Затем перечислите эти таргеты в опции WantedBy в разделе [Install] файла юнита. Например, postfix ранее запускался на уровнях запуска 2, 3, 4 и 5, что соответствует таргетам multi-user.target и graphical.target в Red Hat Enterprise Linux 7. Обратите внимание, что graphical.target зависит от multiuser.target, поэтому нет необходимости указывать оба, как в примере 10.17, «Файл модуля postfix.service». Вы также можете найти информацию о дефолтных и запрещенных уровнях запуска в строках #Default-Start и #Default-Stop в заголовке LSB.
Два других значения, указанные в строке #chkconfig, представляют приоритеты запуска и завершения init-скрипта. Эти значения интерпретируются systemd, если он загружает init-скрипт, но нет эквивалентного юнит-файла.

Определение файлов, используемых сервисом

Init-скрипты требуют загрузки библиотеки функций из выделенной директории и позволяют импортировать файлы конфигурации, среды и PID файлы. Переменные среды указываются в строке, начинающейся с #config в заголовке скрипта и соответствует опции EnvironmentFile в файле юнита. Файл PID, указанный в init-скрипте в строке #pidfile импортируется в файл юнита с опцией PIDFile.
Ключевой информацией, которая не включена в заголовок скрипта, является путь к исполняемому файлу сервиса и, возможно, некоторые другие файлы, необходимые для сервиса. В предыдущих версиях Red Hat Enterprise Linux init-скрипты использовали оператор Bash case, чтобы определить поведение службы при действиях по умолчанию, таких как запуск, остановка или перезапуск, а также при выполнении определенных пользователем действий. Следующий фрагмент из init-скрипта postfix показывает блок кода, который должен быть выполнен при запуске сервиса.

conf_check() {
    [ -x /usr/sbin/postfix ] || exit 5
    [ -d /etc/postfix ] || exit 6
    [ -d /var/spool/postfix ] || exit 5
}
 
make_aliasesdb() {
	if [ "$(/usr/sbin/postconf -h alias_database)" == "hash:/etc/aliases" ]
	then
		# /etc/aliases.db might be used by other MTA, make sure nothing
		# has touched it since our last newaliases call
		[ /etc/aliases -nt /etc/aliases.db ] ||
			[ "$ALIASESDB_STAMP" -nt /etc/aliases.db ] ||
			[ "$ALIASESDB_STAMP" -ot /etc/aliases.db ] || return
		/usr/bin/newaliases
		touch -r /etc/aliases.db "$ALIASESDB_STAMP"
	else
		/usr/bin/newaliases
	fi
}
 
start() {
	[ "$EUID" != "0" ] && exit 4
	# Check that networking is up.
	[ ${NETWORKING} = "no" ] && exit 1
	conf_check
	# Start daemons.
	echo -n $"Starting postfix: "
	make_aliasesdb >/dev/null 2>&1
	[ -x $CHROOT_UPDATE ] && $CHROOT_UPDATE
	/usr/sbin/postfix start 2>/dev/null 1>&2 && success || failure $"$prog start"
	RETVAL=$?
	[ $RETVAL -eq 0 ] && touch $lockfile
        echo
	return $RETVAL
}

Init-скрипт позволяет указать пользовательские функции, здесь это conf_check() и make_aliasesdb(), которые вызываются из функционального блока start(). В приведенном выше коде упоминаются несколько внешних файлов и директорий: исполняемый файл основного сервиса /usr/sbin/postfix, директории конфигураций /etc/postfix/ и /var/spool/postfix/, а также директория /usr/sbin/postconf/.
Systemd поддерживает только предопределенные действия, но позволяет выполнять пользовательские исполняемые файлы с помощью ExecStart, ExecStartPre, ExecStartPost, ExecStop и ExecReload. В случае с postfix в RHEL 7, /usr/sbin/postfix выполняется вместе со вспомогательными скриптами при запуске сервиса. Посмотрите файл юнита postfix в Примере 10.17, «Файл модуля postfix.service».
Преобразование сложных скриптов требует понимания назначения каждого оператора в скрипте. Некоторые операторы относятся к конкретной версии операционной системы, поэтому вам не нужно переводить их. С другой стороны, в новой среде могут потребоваться некоторые корректировки, как в файле юнита, так и в исполняемом файле сервиса и вспомогательных файлах.

10.6.4. Изменение существующих файлов юнитов

Службы, установленные в системе, поставляются с файлами юнитов по умолчанию, которые хранятся в директории /usr/lib/systemd/system/. Системные администраторы не должны изменять эти файлы напрямую, любые настройки должны быть ограничены файлами конфигурации в директории /etc/systemd/system/. В зависимости от степени необходимых изменений выберите один из следующих подходов:

  • Создайте директори. для дополнительных файлов конфигурации в /etc/systemd/system/unit.d/. Этот метод рекомендуется в большинстве случаев. Это позволяет расширить конфигурацию дополнительными функциональными возможностями, ссылаясь при этом на исходный файл юнита. Поэтому изменения в юните, поисходящие при обновлении пакета, применяются автоматически. См. Раздел «Расширение конфигурации юнита по умолчанию» для получения дополнительной информации.
  • Создайте копию файла юнита из /usr/lib/systemd/system/ в /etc/systemd/system/ и делайте изменения в ней. Копия переопределяет исходный файл, поэтому изменения, внесенные обновлением пакета, не применяются. Этот метод полезен для внесения значительных изменений в юниты, которые должны сохраняться независимо от обновлений пакета. Подробнее см. в разделе «Переопределение конфигурации модуля по умолчанию».

Чтобы вернуться к стандартной конфигурации юнита, просто удалите пользовательские файлы конфигурации в /etc/systemd/system/. Чтобы применить изменения к файлам юнита без перезагрузки системы, выполните:

systemctl daemon-reload

Опция daemon-reload перезагружает все файлы юнитов и воссоздает все дерево зависимостей для применения любых изменений в файлах юнитов. Того же результата можно добиться с помощью следующей команды:

init q

Также, если модифицированный юнит-файл принадлежит работающему сервису, необходимо перезапустить сам сервис для применения новых настроек:

systemctl restart name.service

Важно
Чтобы изменить свойства (такие как зависимости или тайм-ауты) сервиса, который обрабатывается init-скриптом SysV, не изменяйте сам init-скрипт. Вместо этого создайте системный файл конфигурации systemd для службы, как описано в разделе «Расширение конфигурации юнита по умолчанию» и в разделе «Переопределение конфигурации юнита по умолчанию». Затем управляйте этим сервисом так же, как обычным сервисом systemd.
Например, чтобы расширить конфигурацию сервиса network, не изменяйте init-файл /etc/rc.d/init.d/network. Вместо этого создайте новую директорию /etc/systemd/system/network.service.d/ и drop-in файл /etc/systemd/system/network.service.d/my_config.conf (прим. переводчика: для себя я определяю drop-in файлы как дополнительные конфиги. Система заглядывает в каталоги конфигурации и подбирает то, что там лежит). Затем поместите измененные значения в drop-in файл. Заметка: systemd знает сервис network как network.service, поэтому созданный каталог должен называться network.service.d.

Расширение конфигурации юнитов

Чтобы добавить дополнительные параметры конфигурации в файл юнита, сначала создайте директорию конфигурации в /etc/systemd/system/. Если вы расширяете юнит сервиса, выполните следующую команду от root:

mkdir /etc/systemd/system/name.service.d/

Замените name именем сервиса, который вы хотите расширить. Вышеуказанный синтаксис применяется ко всем типам юнитов.
Создайте файл конфигурации в директории, созданной на предыдущем шаге. Имя файла должно иметь суффикс .conf . Наберите:

touch /etc/systemd/system/name.service.d/config_name.conf

Замените config_name на имя файла конфигурации. Этот файл имеет структуру обычного файла юнита, поэтому все директивы должны быть указаны в соответствующих разделах, см. Раздел 10.6.1, «Понимание структуры файла юнита».
Например, чтобы добавить зависимость, создайте файл конфигурации со следующим содержимым:

[Unit]
Requires=new_dependency
After=new_dependency

Где new_dependency обозначает юнит, который помечен как зависимость. Другой пример файла конфигурации, который перезапускает сервис после того, как основной процесс завершится, с задержкой 30 секунд:

[Service]
Restart=always
RestartSec=30

Рекомендуется создавать небольшие файлы конфигураций, ориентированные на одну задачу. Такие файлы легко переместить или связать (создать линк) с каталогами конфигурации других сервисов.
Чтобы внесенные изменения вступили в силу, выполните от root:

systemctl daemon-reload
systemctl restart name.service

Пример 10.20. Расширение конфигурации httpd.service

Изменим юнит httpd.service так, чтобы при запуске Apache автоматически выполнялся shell-скрипт. Создайте каталог и файл конфигурации:

~]# mkdir /etc/systemd/system/httpd.service.d/
~]# touch /etc/systemd/system/httpd.service.d/custom_script.conf

Предположим, что /usr/local/bin/custom.sh – путь к скрипту, который вы хотите запустить вместе с Apache, вставьте следующий текст в файл custom_script.conf:

[Service]
ExecStartPost=/usr/local/bin/custom.sh

Чтобы принять изменения, выполните:

~]# systemctl daemon-reload
~]# systemctl restart httpd.service

Заметка

Файлы конфигурации из директорий /etc/systemd/system/ имеют приоритет над файлами юнитов в /usr/lib/systemd/system/. Следовательно, если файлы конфигурации содержат параметр, который может быть указан только один раз, например, Description или ExecStart, значение по умолчанию для этого параметра переопределяется. Обратите внимание, что в выходных данных команды systemd-delta, описанной в разделе «Мониторинг переопределенных юнитов», такие юниты всегда помечаются как [EXTENDED], хотя фактически некоторые параметры переопределяются.

Переопределение конфигурации юнита по умолчанию

Чтобы внести изменения в юнит, которые сохранятся после обновления пакета, сначала скопируйте файл в каталог /etc/systemd/system/. Для этого выполните от root:

cp /usr/lib/systemd/system/name.service /etc/systemd/system/name.service

Где name – имя сервиса, файл юнита которого вы хотите изменить. Этот синтаксис применим ко всем типам юнитов.
Откройте скопированный файл в текстовом редакторе и внесите желаемые изменения. Чтобы принять изменения, выполните от root:

systemctl daemon-reload
systemctl restart name.service

Пример 10.21. Изменение тайм-аута

Вы можете указать тайм-аут для каждой службы, чтобы предотвратить зависание системы из-за сбоя в работе службы. Обычно, тайм-аут установлен в 90 секунд для обычных сервисов и 300 секунд для SysV-совместимых сервисов.
Например, установим тайм-аут для httpd сервиса:

  1. Скопируйте юнит-файл httpd в директорию /etc/systemd/system/:
    cp /usr/lib/systemd/system/httpd.service /etc/systemd/system/httpd.service
  2. Откройте файл /etc/systemd/system/httpd.service и определите значение TimeoutStartUSec в секции [Service]:
    ...
    [Service]
    ...
    PrivateTmp=true
    TimeoutStartSec=10
     
    [Install]
    WantedBy=multi-user.target
    ...
  3. Перезагрузите демон systemd:
    systemctl daemon-reload
  4. Проверьте, что новый тайм-аут установлен:
    systemctl show httpd -p TimeoutStartUSec

Заметка
Чтобы сменить тайм-аут глобально, введите значение DefaultTimeoutStartSec в файл /etc/systemd/system.conf. Подробнее см. раздел 10.1, “Введение в systemd”.

Мониторинг переопределенных юнитов

Чтобы просмотреть переопределенные или измененные юниты, используйте следующую команду:

systemd-delta

Например, вывод вышеуказанной команды может выглядеть следующим образом:

[EQUIVALENT] /etc/systemd/system/default.target → /usr/lib/systemd/system/default.target
[OVERRIDDEN] /etc/systemd/system/autofs.service → /usr/lib/systemd/system/autofs.service
 
--- /usr/lib/systemd/system/autofs.service      2014-10-16 21:30:39.000000000 -0400
+++ /etc/systemd/system/autofs.service  2014-11-21 10:00:58.513568275 -0500
@@ -8,7 +8,8 @@
 EnvironmentFile=-/etc/sysconfig/autofs
 ExecStart=/usr/sbin/automount $OPTIONS --pid-file /run/autofs.pid
 ExecReload=/usr/bin/kill -HUP $MAINPID
-TimeoutSec=180
+TimeoutSec=240
+Restart=Always
 
 [Install]
 WantedBy=multi-user.target
 
[MASKED]     /etc/systemd/system/cups.service → /usr/lib/systemd/system/cups.service
[EXTENDED]   /usr/lib/systemd/system/sssd.service → /etc/systemd/system/sssd.service.d/journal.conf
 
4 overridden configuration files found.

В таблице 10.13 «Типы различий systemd-delta» перечислены типы переопределений, которые можно увидеть в выводе systemd-delta. Обратите внимание, что если файл переопределен, systemd-delta по умолчанию отображает сводку изменений, аналогичную выводу команды diff.

Таблица 10.13, Типы различий systemd-delta
Опция LSB Описание
[MASKED] Замаскированные юниты. Как замаскировать юнит см. Раздел 10.2.7, “Удаление из автозагрузки”.
[EQUIVALENT] Неизмененные копии, которые переопределяют исходные файлы, но не отличаются по содержанию, как правило, это символические ссылки.
[REDIRECTED] Файлы, которые перенаправляют в другой файл.
[OVERRIDEN] Перезаписанные и измененные файлы.
[EXTENDED] Файлы, которые расширены файлами .conf в директории /etc/systemd/system/unit.d/.
[UNCHANGED] Неизмененные файлы, отображаются при использовании опции --type=unchanged.

Рекомендуется запускать systemd-delta после обновления системы, чтобы проверить, есть ли какие-либо обновления для юнитов по умолчанию, которые в настоящее время переопределяются пользовательской конфигурацией. Также можно ограничить вывод только определенным типом различий. Например, чтобы просмотреть только переопределенные блоки [OVERRIDEN], выполните:

systemd-delta --type=overridden

10.6.5. Работа с юнитами, созданными из шаблона (Instantiated Units)

Можно создать несколько экземпляров из одного файла конфигурации шаблона во время выполнения. Символ «@» используется для обозначения шаблона и ассоциации юнита с ним. Instantiated units могут быть запущены из другого файла юнита (с использованием параметров Requires или Wants) или с помощью команды systemctl start. Instantiated service units именуются следующим образом:

template_name@instance_name.service

Где template_name – имя файла конфигурации шаблона. Замените instance_name именем экземпляра юнита. Несколько экземпляров могут указывать на один и тот же файл шаблона с параметрами конфигурации, общими для всех экземпляров юнита. Имя шаблона юнита имеет вид:

unit_name@.service

Например, следующая настройка Wants в файле юнита:

Wants=getty@ttyA.service,getty@ttyB.service

сначала выполняет поиск для заданных сервисных юнитов. Если таких юнитов не найдено, часть между “@” и суффиксом типа игнорируется, и systemd ищет файл getty@.service, считывает из него конфигурацию и запускает сервисы.
Подстановочные знаки, называемые спецификаторами единиц, могут использоваться в любом файле конфигурации юнитов. Спецификаторы юнита заменяют определенные параметры модуля и интерпретируются во время выполнения. В таблице 10.14 «Важные спецификаторы юнитов» перечислены полезные для юнитов-шаблонов спецификаторы юнитов.

Таблица 10.14, Важные спецификаторы юнитов
Спецификатор Значение Описание
%n Полное имя юнита Полное имя юнита, включая суффикс. %N имеет то же значение, но также заменяет запрещенные символы на коды ASCII.
%p Префикс Имя юнита без суффикса типа. Для созданных экземпляров юнитов %p обозначает часть имени юнита перед символом «@».
%i Instance name Имя экземпляра Это часть имени экземпляра юнита между символом «@» и суффиксом типа. %I имеет то же значение, но также заменяет запрещенные символы на коды ASCII.
%H Host name Имя хоста Имя хоста работающей системы в момент загрузки конфигурации юнита.
%t Runtime directory Represents the runtime directory, which is either /run for the root user, or the value of the XDG_RUNTIME_DIR variable for unprivileged users.
Представляет собой runtime-директорию, которая либо /run для пользователя root, либо значение из переменной окружения XDG_RUNTIME_DIR для непривилегированных пользователей.

Полный список спецификаторов см. в мануале systemd.unit(5).

Например, шаблон getty@.service содержит следующие директивы:

[Unit]
Description=Getty on %I
...
[Service]
ExecStart=-/sbin/agetty --noclear %I $TERM
...

Когда создаются экземпляры getty@ttyA.service и getty@ttyB.service из вышеприведенного шаблона, Description = преобразуется в Getty on ttyA и Getty on ttyB.

10.7. Additional Resources – этот раздел я не вижу смысла переводить, так как он просто содержит ссылки на дополнительные источники информации. Но оставлю его тут)

Глава 10. Управление сервисами в systemd. 10.6. Создание и изменение файлов юнитов в systemd. Часть 1

Файл юнита содержит директивы, которые описывают юнит и определяют его поведение. Некоторые команды systemctl работают с файлами юнитов в фоновом режиме. Чтобы произвести более детальную настройку, системный администратор должен отредактировать или создать файл юнита вручную. В Таблице 10.2 «Расположение файлов юнитов systemd» перечислены три основных директории, в которых хранятся файлы юнитов системы. Каталог /etc/systemd/system/ зарезервирован для юнитов, созданных или настроенных системным администратором.
Имена файлов имеют следующий вид:

unit_name.type_extension

где unit_name – имя юнита, type_extension – его тип. Полный список типов юнитов см. в Таблице 10.1, “Доступные типы юнитов systemd”. Например, обычно в системе существуют юниты sshd.service и sshd.socket.
Файлы юнитов могут быть дополнены каталогом дополнительных конфигурационных файлов. Например, чтобы добавить пользовательскую конфигурацию sshd.service, создайте файл sshd.service.d/custom.conf и добавьте в него дополнительные директивы. Больше информации о директориях конфигурации см. в разделе 10.6.4, “Изменение существующих файлов юнитов”.
Кроме того, могут быть созданы директории sshd.service.wants/ и sshd.service.requires/. Эти директории содержат символические ссылки (симлинки) на файлы юнитов сервиса sshd. Симлинки либо автоматически создаются во время установки в соответствии с параметрами в секции [Install] файла юнита (см. таблицу 10.11, “Важные опции секции [Install]), либо во время выполнения в соответствии с параметрами секции [Unit] (см. таблицу 10.9, “Важные опции секции [Unit]). Также можно создать эти директории и симлинки вручную.
Многие опции юнит-файла могут быть установлены с использованием так называемых спецификаторов юнитов – подстановочных строк, которые динамически заменяются параметрами юнита при загрузке файла юнита. Это позволяет создавать общие файлы юнитов, которые служат шаблонами для генерации конкретных экземпляров. См. раздел 10.6.5, “Работа с юнитами, созданными из шаблона (Instantiated Units)” для получения дополнительной информации.

10.6.1 Понимание структуры файла юнита

Файлы юнитов обычно содержат три секции:

Таблица 10.9, Важные параметры секции [Unit]
Опция[a] Описание
Description Информативное описание юнита. Эта информация отображается, например, в выводе команды systemctl status
Documentation Предоставляет список URI (Uniform Resource Identifier — унифицированный идентификатор ресурса), ссылающийся на документацию для юнита.
After[b] Определяет порядок запуска юнитов. Юнит запускается только после того, как активированы юниты, указанные в After. В отличие от Requires, After не активирует явно определенные юниты. Опция Before имеет противоположную функциональность After.
Requires Настраивает зависимости от других юнитов. Юниты, перечисленные в разделе Requires, активируются вместе с юнитом. Если какой-либо из необходимых юнитов не запускается, юнит не активируется.
Wants Настраивает более слабые зависимости, чем Requires. Если какой-либо из перечисленных юнитов не запускается, он не влияет на активацию данного юнита. Это рекомендуемый способ установки зависимостей пользовательских юнитов.
Conflicts Настраивает отрицательные зависимости, противоположные Requires.
[a] Полный список параметров, настраиваемых в разделе [Unit], см. в man systemd.unit (5).
[b] В большинстве случаев, достаточно устновить зависимости с опциями After и Before. Если вы также установили зависимость от требований Wants (рекомендуется) или Requires, зависимости последовательности все еще должны быть определены. Связано это с тем, что зависимости упорядочения и требований работают раздельно.

Таблица 10.10, Важные параметры секции [Service]
Опция[a] Описание
Type Настраивает тип запуска юнита, который влияет на функциональность ExecStart и связанных с ним опций. Возможные значения:

  • simple – Значение по умолчанию. Процесс стартующий с ExecStart, является основным процессом сервиса.
  • forking – Процесс, запущенный с ExecStart, порождает дочерний процесс, который становится основным процессом сервиса. После завершения запуска родительский процесс завершается.
  • oneshot – Этот тип похож на simple, но процесс завершается до запуска последующих юнитов.
  • dbus – Этот тип похож на simple, но последующие юниты запускаются только после того, как основной процесс получает D-Bus имя.
  • notify – похож на simple, но последующие юниты запускаются только после отправвки уведомления посредством функции sd_notify().
  • idle – похож на simple, фактическое выполнение сервиса задерживается до завершения всех заданий, что позволяет избежать смешивания потока вывода состояния с выводом сервиса.
ExecStart Указывает команды или сценарии, которые должны выполняться при запуске юнита. ExecStartPre и ExecStartPost определяют пользовательские команды, которые должны выполняться до и после ExecStart. Type=oneshot позволяет указать несколько пользовательских команд, которые затем выполняются последовательно.
ExecStop Определяет команды или скрипты, которые должны выполняться при остановке юнита.
ExecReload Определяет команды или скрипты, которые должны выполняться при перезагрузке юнита.
Restart Если эта опция включена, сервис перезапускается после завершения его процесса, за исключением чистой остановки командой systemctl.
RemainAfterExit Если установлено значение True, сервис считается активным, даже когда все его процессы завершены. Значение по умолчанию – False. Эта опция особенно полезна, если используется Type=oneshot.
[a] Полный список параметров, настраиваемых в разделе [Service], см. в man systemd.service (5).

Таблица 10.11, Важные параметры секции [Install]
Опция[a] Описание
Alias Предоставляет список дополнительных имен для юнита, разделенных побелами. Большая часть команд systemctl, за исключением systemctl enable, может использовать алиасы вместо фактического имени юнита.
RequiredBy Список юнитов, которые зависят от этого юнита. Когда этот юнит включен, юниты перечисленные в RequiredBy gain a Require dependency on the unit.
WantedBy Список юнитов, которые слабо зависят от этого юнита. Когда этот юнит включен, юниты перечисленные в WantedBy gain a Want dependency on the unit.
Also Указывает список юнитов, которые будут установлены или удалены вместе с юнитом.
DefaultInstance Ограничена конкретным юнитом, эта опция определяет экземпляр по умолчанию для которого активирован юнит. См. раздел 10.6.5, “Работа с юнитами, созданными из шаблона (Instantiated Units)”
[a] Полный список параметров, настраиваемых в разделе [Install], см. в man systemd.unit (5).

Пример 10.17, «Юнит-файл postfix.service» показывает пример сервисного юнита, установленного в системе. Кроме того, параметры файла юнита могут быть определены таким образом, чтобы обеспечить динамическое создание юнитов, как описано в Разделе 10.6.5 «Работа с юнитами, созданными из шаблона (Instantiated Units)».

Пример 10.17. Юнит-файл postfix.service

Ниже представлено содержание файла юнита /usr/lib/systemd/system/postifix.service:

[Unit]
Description=Postfix Mail Transport Agent
After=syslog.target network.target
Conflicts=sendmail.service exim.service
 
[Service]
Type=forking
PIDFile=/var/spool/postfix/pid/master.pid
EnvironmentFile=-/etc/sysconfig/network
ExecStartPre=-/usr/libexec/postfix/aliasesdb
ExecStartPre=-/usr/libexec/postfix/chroot-update
ExecStart=/usr/sbin/postfix start
ExecReload=/usr/sbin/postfix reload
ExecStop=/usr/sbin/postfix stop
 
[Install]
WantedBy=multi-user.target

Секция [Unit] описывает сервис, определяет зависимости, а также конфликтующие юниты. В [Service] указывается последовательность пользовательских скриптов, которые должны выполняться во время активации юнита, остановки и перезагрузки. EnvironmentFile указывает на место, где определены переменные среды для сервиса, PIDFile задает PID для основного процесса сервиса. Наконец, в разделе [Install] перечислены зависимости.

10.6.2. Создание пользовательских файлов юнитов

Существует несколько способов создания файлов юнитов с нуля: вы можете запустить собственны демон, создать второй экземпляр какой-либо существующей службы (как в примере 10.19, «Создание второго экземпляра службы sshd») или импортировать скрипт инициализации SysV (см. в разделе 10.6.3, «Преобразование сценариев инициализации SysV в файлы модулей»). С другой стороны, если вы намереваетесь просто изменить или расширить поведение существующего юнита, используйте инструкции из раздела 10.6.4, «Изменение существующих файлов модуля». Следующая процедура описывает общий процесс создания пользовательского юнита:

  1. Подготовьте исполняемый файл с помощью пользовательского сервиса. Это может быть пользовательский скрипт или исполняемый файл, предоставленный поставщиком программного обеспечения. При необходимости подготовьте PID-файл для хранения постоянного PID основного процесса пользовательской службы. Также можно включить файлы среды для хранения переменных оболочки для сервиса. (It is also possible to include environment files to store shell variables for the service.) Убедитесь, что исходный скрипт является исполняемым (выполнив команду chmod a+x) и не является интерактивным.
  2. Создайте файл юнита в директории /etc/systemd/system/ и убедитесь, что он имеет корректные права доступа. Выполните от рута:
    touch /etc/systemd/system/name.service
    chmod 664 /etc/systemd/system/name.service

    Замените name имененм сервиса, который должен быть создан. Обратите внимание, что файл не должен быть исполняемым.

  3. Откройте файл name.service, созданный на предыдущем шаге и добавьте параметры конфигурации сервиса. Существует множество вариантов, которые можно использовать в зависимости от типа службы, которую вы хотите создать, см. раздел 10.6.1, «Понимание структуры файлов модуля». Ниже приведен пример конфигурации модуля для сетевой службы:
    [Unit]
    Description=service_description
    After=network.target
     
    [Service]
    ExecStart=path_to_executable
    Type=forking
    PIDFile=path_to_pidfile
     
    [Install]
    WantedBy=default.target

    Где:

    • service_description – это информативное описание, которое отображается в логах (журналах) и в выводе команды systemctl status.
    • настройка After обеспечивает запуск службы только после запуска сети. Добавьте добавьте другие службы или таргеты, разделив их пробелами.
    • path_to_executable устанавливает путь к исполняемому файлу службы.
    • Type=forking используется для демонов, которые делают системный вызов fork. Основной процесс службы создается с PID, указанным в path_to_pidfile. Другие типы запуска можно посмотреть в таблице 10.10, «Важные опции [Service]».
    • WantedBy указывает таргет или таргеты, под которыми служба должна быть запущена. Представьте, что это замена старой концепции ранлевелов, подробнее см. Раздел 10.3, «Работа с таргетами systemd».
  4. Сообщите systemd о существовании нового файла с именем name.service выполнив следующую команду от root:
    systemctl daemon-reload
    systemctl start name.service

    Предупреждение!
    Всегда выполняйте команду systemctl daemon-reload после создания нового файла юнита или модификации существующего. В противном случае, команды systemctl start или systemctl enable могут завершиться ошибкой из-за несоответствия между состоянием systemd и актуальными файлами юнитов на диске.
    Юнит name.service теперь может управляться как любой другой сервис с помощью команд, описанных в разделе 10.2 “Управление системными сервисами”.

Пример 10.18. Создание файла emacs.service

При использовании текстового редактора Emacs часто быстрее и удобнее запускать его в фоновом режиме, а не запускать новый экземпляр программы при редактировании файла. Далее показано, как создать файл юнита для Emacs, чтобы он мог обрабатываться как служба.

  1. Создайте юнит-файл в директории /etc/systemd/system/ удостоверьтесь, что он имеет корректные права доступа. Выполните как root:
    ~]# touch /etc/systemd/system/emacs.service
    ~]# chmod 664 /etc/systemd/system/emacs.service
  2. Добавьте в файл следующее содержимое:
    [Unit]
    Description=Emacs: the extensible, self-documenting text editor
     
    [Service]
    Type=forking
    ExecStart=/usr/bin/emacs --daemon
    ExecStop=/usr/bin/emacsclient --eval "(kill-emacs)"
    Environment=SSH_AUTH_SOCK=%t/keyring/ssh
    Restart=always
     
    [Install]
    WantedBy=default.target

    В приведенной выше конфигурации исполняемый файл /usr/bin/emacs запускается как демон при запуске службы. Переменная среды SSH_AUTH_SOCK задается с помощью спецификатора “%t”, который stands for the runtime directory. Сервис также перезапускает процесс emacs, если он неожиданно завершает работу.

  3. Выполните следующие команды, чтобы перезагрузить конфигурацию и запустить пользовательский сервис:
    ~]# systemctl daemon-reload
    ~]# systemctl start emacs.service

Поскольку редактор теперь зарегистрирован как сервис systemd, вы можете использовать все стандартные команды systemctl. Например, запустите systemctl status emacs для отображения статуса редактора или systemctl enable emacs для автоматического запуска редактора при загрузке системы.

Пример 10.19. Создание второго экземпляра службы sshd

Системным администраторам часто приходится настраивать и запускать несколько экземпляров служб. Это делается путем создания копий исходных файлов конфигурации службы и изменения определенных параметров, чтобы избежать конфликтов с основным экземпляром службы. Следующий шаги показывают, как создать второй экземпляр службы sshd:

  1. Создайте копию файла sshd_config file который будет использоваться вторым демоном:
    ~]# cp /etc/ssh/sshd{,-second}_config
  2. Отредактируйте ранее созданный файл sshd-second_config, ччтобы назначить другой порт и и PID-файл для второго демона:
    Port 22220
    PidFile /var/run/sshd-second.pid

    См. мануал sshd_config(5) (man sshd_config) для получения дополнительной информации об опция Port и PidFile. Удостоверьтесь, что порт, который вы выбрали, не используется другим сервисом. PID-файл не должен существовать до запуска сервиса, он генерируется автоматически при старте сервиса.

  3. Создайте копию файла юнита systemd для сервиса sshd:
    ~]# cp /usr/lib/systemd/system/sshd.service /etc/systemd/system/sshd-second.service
  4. После измените файл sshd-second.service следующим образом:
    • Измените опцию Description:
      Description=OpenSSH server second instance daemon
    • Добавьте sshd.service к службам, указанным в опции After, чтобы второй экземпляр запускался только после того, как первый уже запущен:
      After=syslog.target network.target auditd.service sshd.service
    • Первый экземпляр sshd включает генерацию ключа, поэтому удалите строку ExecStartPre=/usr/sbin/sshd-keygen.
    • Добавьте параметр -f /etc/ssh/sshd-second_config к команде запуска sshd, чтобы использовать альтеративный файл конфигурации:
      ExecStart=/usr/sbin/sshd -D -f /etc/ssh/sshd-second_config $OPTIONS
    • После вышеуказанных изменений sshd-second.service должен выглядеть следующим образом:
      [Unit]
      Description=OpenSSH server second instance daemon
      After=syslog.target network.target auditd.service sshd.service
       
      [Service]
      EnvironmentFile=/etc/sysconfig/sshd
      ExecStart=/usr/sbin/sshd -D -f /etc/ssh/sshd-second_config $OPTIONS
      ExecReload=/bin/kill -HUP $MAINPID
      KillMode=process
      Restart=on-failure
      RestartSec=42s
       
      [Install]
      WantedBy=multi-user.target
  5. Если вы используете SELinux, добавьте порт для второго экземпляра sshd в порты для SSH, иначе привязка у порту для второго экземпляра будет отклонена:
    ~]# semanage port -a -t ssh_port_t -p tcp 22220
  6. Добавьте сервис sshd-second.service в автоматическую загрузку:
    ~]# systemctl enable sshd-second.service

    Проверьте, запущен ли sshd-second.service, с помощью команды systemctl status. Также проверьте, доступен ли порт, подключившись к сервису:

    ~]~]$ ssh -p 22220 user@server

    Если используется файрвол, убедитесь что он настроен таким образом, чтобы разрешать подключение второго экземпляра sshd по данному порту.

Для получения информации о том, как правильно выбрать таргет, для упорядочения и зависимостей пользовательских юнитов, см следующие статьи:
How to write a service unit file which enforces that particular services have to be started
How to decide what dependencies a systemd service unit definition should have
Дополнительная информация с реальными примерами упорядочения и зависимостей для файлов юнитов доступна в следующей статье: Is there any useful information about writing unit files?
Как установить ограничения для служб, запускаемых systemd, см. в Статье базы знаний Red Hat How to set limits for services in RHEL 7 and systemd. Эти ограничения должны быть установлены в файле юнита службы. Обратите внимание, что systemd игнорирует ограничения, установленные в файлах конфигурации /etc/security/limits.conf и /etc/security/limits.d/*.conf. Ограничения, определенные в этих файлах, устанавливаются PAM при запуске сеанса входа в систему, но демоны, запущенные systemd, не используют сеансы входа в PAM.

Бэкап на sftp с ротацией

Исходные данные:
Необходимо делать бэкап чего-то раз в сутки. Нужно хранить последние 5 версий бэкапа. Бэкап надо сохранять на сервер бэкапа, доступ к которому предоставлен по sftp (в моем случае еще и ключа на sftp нет, будем делать по паролю. Если у вас ключ – поздравляю! Вы счастливчик!).
Проверяем установлен ли у нас пакет sshfs. Если нет – устанавливаем. Для RHEL/CentOS:

sudo yum install sshfs

Debian/Ubuntu:

sudo apt-get install sshfs

Cоздаем папку для монтирования:

sudo mkdir /mnt/sftp

Создаем скрипт sshfs_mount.sh для монтирования sftp к нашей файловой системе.Если у вас авторизация по ключу для sftp, содержание файла скрипта будет следующим:

#!/bin/bash
sshfs user@my.sftp.backup.server:/ /mnt/sftp/

Если вам необходимо авторизоваться по паролю, то можно сделать так:

#!/bin/bash
sshfs -o password_stdin user@my.sftp.backup.server:/ /mnt/sftp/ <<< "my_password"

Вообще, можно не выносить монтирование в отдельный скрипт, а просто команду с маунтом вписать в скрипт бэкапа (перед командой переноса файлов на sftp, естественно). Но мне удобнее делать именно так.

Теперь, когда мы смонтировали sftp в /mnt/sftp/, можем осуществить ротацию бэкапов на sftp.
Для этого мы не будем использовать время создания/изменения. Все наши бэкапы сейчас имеют имена вида YY-MM-DD.name.backup, которые можно отсортировать и удалить лишнее.
Бэкапы должны складываться в отдельную папку, где ничего кроме них не будет лежать. Это важно! Иначе вы просто наудаляете лишнего. У нас эти бэкапы складываются в /mnt/sftp/mysql_backup/
Назовем его mysql_backup.sh:

#!/bin/bash
BACKUP_DATE=`date +%Y-%M-%D_%H:%M:%S`
 
mysqldump -u root --databases table1 > /mnt/sftp/mysql_backup/$BACKUP_DATE.mysql/$BACKUP_DATE.table1.sql
mysqldump -u root --databases table2 > /mnt/sftp/mysql_backup/$BACKUP_DATE.mysql/$BACKUP_DATE.table2.sql
mysqldump -u root --databases table3 > /mnt/sftp/mysql_backup/$BACKUP_DATE.mysql/$BACKUP_DATE.table3.sql

Теперь, когда мы смонтировали sftp в /mnt/sftp/ и скопировали туда свежие дампы, можем осуществить ротацию бэкапов.
Все наши бэкапы сейчас имеют имена вида YY-MM-DD.name.backup, которые можно отсортировать и удалить лишнее. Я хочу хранить 4 последние версии.
Пусть это будет скрипт с именем rotate_backup.sh и следующим содержанием:

#!/bin/bash
 
MAX_COPIES_COUNTER=4 # Количество версий, которое вы хотите хранить
DIRECTORY=/mnt/sftp/mysql_backup # Директория, в которой лежат бэкапы
 
COPIES_COUNTER=`ls $DIRECTORY | wc -l` # Считаем количество папок с бэкапами
 
if [ $COPIES_COUNTER -gt $MAX_COPIES_COUNTER ] # Если текущее количество больше, чем то, что мы хотим, то
then
NEED_TO_DELETE_COUNTER=$(($(ls $DIRECTORY | wc -l)-$MAX_COPIES_COUNTER)) # Считаем сколько необходимо удалить
for (( i==1; i<$NEED_TO_DELETE_COUNTER; i++ ))
do
rm -rf $DIRECTORY/$(ls $DIRECTORY | sort | head -n 1) # Выводим список, сортируем, удаляем лишнее начиная с самого давнего
done
fi

Теперь эти три скрипта необходимо добавить в крон. Сначала sshfs_mount.sh и mysql_backup.sh. И где-нибудь потом rotate_backup.sh.
Выполним

crontab -e

И внесем их в крон:

9 0 * * * /bin/bash /home/Lector/sshfs_mount.sh
10 0 * * * /bin/bash /home/Lector/mysql_backup.sh
10 1 * * * /bin/bash /home/Lector/rotate_backup.sh

Все)

Глава 10. Управление сервисами в systemd. 10.5 Управление systemd на удаленной машине

В дополнение к управлению системой systemd и диспетчером служб локально, утилита systemctl также позволяет вам взаимодействовать с systemd, работающим на удаленной машине по протоколу SSH. При условии, что служба sshd на удаленном компьютере запущена, вы можете подключиться к этому компьютеру, запустив команду systemctl с опцией -host или -H:

systemctl --host user_name@host_name command

Замените user_name именем удаленного пользователя, host_name именем удаленного хоста (или ip) и введите любую из команд systemctl из описанных в предыдущих главах. Обратите внимание, что на удаленном компьютере должен быть сконфигурирован ssh, чтобы разрешить удаленный доступ выбранному пользователю. Для получения информации о том, как настроить SSH-сервер, см. Chapter 12, OpenSSH.

Пример 10.16. Удаленное управление

Чтобы войти на удаленный компьютер server-01.example.com как пользователь root и определить текущий статус сервиса httpd.service, выполните следующую команду:

~]$ systemctl -H root@server-01.example.com status httpd.service
>>>>>>> systemd unit files -- update
root@server-01.example.com's password:
httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled)
   Active: active (running) since Fri 2013-11-01 13:58:56 CET; 2h 48min ago
 Main PID: 649
   Status: "Total requests: 0; Current requests/sec: 0; Current traffic:   0 B/sec"
   CGroup: /system.slice/httpd.service

Глава 10. Управление сервисами в systemd. 10.4 Выключение, приостановка и спящий режим

В RHEL 7 утилита systemctl заменила команды управления питанием из предыдущих версий дистрибутива. Команды, представленные в Таблице 10.8 “Сопоставление команд управления питанием с systemctl” также доступны в системе, но, по-возможности, рекомендуется использовать systemctl.

Таблица 10.7 Сопоставление команд управления питанием с systemctl
Старая команда Новая команда Описание
halt systemctl halt Останавливает систему
poweroff systemctl poweroff Выключает систему
reboot systemctl reboot Перезагружает систему
pm-suspend systemctl suspend Приостанавливает систему
pm-hibernate systemctl hibernate Отправляет систему в спящий режим
pm-suspend-hybrid systemctl hybrid-sleep Отправляет в спящий режим и приостанавливает систему

10.4.1.Выключение системы

Утилита systemctl предоставляет команды для выключения системы, однако традиционная команда shutdown также поддерживается. Хотя команда shutdown вызовет утилиту systemctl для выключения системы, она все же имеет преимущество т.к. поддерживает аргумент времени.
Это особенно полезно для планового обслуживания и дает пользователю время отреагировать на предупреждение системы о завершении работы. Преимуществом также является возможность отмены выключения.

Использование команды systemctl

Чтобы отключить систему и выключить машину введите в командной строке от root’а:

systemctl poweroff

Чтобы выключить и остановить систему без выключения компьютера, запустите следующую команду от root’а:

systemctl halt

По умолчанию каждая из этих команд заставляет systemd отправлять информационное сообщение всем пользователям, которые вошли в систему. Чтобы предотвратить отправку этого сообщения, запустите выбранную команду с опцией –no-wall, например:

systemctl --no-wall poweroff

Использование команды shutdown

Чтобы отключить систему и выключить машину в определенное время, выполните от root’а:

shutdown --poweroff hh:mm

Где hh:mm – время в 24-часовом формате. Ща 5 минут до выключения системы содается файл /run/nologin, который предоствращает вход в систему. При использовании аргумента времени можно добавить сообщение.
Чтобы выключить и остановить систему с задержкой, без отключения компьютера, используйте следующую команду от root:

shutdown --halt +m

Где +m время задержки до выключения в минутах. Вместо now можно также использовать +0. The now keyword is an alias for +0.
Ожидание завершения работы может быть отменено от root’а следующим образом:

shutdown -c

См. страницу мануала shutdown(8) (man shutdown), чтобы посмотреть дополнительные параметры команды.

10.4.2. Перезагрузка системы

Чтобы перезапустить систему, наберите от root’а:

systemctl reboot

По умолчанию эта команда заставляет systemd отправлять информационное сообщение пользователям, которые залогинены в системе. Чтобы предовратить отправку сообщения, выполните эту команду с опцией --no-wall:

systemctl --no-wall reboot

10.4.3. Приостановка системы

Чтобы приостановить систему, наберите от root’а:

systemctl suspend

Эта команда сохраняет состояние системы в ОЗУ и отключает большую часть устройств, за исключением модуля ОЗУ. Когда вы снова включаете машину, система восстанавливает свое состояние из ОЗУ без повторной загрузки. Поскольку состояние системы сохраняется в ОЗУ, а не на жестком диске, восстановление системы из режима приостановки значительно быстрее, чем восстановление ее из спящего режима, но, как следствие, состояние приостановленной системы также уязвимо для отключения питания.

10.4.4. Спящий режим

Чтобы отправить систему в спящий режим:

systemctl hibernate

Эта команда сохраняет состояние системы на жесткий диск и отключает машину. Когда вы включаете машину снова, система восстанавливает это состояние из сохраненных данных без повторной загрузки. Поскольку состояние системы сохраняется на жестком диске, а не в ОЗУ, машине не требуется электроэнергия для ОЗУ, но, как следствие, восстановление системы из спящего режима происходит значительно медленнее, чем восстановление из режима ожидания.
Чтобы отправить в спящий режим и приостановить систему, выполните от root’а:

systemctl hybrid-sleep

(Прим.пер. – я так понимаю, это своего рода перестраховка. Система приостановлена, но при сбое питания у нас есть сохраненное состояние системы на харде.)

Глава 10. Управление сервисами в systemd. 10.3 Работа с таргетами в systemd

Предыдущие версии RHEL, которые распространялись с SysV init или Upstart, включали предопределенный набор уровней запуска (ранлевелов), которые представляли собой конкретные режимы работы. Ранлевелы нумеровались от 0 до 6 и определяли набор системных сервисов, которые запускались когда системный администратор запускал определенный ранлевел. В RHEL7 концепция уровней запуска была заменена таргетами systemd.
Таргеты systemd представлены таргет-юнитами. Файлы этих юнитов имеют расширение .target и их предназначение в том, чтобы объединить другие юниты systemd в цепочку зависимостей. Например, юнит graphical.target, который используется для запуска графического интерфейса, запускает такие сервисы как GNOME Display Manager (gdm.service) или Accounts Service (accounts-daemon.service), а также активирует таргет multi-user.target. Аналогично, юнит multi-user.target запускает другие важные системные сервисы, такие как NetworkManager (NetworkManager.service) или D-Bus (dbus.service), и активирует другой таргет с именем basic.target.
RHEL распространяется с несколькими предопределенными таргетами, которые похожи на стандартные уровни выполнения предыдущих релизов системы. По соображениям совместимости он также предоставляет псевдонимы для этих таргетов, которые непосредственно отображают их на уровни запуска SysV. В таблице 10.6 «Сравнение уровней запуска SysV с таргетами systemd» представлен полный список уровней запуска SysV и соответствующих им таргетов.

Таблица 10.6 Сравнение уровней запуска SysV init с таргетами systemd
Ранлевел Таргет Описание
0 runlevel0.target, poweroff.target Завершение работы и отключение системы
1 runlevel1.target, rescue.target Оболочка восстановления
2 runlevel2.target, multi-user.target Многопользовательская система без графоболочки
3 runlevel3.target, multi-user.target Многопользовательская система без графоболочки
4 runlevel4.target, multi-user.target Многопользовательская система без графоболочки
5 runlevel5.target, graphical.target Многопользовательская система с графоболочкой
6 runlevel6.target, reboot.target Выключение и перезагрузка системы

Чтобы просмотреть, изменить или настроить таргеты systemd, используйте утилиту systemctl, как описано в таблице 10.7, «Сравнение команд SysV init с systemctl» и в следующих разделах. Команды runlevel и telinit по-прежнему доступны в системе и работают должным образом, но включены только по соображениям совместимости и их следует избегать.

Таблица 10.7 Сравнение команд SysV init с таргетами systemd
Старая команда Новая команда Описание
runlevel systemctl list-units –type target Список загруженных таргетов
telinit
runlevel
systemctl isolate name.target Смена текущего таргета

10.3.1. Просмотр таргета по умолчанию

Чтобы определить какой таргет используется по умолчанию, запустите следующую команду:

systemctl get-default

Эта команда читает симлинк, расположенный в /etc/systemd/system/default.target, и отображает результат. Для получения информации о том, как сменить таргет по умолчанию см. в разделе 10.3.3, “Смена таргета по умолчанию”. Для получения списка всех загруженных таргетов см. раздел 10.3.2,”Просмотр текущих таргетов”.
Пример 10.10. Просмотр таргета по умолчанию
Чтобы отобразить таргет по умолчанию, выполните:

~]$ systemctl get-default
graphical.target

10.3.2. Просмотр текущего таргета

Чтобы получить список загруженных таргетов, наберите следующую команду:

systemctl list-units --type target

Для каждого таргета эта команда отображает полное имя (UNIT), за ним следует примечание загружен ли юнит (LOAD), высокоуровневый (ACTIVE) и низкоуровневый (SUB) статус юнита, и краткое описание (DESCRIPTION).
По умолчанию команда systemctl list-units отображает только активные юниты. Если вы хотите просмотреть список всех загруженных юнитов независимо от их состояния, запустите эту команду с флагом --all или -a:

systemctl list-units --type target --all

Как сменить текущий таргет см. в разделе 10.3.4, “Смена текущего таргета”.

Пример 10.11. Просмотр текщего таргета

~]$ systemctl list-units --type target
UNIT                  LOAD   ACTIVE SUB    DESCRIPTION
basic.target          loaded active active Basic System
cryptsetup.target     loaded active active Encrypted Volumes
getty.target          loaded active active Login Prompts
graphical.target      loaded active active Graphical Interface
local-fs-pre.target   loaded active active Local File Systems (Pre)
local-fs.target       loaded active active Local File Systems
multi-user.target     loaded active active Multi-User System
network.target        loaded active active Network
paths.target          loaded active active Paths
remote-fs.target      loaded active active Remote File Systems
sockets.target        loaded active active Sockets
sound.target          loaded active active Sound Card
spice-vdagentd.target loaded active active Agent daemon for Spice guests
swap.target           loaded active active Swap
sysinit.target        loaded active active System Initialization
time-sync.target      loaded active active System Time Synchronized
timers.target         loaded active active Timers
 
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.
 
17 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.

10.3.3. Смена таргета по умолчанию

Чтобы сконфигурировать систему на использование другого таргета по умолчанию, выполните от root:

systemctl set-default name.target

Замените name на имя таргета, который вы хотите сделать дефолтным (например, multi-user). Эта команда заменяет файл /etc/systemd/system/default.target символической ссылкой на /usr/lib/systemd/system/name.target, где name это имя таргета, который вы хотите использовать. Как сменить текущий таргет см. в разделе 10.3.4, “Смена текущего таргета”. Как посмотреть информацию о текущем таргете, см. раздел 10.3.2,”Просмотр текущих таргетов”.

Пример 10.12. Смена таргета по умолчанию

Чтобы скофигурировать систему для использования multi-user.target по умолчанию, выполните от root:

~]# systemctl set-default multi-user.target
rm '/etc/systemd/system/default.target'
ln -s '/usr/lib/systemd/system/multi-user.target' '/etc/systemd/system/default.target'

10.3.4. Смена текущего таргета

Чтобы сменить таргет в текущей сессии, наберите от root:

systemctl isolate name.target

Замените name на имя таргета, который вы хотите использовать (например, multi-user). Эта команда запускает таргет с именем name и немедленно останавливает все остальные. Как сменить таргет по умолчанию см. раздел 10.3.3, “Смена таргета по умолчанию”. Как просмотреть список загруженных таргетов см. в разделе 10.3.2,”Просмотр текущих таргетов”.

Пример 10.13. Смена текущего таргета

Чтобы выключить графический интерфейс и сменить его на multi-user.target в текущей сессии, запустите от root:

~]# systemctl isolate multi-user.target

10.3.5. Переход в режим восстановления

Режим восстановления предоставляет однопользовательскую среду и позволяет восстановить систему в ситуациях, когда система не может завершить обычный процесс загрузки. В режиме восстановления система пытается смонтировать все локальные файловые системы и запустить некоторые системные сервисы, но не активирует сетевые интерфейсы и не позволяет одновременно входить нескольким пользователям в систему. В RHEL 7 режим восстановления эквивалентен однопользовательскому режиму и требует ввода рутового пароля.
Смена текущего таргета и переход в режим восстановления в текущей сессии (от root):

systemctl rescue

Этак команда похожа на systemctl isolate rescue.target, но она также отправляет информационное сообщение всем пользователям, которые в настоящее время вошли в систему. Чтобы система не отправляла сообщение, запустите команду с опцией --no-wall:

systemctl --no-wall rescue

Пример 10.14. Переход в режим восстановления

~]# systemctl rescue
Broadcast message from root@localhost on pts/0 (Fri 2013-10-25 18:23:15 CEST):
 
The system is going down to rescue mode NOW!

10.3.6. Переход в аварийный режим

Аварийный режим предоставляет минимально возможную среду и позволяет восстановить систему даже тогда, когда она не может загрузиться в режим восстановления. Система монтирует root file system только для чтения и запускает только несколько основных сервисов, не пытается подключить другие файловые системы и не активирует сеть. В RHEL 7 аварийный режим требует ввода пароля root’а.
Чтобы сменить текущий таргет на аварийный режим, введите от root’а:

systemctl emergency

Эта команда похожа на systemctl isolate emergency.target, но она дополнительно отправляет сообщение всем пользователям, которые в настоящее время вошли в систему. Чтобы система не отправляла сообщение, запустите команду с опцией --no-wall:

systemctl --no-wall emergency

Пример 10.15. Переход в аварийный режим
Чтобы перейти в аварийный режим с отправкой сообщения всем пользователям, запустите от root’а:

~]# systemctl --no-wall emergency