Управление пакетами и работающей службой

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

Введение

Установленный пакет, существующий файл конфигурации и отвечающая служба — разные результаты. Вы будете управлять каждым явно: установите и удалите утилиту, настроите nginx, объявите его рабочее состояние и перезагрузите изменённую конфигурацию через обработчик. Настоящие HTTP-ответы обоих управляемых узлов подтвердят работу службы.

Объявите состояния установки и отсутствия пакетов

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

Модуль apt управляет пакетами Ubuntu на управляемом хосте. Его state: present запрашивает установку, а state: absent — удаление. В этом окружении есть подготовленные списки пакетов и кэш загрузок, поэтому сохраняйте update_cache: false; обновление списков или запрос последних версий добавили бы ненужную зависимость от сети. Политики обновления в эксплуатации могут отличаться.

Перейдите в проект управляющего узла:

cd /home/labex/project

Создайте плейбук, в котором переменная выбирает желаемое состояние пакета tree. Операции с пакетами требуют become на целевых узлах. install_recommends: false исключает необязательные рекомендуемые пакеты.

cat > packages.yml <<'YAML'
- name: Declare a utility package state
  hosts: all
  gather_facts: false
  become: true
  vars:
    utility_state: present
  tasks:
    - name: Converge the tree package
      ansible.builtin.apt:
        name: tree
        state: "{{ utility_state }}"
        update_cache: false
        install_recommends: false
YAML

Установите утилиту:

ansible-playbook packages.yml

Команда tree отображает деревья каталогов; здесь её параметр версии демонстрирует, что исполняемый файл действительно установлен на каждом управляемом узле:

ansible all -m ansible.builtin.command -a 'tree --version'

Каждый целевой узел должен вернуть версию tree. Повторите плейбук; уже присутствующим пакетам не нужна ещё одна установка:

ansible-playbook packages.yml

Теперь запросите отсутствие через дополнительную переменную вместо редактирования многократно используемой задачи:

ansible-playbook packages.yml -e utility_state=absent

Повторите то же желаемое отсутствие. Теперь обе строки итога должны показывать changed=0, failed=0 и unreachable=0:

ansible-playbook packages.yml -e utility_state=absent

Состояние пакета — объявление об установке, а не доказательство, что служба запущена или отвечает. Оставьте tree отсутствующим, пока следующий шаг развёртывает nginx.

Настройте и запустите настоящую веб-службу

На этом шаге вы установите nginx, развернёте полную проверенную конфигурацию и явно сохраните его службу запущенной.

Два управляемых узла — контейнеры с отдельными конечными точками SSH и файловыми системами. В них не запущен systemd. Модуль service использует доступный им диспетчер служб; не выполняйте systemctl на этих целевых узлах. Мы будем управлять текущим рабочим состоянием, а не обещать политику загрузки systemd.

Создайте статическую страницу на управляющем узле. Она заканчивается переводом строки, чтобы точные управляемые байты были предсказуемы:

printf 'Ansible service ready\n' > page.txt

Напишите полную конфигурацию nginx. events и http — контексты верхнего уровня nginx, server определяет сайт, listen выбирает порт 8080, root выбирает каталог документов, а index — страницу для запросов /. Это настройки nginx, а не YAML Ansible.

cat > nginx-course.conf <<'NGINX'
events {}
http {
    server {
        listen 8080;
        root /var/www/ansible-site;
        index index.html;
    }
}
NGINX

Создайте плейбук развёртывания. Задача apt использует policy_rc_d: 101, чтобы установщик пакетов не запускал nginx неявно; последующая задача service явно объявляет рабочее состояние. Параметр validate задачи copy выполняет тест конфигурации nginx для временного кандидата (%s) перед заменой назначения.

Обработчик — именованное действие в handlers. Изменившаяся задача конфигурации уведомляет Reload nginx, который выполняется один раз в конце play. Нет изменения конфигурации — нет уведомления. Обычная задача service использует started, сохраняющий уже работающую службу запущенной без безусловного перезапуска.

cat > web.yml <<'YAML'
- name: Deploy a working web service
  hosts: all
  gather_facts: false
  become: true
  tasks:
    - name: Install nginx without refreshing the prepared package lists
      ansible.builtin.apt:
        name: nginx
        state: present
        update_cache: false
        install_recommends: false
        policy_rc_d: 101

    - name: Prepare the site directory
      ansible.builtin.file:
        path: /var/www/ansible-site
        state: directory
        owner: root
        group: root
        mode: "0755"

    - name: Deploy the static page
      ansible.builtin.copy:
        src: /home/labex/project/page.txt
        dest: /var/www/ansible-site/index.html
        owner: root
        group: root
        mode: "0644"

    - name: Validate and deploy nginx configuration
      ansible.builtin.copy:
        src: /home/labex/project/nginx-course.conf
        dest: /etc/nginx/nginx.conf
        owner: root
        group: root
        mode: "0644"
        validate: /usr/sbin/nginx -t -c %s
      notify: Reload nginx

    - name: Keep nginx running
      ansible.builtin.service:
        name: nginx
        state: started

  handlers:
    - name: Reload nginx
      ansible.builtin.service:
        name: nginx
        state: reloaded
YAML

Проверьте синтаксис, затем примените развёртывание:

ansible-playbook web.yml --syntax-check
ansible-playbook web.yml

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

curl — клиент HTTP. Его параметр --fail считает неуспешный статус HTTP сбоем команды; --silent убирает вывод хода работы, а --show-error сохраняет сведения об ошибках. Выполните его на каждом управляемом хосте для собственного петлевого интерфейса этого хоста:

ansible all -m ansible.builtin.command -a 'curl --fail --silent --show-error http://127.0.0.1:8080/'

Каждый результат должен содержать Ansible service ready. У управляющего и каждого целевого узла отдельные петлевые интерфейсы; эта команда проверяет обе целевые службы, а не управляющий узел.

Примените изменение конфигурации через обработчик

На этом шаге вы измените действующую настройку nginx, увидите обработчик и подтвердите настройку через HTTP-ответ.

Директива nginx server_tokens управляет тем, раскрывают ли заголовки ответа версию nginx. Добавьте server_tokens off внутри http, заменив конфигурацию управляющего узла этой полной версией:

cat > nginx-course.conf <<'NGINX'
events {}
http {
    server_tokens off;
    server {
        listen 8080;
        root /var/www/ansible-site;
        index index.html;
    }
}
NGINX

Примените тот же плейбук:

ansible-playbook web.yml

Копирование конфигурации должно сообщить changed и уведомить Reload nginx на обоих хостах. Обработчик перезагружает работающую службу после успешной проверки новой конфигурации. Его выполнение вводит конфигурацию в действие; простое копирование файла не подтверждает, что загрузил процесс.

Параметр curl -I запрашивает заголовки HTTP. Изучите фактический ответ службы на обоих хостах:

ansible all -m ansible.builtin.command -a 'curl --fail --silent --show-error -I http://127.0.0.1:8080/'

Оба ответа должны иметь успешный статус HTTP и заголовок Server со значением nginx без суффикса версии. Другие поля заголовков, например даты, меняются.

Повторите полный плейбук:

ansible-playbook web.yml

Оба хоста должны сообщить changed=0 без сбоев и недоступных задач, и обработчик перезагрузки не должен планироваться. Статическая страница остаётся доступной, tree — отсутствующим, а nginx — установленным и запущенным.

Резюме

Вы объявили присутствие и отсутствие пакетов, отделили установку от рабочего состояния службы и развернули полную конфигурацию nginx с проверкой кандидата. Изменённая конфигурация уведомила обработчик перезагрузки, настоящие ответы HTTP подтвердили действующее поведение, а повторный запуск без изменений избежал лишних изменений и перезагрузок.