Agentless: магия без агентов
Урок 2 - разбираемся, как Ansible управляет серверами без единого агента.
«Лучший агент - это тот, которого не нужно устанавливать, обновлять и охранять».
Многие инструменты управления конфигурацией (Puppet, Chef, Salt в классическом режиме) работают по схеме «агент». На каждый сервер ставится демон, он постоянно крутится, ходит на центральный сервер за инструкциями. Это мощно, но дорого: агента надо установить, настроить, обновлять, следить за его безопасностью - на каждой машине. Ansible пошёл другим путём - agentless, без агента.
Как это работает
Ansible использует то, что и так есть на каждом Linux-сервере: SSH и Python. Когда ты запускаешь playbook, control node подключается к целевому хосту по SSH, копирует туда крошечный Python-модуль, выполняет его, забирает результат в формате JSON и удаляет временный файл. Никакого постоянно работающего процесса на сервере не остаётся.
CONTROL NODE MANAGED HOSTS
(твоя машина)
+-------------+ SSH (22) +-------------+
| playbook | -----------------> | web1 |
| inventory | | python3 |
| ansible | -----------------> +-------------+
+-------------+ SSH (22) +-------------+
| -----------------> | web2 |
| | python3 |
| +-------------+
v SSH (22) +-------------+
модуль на Python -----------------> | db1 |
копируется, run, JSON назад | python3 |
+-------------+
Обрати внимание: стрелки идут только в одну сторону - от control node к хостам. Серверы не ходят никуда сами, не открывают входящих соединений к управляющему узлу. Это упрощает сетевую модель и фаервол.
Как работает под капотом
Под капотом Ansible для каждого хоста делает примерно следующее: устанавливает SSH-соединение (часто переиспользуя его через ControlPersist для скорости), сериализует нужный модуль вместе с аргументами, передаёт его на хост, запускает интерпретатором Python, читает stdout как JSON-результат со статусом (ok, changed, failed) и подчищает за собой. Именно поэтому единственное требование к управляемому хосту - наличие Python и доступ по SSH.
Симулируем логику исполнения модуля на хосте маленькой Python-моделью. Это не настоящий Ansible, но точно отражает идею «модуль возвращает структурированный статус».
# Логика "модуля" на хосте: получает желаемое состояние,
# возвращает структурированный результат как настоящий Ansible-модуль.
def package_module(name, installed_packages, state="present"):
is_installed = name in installed_packages
if state == "present" and not is_installed:
installed_packages.add(name)
return {"changed": True, "msg": f"package {name} installed"}
if state == "absent" and is_installed:
installed_packages.discard(name)
return {"changed": True, "msg": f"package {name} removed"}
# уже в нужном состоянии - ничего не делаем
return {"changed": False, "msg": f"{name} already {state}"}
host_state = {"curl"} # что уже стоит на сервере
print(package_module("nginx", host_state)) # changed: True
print(package_module("nginx", host_state)) # changed: False (повтор)
print(package_module("curl", host_state)) # changed: False
Попробуй сам ▶ Запусти и посмотри: первый вызов вернул changed: True, а повторный - changed: False. Это и есть идемпотентность в зачатке: модуль сначала проверяет состояние, потом решает, нужно ли действие.
Частые ошибки
- Искать «агента Ansible». Его нет и не должно быть. Если кто-то предлагает «поставить ansible на каждый сервер» - это недоразумение. Ansible ставится только на control node.
- Забыть про Python на хосте. Очень минималистичные образы (например, голый Alpine) могут не иметь Python - тогда либо ставят его первым шагом через raw-модуль, либо используют специальный интерпретатор.
- Открывать лишние порты. Раз связь идёт только по SSH от control node, входящие соединения к серверам со стороны Ansible не нужны.
Best practices
- Используй SSH-ключи, а не пароли. Это и безопаснее, и удобнее для автоматизации.
- Заведи отдельного пользователя для Ansible с правом
sudoтам, где нужно повышение прав. - Не плоди агентов: простота agentless-модели - это фича, не недостаток.
В реальной работе
Agentless-модель особенно выручает в гетерогенной среде, где соседствуют разные дистрибутивы и версии. Тебе не нужно собирать и поддерживать пакет агента под каждую ОС, следить за совместимостью его версий и обновлять его по всему парку машин - достаточно того, что на хосте уже есть. Минус подхода в том, что Ansible работает «по требованию»: он не следит за серверами постоянно, как агентные системы, а приводит их в порядок только в момент запуска. Поэтому в зрелых командах playbook'и гоняют регулярно по расписанию или из CI, чтобы дрейф конфигурации не накапливался между ручными запусками.
Итоги
Ansible не требует агентов: он работает по обычному SSH, временно копируя на хост Python-модули и забирая структурированный результат. Это упрощает безопасность, сеть и эксплуатацию. Дальше познакомимся с установкой и первой командой.