Разгадываем Ansible Handlers: Обеспечение идемпотентной перезагрузки служб
Узнайте, как обработчики Ansible перезапускают или перезагружают службы только при изменении задач, с примерами для плейбуков, ролей и принудительного запуска обработчиков.
Демистификация обработчиков Ansible: обеспечение идемпотентных перезапусков служб
Обработчики Ansible решают распространенную проблему развертывания: ваш конфигурационный файл может проверяться при каждом запуске, но служба должна перезапускаться только при фактическом изменении этого файла. Без обработчиков ваш плейбук может перезапускать исправные службы без причины.
Это руководство объясняет, как работают обработчики, где их определять и когда запускать принудительно. В примерах используются веб-службы, но тот же шаблон применим к рабочим процессам приложений, планировщикам и системным демонам.
Что такое обработчики Ansible?
В Ansible обработчик — это задача, которая выполняется только после того, как другая задача уведомит ее. Когда задача изменяет что-то и включает notify, Ansible ставит в очередь соответствующий обработчик.
Ключевые характеристики обработчиков:
- Запускаются по уведомлению: Обработчик выполняется, когда измененная задача использует
notify. - Выполняются один раз за плей: Если пять задач уведомляют один и тот же обработчик, Ansible все равно запускает его один раз в конце плея.
- Лучше всего подходят для перезапусков и перезагрузок: Обработчики идеальны для действий со службами, которые должны происходить только после изменений конфигурации.
Зачем использовать обработчики для перезапуска служб?
Основной вариант использования обработчиков Ansible — управление службами. Когда вы обновляете конфигурационный файл Apache, Nginx или приложения, службу часто нужно перезапустить или перезагрузить. Вы хотите выполнять это действие только тогда, когда развернутый файл отличается от текущего.
Рассмотрим альтернативу:
- Без обработчиков: Прямая задача перезапуска выполняется каждый раз, когда плейбук доходит до нее, если не добавить дополнительные условия.
- С обработчиками: Задача шаблона или копирования уведомляет о перезапуске только тогда, когда сообщает об изменении.
Например, производственный плейбук Nginx может запускаться каждый час для устранения дрейфа конфигурации. С обработчиками неизмененные конфигурационные файлы не вызывают ежечасных перезагрузок.
Как реализовать обработчики Ansible
Обработчики находятся в разделе handlers в плейбуке или в handlers/main.yml внутри роли. Имя обработчика должно совпадать с именем, используемым notify.
Базовый синтаксис обработчика
Обработчики объявляются в блоке handlers на уровне плейбука или внутри роли.
---
- name: Настроить и перезапустить веб-сервер
hosts: webservers
become: yes
tasks:
- name: Убедиться, что конфигурация Apache присутствует
template:
src: templates/httpd.conf.j2
dest: /etc/httpd/conf/httpd.conf
notify:
- Перезапустить Apache
handlers:
- name: Перезапустить Apache
service:
name: httpd
state: restarted
В этом примере:
- Задача
templateиспользуется для развертывания нового конфигурационного файла Apache (httpd.conf). - Ключевое слово
notifyустановлено вПерезапустить Apache. Это означает, что если задачаtemplateуспешно изменит файлhttpd.conf, Ansible подаст сигнал обработчику с именемПерезапустить Apache. - Раздел
handlersопределяет обработчикПерезапустить Apache, который использует модульserviceдля перезапуска службыhttpd.
Уведомление нескольких обработчиков
Одна задача может уведомлять несколько обработчиков. Это полезно, если изменение одной конфигурации требует перезапуска нескольких служб или выполнения нескольких действий по очистке.
---
- name: Развернуть приложение с обновлениями базы данных и веб-сервера
hosts: app_servers
become: yes
tasks:
- name: Обновить конфигурацию приложения
copy:
src: files/app.conf
dest: /etc/app/app.conf
notify:
- Перезапустить службу приложения
- Перезагрузить Nginx
handlers:
- name: Перезапустить службу приложения
service:
name: myapp
state: restarted
- name: Перезагрузить Nginx
service:
name: nginx
state: reloaded
В этом сценарии, если app.conf обновлен, будут запущены оба обработчика: Перезапустить службу приложения и Перезагрузить Nginx.
Использование обработчиков в ролях
Обработчики обычно используются в ролях Ansible. Они определяются в файле handlers/main.yml роли. Когда задача внутри роли (или из плейбука, который включает роль) уведомляет обработчик, определенный в роли, Ansible выполнит его.
Предположим, у вас есть роль с именем apache со следующей структурой:
apache/
├── handlers/
│ └── main.yml
└── tasks/
└── main.yml
apache/tasks/main.yml:
---
- name: Развернуть конфигурацию Apache
template:
src: httpd.conf.j2
dest: /etc/httpd/conf/httpd.conf
notify:
- Перезапустить Apache
apache/handlers/main.yml:
---
- name: Перезапустить Apache
service:
name: httpd
state: restarted
Затем в вашем плейбуке вы включите роль:
---
- name: Настроить веб-сервер с использованием роли Apache
hosts: webservers
become: yes
roles:
- apache
Когда задача Развернуть конфигурацию Apache в роли apache выполняется и изменяет конфигурацию, будет запущен обработчик Перезапустить Apache, определенный в apache/handlers/main.yml.
Лучшие практики использования обработчиков
- Держите каждый обработчик сосредоточенным на одном действии.
- Используйте имена, соответствующие действию, например
Перезагрузить Nginx. - Предпочитайте
state: reloaded, когда служба поддерживает перезагрузки и полный перезапуск не требуется. - Избегайте прямых задач перезапуска после задач конфигурации.
- Помните, что уведомленные обработчики выполняются в конце плея, если вы не запустите их принудительно.
Продвинутые концепции: принудительный запуск обработчиков
По умолчанию обработчики выполняются один раз в конце плея. Иногда вам нужен перезапуск до того, как продолжатся последующие задачи. Например, вам может потребоваться перезапустить приложение после записи его основной конфигурации перед запуском проверки работоспособности или миграции.
---
- name: Выполнить последовательные обновления конфигурации, требующие немедленного перезапуска служб
hosts: servers
become: yes
tasks:
- name: Обновить основной конфигурационный файл
copy:
src: files/primary.conf
dest: /etc/myapp/primary.conf
notify:
- Перезапустить Myapp
- name: Принудительно запустить обработчики для немедленного перезапуска
meta: flush_handlers
- name: Обновить вторичный конфигурационный файл
copy:
src: files/secondary.conf
dest: /etc/myapp/secondary.conf
notify:
- Перезапустить Myapp
handlers:
- name: Перезапустить Myapp
service:
name: myapp
state: restarted
Здесь первое изменение конфигурации запускает Перезапустить Myapp, а meta: flush_handlers выполняет его немедленно. Последующая задача может снова уведомить тот же обработчик, если изменит другой файл.
Когда обращаться к профессионалу
Попросите о проверке, когда обработчик перезапускает производственные базы данных, балансировщики нагрузки или кластерные службы. Некоторые системы требуют поэтапных перезапусков, проверок кворума или этапов отключения, которые не должны быть скрыты за простым обработчиком.
Вывод
Используйте обработчики Ansible всякий раз, когда измененная задача должна запускать перезапуск службы, перезагрузку или перезагрузку демона. Они сохраняют ваши плейбуки идемпотентными, уменьшают ненужные перезапуски и упрощают анализ изменений служб.