Управление службами с помощью обработчиков (Handlers)

AnsibleBeginner
Практиковаться сейчас

Введение

Обработчики (Handlers) — это специальные задачи Ansible, которые выполняются только в том случае, если их вызывает другая задача, зафиксировавшая изменения. Они обычно используются для перезагрузки конфигураций и перезапуска служб.

В этой лабораторной работе вы развернете безопасный демонстрационный юнит-файл systemd, настроите вызов обработчиков при изменении файла и убедитесь, что служба активна и включена в автозагрузку.

Создание проекта автоматизации служб

На этом этапе вы создадите проект для автоматизации управления службами. В этой лабораторной работе используется один локальный псевдоним хоста, так как служба будет управлять реальным состоянием системы на виртуальной машине RHEL 10.

cd /home/labex/project
mkdir -p rhce-ansible/{inventory,files,playbooks,reports}
cd rhce-ansible
cat > ansible.cfg <<'EOF'
[defaults]
inventory = ./inventory/hosts
host_key_checking = False
retry_files_enabled = False
EOF
cat > inventory/hosts <<'EOF'
[service_hosts]
host ansible_connection=local
EOF

Даже при использовании локального подключения плейбук будет управлять реальным состоянием systemd на виртуальной машине. Именно поэтому в данной работе используется один псевдоним хоста и параметр become: true в дальнейшем, вместо имитации нескольких независимых хостов со службами.

Создание демонстрационного юнит-файла systemd

На этом этапе вы создадите исходный юнит-файл, который Ansible скопирует в /etc/systemd/system. Служба будет запускать /usr/bin/sleep infinity, что делает её безопасной и простой для проверки. Перед выполнением команд на этом этапе вернитесь в каталог проекта Ansible. Это обеспечит стабильность выполнения команд, даже если LabEx запускает каждый шаг отдельно.

cd /home/labex/project/rhce-ansible
cat > files/rhce-handler-demo.service <<'EOF'
[Unit]
Description=RHCE handler demo service

[Service]
Type=simple
ExecStart=/usr/bin/sleep infinity
Restart=always
RestartSec=1

[Install]
WantedBy=multi-user.target
EOF

Этот юнит намеренно безвреден: он запускает длительный процесс sleep и перезапускает его в случае завершения. Секция [Install] позволяет Ansible включить службу для цели multi-user.target.

sed -n "1,12p" files/rhce-handler-demo.service

Перед продолжением проверьте строки ExecStart и WantedBy. Если исходный юнит-файл будет содержать ошибки, Ansible точно так же развернет неверное определение службы.

Написание плейбука с обработчиками

На этом этапе вы напишете плейбук, который копирует юнит-файл и вызывает обработчики. Задача meta: flush_handlers выполняет ожидающие обработчики перед задачей управления службой, чтобы systemd узнал о новом юните. Перед выполнением команд на этом этапе вернитесь в каталог проекта Ansible.

cd /home/labex/project/rhce-ansible
cat > playbooks/manage-service.yml <<'EOF'
---
- name: Deploy and manage the demo service
  hosts: service_hosts
  become: true
  gather_facts: false
  tasks:
    - name: Install demo systemd unit
      ansible.builtin.copy:
        src: ../files/rhce-handler-demo.service
        dest: /etc/systemd/system/rhce-handler-demo.service
        mode: '0644'
      notify:
        - Reload systemd
        - Restart demo service

    - name: Run handlers before enabling the service
      ansible.builtin.meta: flush_handlers

    - name: Ensure demo service is active and enabled
      ansible.builtin.systemd:
        name: rhce-handler-demo.service
        state: started
        enabled: true

  handlers:
    - name: Reload systemd
      ansible.builtin.systemd:
        daemon_reload: true

    - name: Restart demo service
      ansible.builtin.systemd:
        name: rhce-handler-demo.service
        state: restarted
EOF

Задача copy вызывает два обработчика только при изменении юнит-файла. meta: flush_handlers запускает все ожидающие обработчики до того, как задача systemd начнет запуск и включение службы, что критически важно, так как systemd должен перезагрузить конфигурацию юнитов, прежде чем он узнает о новой службе.

ansible-playbook playbooks/manage-service.yml --syntax-check

Проверка синтаксиса должна пройти успешно до того, как плейбук начнет запись в /etc/systemd/system. Это позволит выявить ошибки отступов в списке задач и секции handlers, не затрагивая состояние службы.

Запуск плейбука и проверка службы

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

cd /home/labex/project/rhce-ansible
ansible-playbook playbooks/manage-service.yml | tee reports/service-first-run.txt

Первый запуск должен скопировать юнит-файл, перезагрузить systemd, перезапустить демонстрационную службу через обработчик, а затем убедиться, что служба включена. Сохранение вывода позволит вам проверить, сработал ли путь выполнения обработчика.

systemctl is-active rhce-handler-demo.service
systemctl is-enabled rhce-handler-demo.service

is-active проверяет состояние выполнения в текущей сессии загрузки, а is-enabled проверяет, добавлена ли служба в автозагрузку. Задачи RHCE по управлению службами часто требуют проверки обоих параметров.

Изменение юнит-файла и повторный вызов обработчика

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

cd /home/labex/project/rhce-ansible

Модуль lineinfile также может редактировать локальные файлы с помощью ad-hoc команды. Здесь он изменит только одну строку в исходном юнит-файле.

ansible localhost -c local -m ansible.builtin.lineinfile -a 'path=files/rhce-handler-demo.service regexp=^RestartSec= line=RestartSec=3'

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

ansible-playbook playbooks/manage-service.yml | tee reports/service-second-run.txt
grep -F RestartSec /etc/systemd/system/rhce-handler-demo.service

Установленный юнит теперь должен содержать RestartSec=3. Служба должна оставаться активной и включенной, так как обработчики перезагрузили systemd и перезапустили демонстрационную службу после изменения файла.

Резюме

Вы развернули безопасный юнит systemd, использовали обработчики для перезагрузки systemd и перезапуска службы, проверили состояние активности и включения службы, а также вызвали обработчик с помощью контролируемого изменения юнит-файла.