Гид по технологиям

Как управлять серверами с Rex — лучшие практики

5 min read Инфраструктура Обновлено 09 Nov 2025
Управление серверами с Rex — лучшие практики
Управление серверами с Rex — лучшие практики

О чем эта статья

Эта инструкция шаг за шагом показывает, как структурировать код задач Rex, хранить общие модули в репозиториях и применять их к разным проектам (в примере — «website» и «database»). Примеры используют Subversion, Ubuntu и стандартные конфигурации Apache/MySQL/NTP. Кодовые фрагменты и пути к файлам сохранены без изменений.

Важно: примеры команд показаны без sudo — выполняйте их с правами, соответствующими вашей среде.

Ключевые варианты поиска (SEO):

  • Управление серверами Rex
  • Rex оркестрация и конфигурация
  • Rex best practices
  • Rex задачи и модули
  • Хранение задач Rex в SCM

Введение в Rex

Rex — это инструмент оркестрации и управления конфигурацией. С Rex вы управляете всеми серверами централизованно: описываете задачи (tasks) в Perl и исполняете их по SSH на удалённых хостах. По сути, Rex похож на Make для инфраструктуры: есть центральный Rexfile и набор задач, сгруппированных по модулям и неймспейсам.

Сайт проекта: http://rexify.org/.

Префейс — используемые роли и серверы

В примерах используются следующие серверы:

  • Subversion server: svn01
  • Database Server: db01
  • Web Server: web01
  • Workstation: wks01

Я использую Subversion для управления задачами и шаблонами, но вы можете применять любую систему контроля версий, поддерживающую аналогичный механизм внешних ссылок (externals).

Установка репозиториев кода (Subversion)

Выполните на Subversion-сервере установку необходимых пакетов:

svn01# apt-get install libapache2-svn subversion apache2-mpm-prefork

Отредактируйте /etc/apache2/mods-enabled/dav_svn.conf, заменив содержимое следующим блоком:


  DAV svn
  SVNParentPath /var/lib/svn
  AuthType Basic
  AuthName "Subversion Repository"
  AuthUserFile /etc/apache2/dav_svn.passwd
  
    Require valid-user
  

Создайте директории и репозитории:

svn01# mkdir /var/lib/svn  
svn01# cd /var/lib/svn  
svn01 /var/lib/svn# svnadmin create common  
svn01 /var/lib/svn# svnadmin create service  
svn01 /var/lib/svn# svnadmin create database  
svn01 /var/lib/svn# svnadmin create website  
svn01 /var/lib/svn# chown -R www-data: .

Настройте аутентификацию Apache и перезапустите сервис:

svn01# htpasswd -c /etc/apache2/dav_svn.passwd your-user-name
svn01# service apache2 restart

Теперь сервер Subversion готов. Переходим на рабочую станцию для чекаута репозиториев.

Чекаут репозиториев и написание задач

На рабочей станции выполните:

wks01# svn co http://svn01/svn/common Common  
wks01# svn co http://svn01/svn/service Service  
wks01# svn co http://svn01/svn/database  
wks01# svn co http://svn01/svn/website

Общая задача: NTP

Создадим общий модуль для настройки NTP. Перейдите в Common и создайте файл NTP.pm:

wks01# cd Common
# Common/NTP.pm
package Common::NTP;
use Rex -base;
task prepare => sub {
   install "ntp";
   file "/etc/ntp.conf",
      source => "files/ntp.conf",
      on_change => sub {
         service ntp => "restart";
      };
};
1;

Этот task «prepare» в неймспейсе NTP устанавливает пакет ntp и загружает конфигурационный файл. При изменении файла сервис перезапускается.

Создайте папку для файлов и добавьте ntp.conf:

bash Common# mkdir files

Содержимое files/ntp.conf (простой дефолтный файл):

# /etc/ntp.conf, managed with rex
driftfile /var/lib/ntp/ntp.drift
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
server 0.ubuntu.pool.ntp.org
server 1.ubuntu.pool.ntp.org
server 2.ubuntu.pool.ntp.org
server 3.ubuntu.pool.ntp.org
# Use Ubuntu's ntp server as a fallback.
server ntp.ubuntu.com
restrict -4 default kod notrap nomodify nopeer noquery
restrict -6 default kod notrap nomodify nopeer noquery
# Local users may interrogate the ntp server more closely.
restrict 127.0.0.1
restrict ::1

Добавьте и зафиксируйте изменения в репозитории:

wks01 Common# svn add NTP.pm files  
wks01 Common# svn ci -m "added NTP task"

Сервисные модули: Apache и MySQL

Перейдем в репозиторий Service и создадим модули Apache и MySQL:

wks01 Common# cd ../Service  
wks01 Service# touch Apache.pm MySQL.pm

Содержимое Apache.pm:

package Service::Apache;
use Rex -base;
task prepare => sub {
   install "apache2";
};
task configure => sub {
   my $param = shift;
   file "/etc/apache2/apache2.conf",
      owner => "root",
      mode => 644,
      content => template("templates/apache2/apache2.conf.tpl", %{ $param });
   file "/etc/apache2/conf.d/security",
      owner => "root",
      mode => 644,
      content => template("templates/apache2/conf.d/security.tpl", %{ $param });
};
1;

Создаём каталоги для шаблонов:

wks01 Service# mkdir -p templates/apache2/conf.d

Шаблон templates/apache2/apache2.conf.tpl:

LockFile /var/run/apache2/accept.lock
PidFile /var/run/apache2.pid
Timeout <%= is_defined($::timeout, "300") %>
KeepAlive <%= is_defined($::keepalive, "On") %>
MaxKeepAliveRequests <%= is_defined($::max_keepalive_requests, "100") %>
KeepAliveTimeout <%= is_defined($::keepalive_timeout, "5") %>

    StartServers          5
    MinSpareServers       5
    MaxSpareServers      10
    MaxClients          150
    MaxRequestsPerChild   0


    StartServers          2
    MinSpareThreads      25
    MaxSpareThreads      75 
    ThreadLimit          64
    ThreadsPerChild      25
    MaxClients          150
    MaxRequestsPerChild   0


    StartServers          2
    MinSpareThreads      25
    MaxSpareThreads      75 
    ThreadLimit          64
    ThreadsPerChild      25
    MaxClients          150
    MaxRequestsPerChild   0

User <%= is_defined($::user, "www-data") %>
Group <%= is_defined($::group, "www-data") %>

AccessFileName .htaccess

    Order allow,deny
    Deny from all
    Satisfy all

DefaultType None

HostnameLookups <%= is_defined($::hostname_lookups, "Off") %>
ErrorLog <%= is_defined($::error_log, "/var/log/apache2/error.log") %>
LogLevel <%= is_defined($::log_level, "warn") %>
Include mods-enabled/*.load
Include mods-enabled/*.conf
Include httpd.conf
Include ports.conf
LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent

Include conf.d/
Include sites-enabled/

Шаблон templates/apache2/conf.d/security.tpl:

ServerTokens <%= is_defined($::server_tokens, "Prod") %>
ServerSignature <%= is_defined($::server_signature, "Off") %>
TraceEnable <%= is_defined($::trace_enable, "Off") %>

Модуль Service::MySQL в MySQL.pm:

package Service::MySQL;
use Rex -base;
task prepare => sub {
   install "mysql-server";
};
task configure => sub {
   my $param = shift;
   file "/etc/mysql/my.cnf",
      owner => "root",
      mode => 644,
      content => template("templates/mysql/my.cnf.tpl", %{ $param });
};
1;

Шаблон templates/mysql/my.cnf.tpl:

[mysqld]
user     = <%= is_defined($::user, "mysql") %>
pid-file = /var/run/mysqld/mysqld.pid
socket      = /var/run/mysqld/mysqld.sock
port     = <%= is_defined($::port, "3306") %>
basedir     = /usr
datadir     = /var/lib/mysql
tmpdir      = /tmp
lc-messages-dir   = /usr/share/mysql
skip-external-locking
bind-address      = <%= $::eth0_ip %>
key_buffer     = <%= is_defined($::key_buffer, "16M") %>
max_allowed_packet   = <%= is_defined($::max_allowed_packet, "16M") %>
thread_stack      = <%= is_defined($::thread_stack, "192K") %>
thread_cache_size       = <%= is_defined($::thread_cache_size, "8") %>
myisam-recover         = BACKUP
query_cache_limit = <%= is_defined($::query_cache_limit, "1M") %>
query_cache_size        = <%= is_defined($::query_cache_size, "16M") %>
expire_logs_days  = <%= is_defined($::expire_logs_days, "10") %>
max_binlog_size         = <%= is_defined($::max_binlog_size, "100M") %>

[mysqldump]
quick
quote-names
max_allowed_packet   = <%= is_defined($::max_allowed_packet, "16M") %>
[mysql]
[isamchk]
key_buffer     = <%= is_defined($::key_buffer, "16M") %>
!includedir /etc/mysql/conf.d/

Добавьте и зафиксируйте файлы Service:

wks01 Service# svn add *  
wks01 Service# svn ci -m "inital commit of apache and mysql service"

Теперь у вас есть общие модули. Дальше вы можете создавать проектные задачи для database и website, используя общие модули.

Методология: как структурировать репозитории и модули

  • common — переиспользуемые модули (NTP, users, monitoring). Должны быть стабильными и версионируемыми.
  • service — сервисные модули (apache, mysql, redis). Содержат шаблоны и параметры.
  • project (website/database) — проекты, которые объявляют зависимости на common и service и содержат специфичные задачи и конфигурации.
  • Используйте шаблоны для конфигураций и передавайте параметры через hash/параметры задач.

Совет: разделяйте обязательные (install/configure) и описательные (deploy) задачи. Делайте задачи идемпотентными.

Чек-листы по ролям

Администратор инфраструктуры (Ops):

  • Проверить доступность SSH ключей и прав доступа.
  • Настроить и протестировать репозитории SCM.
  • Подключить common-модули к проектам через externals или submodules.
  • Проверить idempotency задач на тестовом хосте.

DBA:

  • Протестировать шаблон my.cnf с ожидаемыми параметрами.
  • Запустить configure task на стенде и проверить логи.
  • Описать требования к бэкапу и рестору в отдельном task.

Разработчик/Deploy инженер:

  • Убедиться, что deploy-task не перезаписывает runtime-конфиг без флага.
  • Подготовить параметризованный Rexfile для разных окружений.

Критерии приёмки

  • Задачи idempotent: повторный запуск не вносит изменений без необходимости.
  • Конфигурации генерируются из шаблонов и параметров проекта.
  • После выполнения prepare/configure сервисы корректно запускаются и в логах нет ошибок.
  • Процедуры отката документированы и протестированы (см. playbook ниже).

Playbook (SOP) — быстрый сценарий деплоя изменений конфигурации

  1. Локально: написать/обновить модуль и шаблон.
  2. Закоммитить в ветку/репозиторий и создать merge request.
  3. На тестовом сервере выполнить rex task и проверить результат.
  4. При успешном тестировании запустить на стенде pre-prod, провести smoke tests.
  5. Планировать окно для prod и уведомить заинтересованные стороны.
  6. Выполнить в prod, параллельно мониторить сервисы и логи.
  7. При проблемах — выполнить rollback (описано ниже).

Критическая рекомендация: тестируйте откат для любых изменения в конфиге БД или сети.

Откат/инцидентный план (Runbook)

  • Если конфигурация привела к недоступности сервиса:
    1. Применить предыдущий рабочий шаблон (хранится в SCM) через rex task.
    2. Перезапустить сервис и проверить логи.
    3. Если сервис не поднимается — восстановить из бэкапа конфигов и данных.

Когда Rex не подходит (контрпримеры)

  • Если требуется управление инфраструктурой без SSH (например, agent-based only), Rex может быть неудобен.
  • Для огромной инфраструктуры с централизованным inventory и привязкой к облачным API удобнее использовать инструменты, оптимизированные под облако (иногда Terraform + провайдеры конфигурации).
  • Если ваша команда преимущественно не знакома с Perl и не готова его поддерживать, рассмотрите YAML/DSL-ориентированные инструменты.

Альтернативные подходы

  • Ansible — похож по принципу agentless SSH, но использует YAML и имеет широкую экосистему ролей.
  • Puppet/Chef — agent-based и декларативные конфигурации, подходят для больших инфраструктур.
  • Salt — гибридный подход с REST и агентами.

Выбор зависит от навыков команды, требований к idempotency, интеграции с CMDB и облачными провайдерами.

Краткий глоссарий (1 строка)

  • task: единица работы в Rex, выполняемая на хосте через SSH.
  • namespace: пространство имён модуля (например, Common::NTP).
  • template: ERB-подобный шаблон для генерации конфигов.

Вывод

Rex — удобный инструмент для команд, которым нужен лёгкий, SSH-ориентированный менеджер задач с возможностью писать модули на Perl. Приведённая структура репозиториев и шаблонов помогает разделять обязанности и переиспользовать код. Тестируйте idempotency, документируйте playbook и имейте план отката.

Важно: адаптируйте примеры под вашу систему управления версиями (Git тоже хорошая альтернатива) и корпоративные процессы.


Полезные ссылки

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Троян Herodotus: как он действует и как защититься
Кибербезопасность

Троян Herodotus: как он действует и как защититься

Включить новое меню «Пуск» в Windows 11
Windows 11

Включить новое меню «Пуск» в Windows 11

Панель полей PivotTable в Excel — руководство
Excel

Панель полей PivotTable в Excel — руководство

Включить новый Пуск в Windows 11 — инструкция
Windows

Включить новый Пуск в Windows 11 — инструкция

Дубликаты Диспетчера задач в Windows 11 — как исправить
Windows

Дубликаты Диспетчера задач в Windows 11 — как исправить

Как посмотреть историю просмотров Reels в Instagram
Социальные сети

Как посмотреть историю просмотров Reels в Instagram