mysurik.ru

Ansible на домашнем сервере: я забыл про ручные правки

У меня три домашних сервера, и до недавнего времени каждый жил своей жизнью: свои правки конфигов, свои особенности, своя документация где-то в заметках. Когда понадобилось поднять четвёртый, я поймал себя на мысли: я же уже делал всё это. Так я познакомился с Ansible для домашнего сервера — и через месяц забыл, где у машин лежат конфиги, потому что они больше там не живут. Делюсь опытом внедрения без корпоративной пафосности.

Звучит как инструмент для сисадминов больших парков? Отчасти. Но домашней лаборатории он нужен даже сильнее: дома нет коллеги, который помнит, как всё настроено. Помните только вы. А лучше пусть помнит плейбук.

Что такое Ansible простыми словами и зачем он дома

Суть в двух предложениях. Вы описываете желаемое состояние серверов в текстовых файлах, которые называются плейбуками, а Ansible сам доводит машины до этого состояния по SSH. Без агентов на серверах, без баз данных — только Python на управляющей машине и SSH-доступ, которые у меня и так есть.

Домашнему администратору это даёт три вещи. Первая: воспроизводимость — новый или переустановленный сервер приводится к бою за минуты. Вторая: документация и настройка перестают быть разными вещами, плейбук и есть документация. Третья: страх что-нибудь сломать при правке исчезает, потому что изменение сначала проверяется на одной машине, а потом раскатывается на остальные.

Первый плейбук: мой базовый набор пакетов

Начал с малого — того, что годами ставлю на каждый сервер руками. Инвентарь и плейбук выглядят скромно:

[home]
server1 ansible_host=192.168.0.130
server2 ansible_host=192.168.0.140
- hosts: home
  become: yes
  tasks:
    - name: базовые пакеты
      apt:
        name: [htop, curl, git, vim]
        state: present
        update_cache: yes

Запуск одной командой:

ansible-playbook -i hosts.ini base.yml -K

Ключ K спрашивает пароль sudo, если у вас ещё не настроены ключи. Первое же выполнение показало магию: обе машины получили пакеты параллельно, а вывод раскрасил, что изменилось, а что уже было так. Приятнее любого скрипта по SSH, который я писал раньше.

Идемпотентность: почему это главная фишка Ansible

Слово страшное, смысл простой: запускать плейбук можно сколько угодно раз, результат будет одинаковым. Задача «пакет установлен» на уже настроенной машине просто пропустится без действий. Сравните с bash-скриптом, который при повторном запуске добавляет строку в конфиг пятый раз.

Для меня это перевернуло подход к правкам. Раньше я боялся трогать работающий сервер: вдруг сломаю. Теперь правка живёт в git, гоняется сначала с ключом проверки:

ansible-playbook base.yml --check --diff

Ключ check показывает, что изменится, ничего не трогая. Diff подсвечивает конкретные строки конфигов. Посмотрел глазами, понравилось — запускаю по-настоящему. Страх исчез полностью, проверено.

Момент Икс: шаблон nginx, который научил меня переменным

Первая серьёзная задача была такой: одинаковый nginx на двух машинах, но разные домены и корневые папки. Я чуть не создал два отдельных плейбука-близнеца. И тут я понимаю, что именно для этого существуют переменные и шаблоны Jinja2. Чуть не похоронил всю элегантность затеи на первой неделе, вот такой момент Икс.

Решение изящное. Переменные описываются рядом с хостом в инвентаре:

[home]
server1 domain=blog.example.ru root=/var/www/blog
server2 domain=shop.example.ru root=/var/www/shop

А шаблон nginx.conf.j2 внутри использует их как подстановки. Одна задача template разворачивает файл на все машины с их значениями. Поменял структуру конфига — правишь один шаблон, а не три файла на трёх серверах. Именно в этот момент я понял, зачем корпорации любят этот инструмент, и простил ему кривую кривую learning curve.

Структура проекта, которая выросла сама

Через месяц файлов стало много, и я навёл порядок. Мой домашний репозиторий выглядит теперь так: инвентарь с группами home и test, каталог group_vars с общими переменными, плейбуки по назначению — base.yml для фундамента, web.yml для веб-стека, backup.yml для резервных копий. Всё в git, изменения только через коммиты.

Отдельный совет из опыта: держите тестовую виртуалку в группе test и гоняйте опасные изменения сначала там. Один раз я неудачно поправил задачу с правами на каталог — боевой сервер пережил это легко, но осадочек остался. Теперь порядок железный: сначала test, потом home. Ansible-vault для секретов тоже прикрутите сразу, пароли в плейбуках не место.

Ansible против моих старых bash-скриптов

Честное сравнение после месяца параллельной жизни. Скрипты выигрывают в простоте для одной конкретной машины: написал, выполнил, забыл. Ansible выигрывает везде, где машин больше одной и задача повторяется. Мои старые скрипты установки стеков я переносил в плейбуки постепенно и каждый раз находил в них ошибки, которые годами жили незамеченными: неотработанные ветки, дубли, забытые зависимости.

Про порог входа скажу честно: первые два вечера я ругался. YAML со своими отступами, странные названия модулей, непонятно, где искать список всех модулей. Потом щёлкнуло — и стало обидно, что годами таскал конфиги руками. Если застрянете на старте, не бросайтесь в сложные туториалы: официальное введение плюс мой первый плейбук выше покрывают процентов восемьдесят домашних нужд.

Ещё неожиданный бонус: плейбуки читаются как документация. Жена спросила однажды, что будет с сайтами, если со мной что-то случится. Полчаса объяснений по репозиторию — и она поняла, что любой знакомый админ восстановит всю инфраструктуру по этим файлам. Со скриптами и заметками такой номер не прошёл бы.

Полезные команды, которыми пользуюсь каждую неделю

  • ansible all -m ping -i hosts.ini — проверить доступность всех машин
  • ansible-playbook site.yml —check —diff — сухой прогон изменений
  • ansible-playbook site.yml —limit server1 — применить к одной машине
  • ansible-vault encrypt secrets.yml — спрятать пароли в шифрованный файл
  • ansible-doc apt — справка по любому модулю прямо в терминале

Команда limit спасала меня дважды, когда нужно было срочно поправить одну машину, не трогая остальные. А ansible-doc заменяет браузер с документацией в девяти случаях из десяти.

Хендлеры: перезапуск сервиса только когда это нужно

Ещё одна жемчужина инструмента, о которой новички узнают поздно. Задача может сообщать об изменении, а специальная секция handlers реагирует на него перезапуском. Классика для nginx:

tasks:
  - name: положить конфиг
    template:
      src: nginx.conf.j2
      dest: /etc/nginx/nginx.conf
    notify: рестарт nginx
handlers:
  - name: рестарт nginx
    service:
      name: nginx
      state: restarted

Если конфиг не изменился — перезапуска не будет вообще. Если изменился — один рестарт в конце прогона, даже если конфигов пять. До Ansible я после каждой правки перезапускал сервисы по привычке, на всякий случай. Теперь лишние рестарты исчезли как класс, а вместе с ними и микро-простои сайтов.

Роли: когда файлов стало больше десяти

Плоские плейбуки хороши до определённого момента. Мой web.yml разросся до трёхсот строк, и навигация превратилась в квест. Спасением стали роли: каждый кусочек функциональности живёт в своей папке со своими задачами, шаблонами и переменными. Роль nginx, роль certbot, роль docker — собираются как конструктор.

Перенос в роли занял вечер и не добавил никакой новой магии, только порядок. Зато появился приятный побочный эффект: роль легко показать другу или забрать себе на другой проект. Я, например, свою роль бэкапов через rsync теперь гоняю и на работе, слегка поменяв переменные. Переиспользование из домашней лаборатории — неожиданный поворот, согласитесь.

Что делать, если плейбук падает с ошибкой

Паника тут не нужна, диагностика логичная. Читаю имя упавшей задачи и вывод модуля — обычно причина видна: нет пакета, отказ в доступе, опечатка в переменной. Частые случаи из моей практики: забыт ключ K на свежей машине, несовпадение имени пользователя в инвентаре, python3 отсутствует на минимальной системе. Лечится всё за минуты.

Если ошибка загадочная — запускаю ту же команду с ключом vvv и читаю подробный лог SSH-сессий. Девять из десяти загадок рассыпаются на этом уровне. И никогда не исправляйте проблему правкой на самом сервере руками: иначе машина разойдётся с плейбуком, и следующий запуск снова всё переделает. Правильный путь — починить плейбук и накатить его.

Мои типовые ошибки первых недель

Собрал личный анти-топ, чтобы вы прошли его быстрее. Первое место: забытый become: yes для задач с apt — модуль вежливо падает с отказом доступа. Второе: пробелы в YAML, табы вместо них — синтаксис этого формата чувствителен до безобразия, редактор с подсветкой обязателен. Третье: переменные из group_vars не видны в инвентаре одной машины — путаница областей видимости решается чтением документации один раз и на совесть.

Четвёртое, самое коварное: задача помечена изменённой при каждом запуске, хотя ничего не меняется. Обычно виноват модуль shell или command — они всегда рапортуют об изменении. Лечится ключами creates или changed_when. Пока не разобрался с этим, мои прогоны пестрели ложными оранжевыми строками, и я зря переживал за стабильность.

Итог: месяц с Ansible — что изменилось дома

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

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

Мониторинг прогонов: как я узнаю, что всё живо

Отдельная маленькая привычка, которая выросла в систему. Раз в неделю я запускаю полный прогон всех плейбуков с ключом check по всем машинам. Если где-то что-то разъехалось с описанным состоянием — я узнаю об этом из отчёта прогона, а не от жены, у которой отвалился сайт. Такой еженедельный аудит дрейфа конфигураций занимает три минуты и заменяет целый класс систем мониторинга для домашнего масштаба.

Для истории храню выводы прогонов в отдельном каталоге репозитория с датой в имени файла. Когда месяц назад спрашивал себя, когда именно менялся конфиг nginx и почему, — ответ нашёлся за минуту в этих логах. Дёшево, сердито и без единой строчки кода мониторинга.

План для ленивых: Ansible за первый вечер

  • Установить Ansible на управляющей машине, настроить ssh-ключи
  • Описать инвентарь с двумя группами: test и home
  • Написать base.yml: пакеты, часовой пояс, базовый пользователь
  • Прогнать с —check —diff, потом по-настоящему на тесте
  • Завести git-репозиторий, секреты спрятать в vault
  • Добавлять по одной задаче в неделю, не торопясь

Ваш комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *