ADG Оставить заявку
Блог Системное администрирование 5 мин чтения

CentOS 7 на продакшне: шпаргалка по systemd для тех, кто вырос на RHEL 6

Перевели первый продакшн-сервер на CentOS 7. Самое непривычное - journald и systemctl. Собрали шпаргалку equivalents для команд RHEL 6.

Контекст момента

CentOS 7 с systemd требует переобучения администраторов: service/chkconfig и syslog заменены на systemctl и journald

В июле мы переносили init.d-скрипты на systemd units на тестовом стенде. Теперь первый боевой сервер клиента из управляемой инфраструктуры реально работает на CentOS 7 в продакшне. Разница между «разобрались на стенде» и «объясняешь коллеге в 23:00 почему service nginx restart не работает» - ощутимая.

Не то чтобы systemd сложный. Он просто другой. И мышечная память, выращенная на RHEL 6, работает против тебя первые несколько недель.

Откуда шпаргалка

Поводом стало конкретное происшествие. Один из администраторов работал с новым сервером, заметил что сервис не стартовал, и потратил минут двадцать прежде чем вспомнил что /etc/init.d/ на этой машине пустой, а chkconfig --list выдаёт половину юнитов и молчит про остальные. Это не его вина - просто на CentOS 7 половина привычных команд либо не работает, либо работает через слой совместимости и даёт неполную картину.

После того случая мы сели и составили таблицу equivalents: что было в RHEL 6 - что делать в CentOS 7. Теперь она висит в нашей внутренней Wiki и помогает при переключении между серверами разных поколений.

Управление сервисами: systemctl вместо service и chkconfig

Базовые операции с сервисами:

  • Запустить/остановить/перезапустить. Было service nginx start / service nginx stop / service nginx restart. Стало systemctl start nginx / systemctl stop nginx / systemctl restart nginx.
  • Статус. Было service nginx status. Стало systemctl status nginx - и это объективно лучше: показывает последние строки из лога прямо в выводе, PID, время запуска, cgroup.
  • Включить автозапуск. Было chkconfig nginx on. Стало systemctl enable nginx. Файл symlink создаётся в /etc/systemd/system/.
  • Отключить автозапуск. Было chkconfig nginx off. Стало systemctl disable nginx.
  • Проверить включён ли автозапуск. Было chkconfig --list nginx. Стало systemctl is-enabled nginx.
  • Список всех сервисов. Было chkconfig --list. Стало systemctl list-units --type=service - показывает все загруженные юниты с их состоянием.
  • Перечитать конфиг без рестарта. Было service nginx reload. Стало systemctl reload nginx - если юнит поддерживает ExecReload, иначе systemctl reload-or-restart.

Отдельный нюанс: systemctl restart nginx и systemctl reload nginx - разные вещи. Reload - это SIGHUP или специфичный для приложения механизм перечитать конфиг без остановки. Restart - это stop + start. В RHEL 6 это тоже было разграничено, но в команде service легко перепутать, потому что слово «reload» звучит похоже на «restart». В systemctl разграничение нагляднее.

Журналы: journald вместо /var/log/messages

Вот здесь непривычность сильнее всего. На RHEL 6 всё шло в /var/log/messages через syslog, и типичный сеанс диагностики выглядел как tail -f /var/log/messages или grep "nginx" /var/log/messages. Файл, строки, grep - понятно и предсказуемо.

На CentOS 7 journald собирает логи в бинарный журнал, и читать его надо через journalctl:

  • Все логи за последний час. journalctl --since "1 hour ago"
  • Логи конкретного юнита. journalctl -u nginx - и это главная команда, которую используем чаще всего.
  • Следить в реальном времени. journalctl -u nginx -f - аналог tail -f, только для конкретного сервиса.
  • Последние N строк. journalctl -u nginx -n 50
  • Логи с момента последнего запуска. journalctl -u nginx -b - показывает только с текущей загрузки, чтобы не листать старое.
  • Логи по PID. journalctl _PID=1234
  • Уровень важности. journalctl -p err - только ошибки и выше.

Первые дни команду journalctl -u <имя-юнита> -n 100 приходилось вспоминать вместо привычного grep. Но она реально удобнее: логи сразу отфильтрованы по конкретному сервису, не надо вычищать строки от других процессов.

Одно ограничение, на которое наткнулись: по умолчанию journald хранит логи в памяти (/run/log/journal/) и они не переживают перезагрузку. Чтобы журнал сохранялся на диске между ребутами, нужно создать директорию /var/log/journal/ - тогда journald сам начнёт туда писать. Делаем это сразу при настройке нового сервера.

Что ещё поменялось

Несколько вещей помимо systemctl и journald, которые сбивают с толку:

  • Firewall. В RHEL 6 - iptables + service iptables save. В CentOS 7 по умолчанию стоит firewalld, управляется через firewall-cmd. Синтаксис другой, логика зон вместо прямых правил. Мы на некоторых серверах отключаем firewalld и ставим iptables-services - там где конфигурация уже выверена и нет смысла переписывать.
  • Сетевые интерфейсы. Именование изменилось: вместо eth0 теперь что-то вроде eno1 или enp2s0 - predictable network interface names. Это ломает скрипты, которые хардкодят eth0. Находили такое в нескольких bash-скриптах клиентов.
  • Hostname. Команда hostname осталась, но для постоянного изменения теперь hostnamectl set-hostname. Запись напрямую в /etc/hostname тоже работает, но hostnamectl делает всё в одном месте.
  • netstat. Пакет net-tools не установлен по умолчанию. netstat -tulpn надо заменить на ss -tulpn из пакета iproute. Функционально почти одинаково, синтаксис чуть другой.

Где сейчас

Шпаргалка в нашей Wiki уже помогла нескольким раз - не только новым людям, но и опытным администраторам при переключении между серверами. CentOS 6 и 7 сейчас существуют одновременно в инфраструктуре, и постоянно держать в голове оба набора команд неудобно.

Самое ценное наблюдение после месяца на боевом сервере: journald с journalctl -u <сервис> реально удобнее чем grep по /var/log/messages. Это не уступка, это улучшение. А вот firewalld пока вызывает скорее раздражение - возможно просто потому что iptables выучен до автоматизма, и новая абстракция добавляет трение там, где его не ожидаешь.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.