Ansible: с чего начать и как не перейти на темную сторону

от автора

Николай Месропян, системный инженер Southbridge, подробно рассказал редакции Слёрма о шестилетнем опыте работы с Ansible. Что стоит за слоганом «Simple IT automation»? Почему нельзя остановить темное движение мысли специалиста? И насколько это ясно на старте работы с Ansible? Николай досконально «разложил» все плюсы инструмента на минусы и наоборот.  

Ansible – для кого, когда и зачем

Ansible — инструмент автоматизации. Он необходим, чтобы упросить и ускорить работу с IT-инфраструктурой, когда bash-скриптов уже недостаточно. Скрипты – сложны в поддержке.

Компаниям, у которых уже есть развитые и устраивающие всех средства работы с инфраструктурой, сетями, настройкой серверов и деплоем приложений, логично продолжать использовать имеющиеся инструменты. В остальных случаях он может помочь даже специалистам без навыков работы с другим подобным ПО. Для Ansible есть готовые модули стандартизации описания конфигурации и работы с инфраструктурными компонентами. Также хорошо организована работа с данными сериализованными и не очень: есть фильтры, как заимствованные из Jinja2, так и собственные.

«Точка входа» в сложные процессы 

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

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

  •  развёртывания облачных окружений у различных провайдеров;

  • настройки операционных систем;

  • установки приложений;

  • работы с сетевыми устройствами — коммутаторами, роутерами, в том числе виртуальными;

  • работы с cgroup-контейнерами разных видов (Docker, Podman);

  • взаимодействия с Kubernetes API и так далее. 

По мере развития кодовой базы можно углублять знания, постепенно совершенствуя свои навыки работы с Ansible. 

В целом, проще перечислить, чего Ansible не умеет. А недостающий модуль можно написать самому. Но лично мне не требовалось. Я всегда обходился штатными специфическими модулями + command/shell. При грамотном применении их можно сделать квази-идемпотентными. Мой пример не может быть полностью репрезентативным, разумеется. В профессиональных сообществах, связанных с Ansible, строго рекомендуют написание собственных модулей в случаях, когда реализация с помощью модулей общего назначения требует «обмазки» сложной логикой. У меня в практике не было подобного примера.

YAML: за и против

В качестве плюса можно добавить использование языка разметки YAML для описания конфигурации. Он интуитивно понятен и весьма популярен сегодня благодаря распространению решений типа Kubernetes.

Фундаментальный недостаток связан с тем, что синтаксис YAML позволяет реализовать любые, самые изощренные bad practices. Просто потому, что это универсальный язык разметки, и при его создании ничего не знали ни про какой Ansible. Он никак не ограничивает самые темные движения мысли разработчика.

Главная слабость Ansible — обратная сторона низкого порога вхождения

Можно легко и непринуждённо породить монстра, который будет выполнять свои функции, но весь состоять из bad practice — сложного в поддержке и непредсказуемо ведущего себя при нетипичных входных данных.

Наиболее зловещими и распространенными антипаттернами, с моей точки зрения, являются два. Назовем их условно «всеобъемлющие роли» и «убей их всех, бог потом рассортирует»  «запускаем плейбук на всех хостах, разбираем условия выполнения в процессе».

Всеобъемлющие роли. Бывает, что вместо набора ролей, каждая из которых делает что-то одно, но хорошо, пишется роль, пытающаяся «объять необъятное». Она, как правило, оказывается пронизанной неочевидными зависимостями и условиями выполнения тасков, крайне затрудняющими чтение и понимание кода. Такое происходит или при добавлении функционала в первоначально простенькую роль (упускается момент, в который становится нужно её декомпозировать на отдельные роли), или просто при изначальном недостатке понимания требуемой архитектуры.

Например:

roles ┐       └ web-server

Верно:

roles ┐       │‐nginx       │‐php       │‐php-fpm       │‐rvm       │‐nodejs       └ selinux

Неиспользование групп хостов. Эта «bad practice» весьма распространена и встречается слишком часто, даже в больших и серьёзных проектах. Подобная проблема также связана с недостаточной декомпозицией, но уже не в контексте «UNIX way», а в контексте «потока выполнения». Вместо того чтобы разбить хосты на группы и, используя набор плеев, выполнять отдельные роли на нужных группах хостов, разработчик ставит hosts: all и внутри tasks с помощью условий разбирает, какой таск на каком хосте выполнить. В результате получается «вермишель», глядя в которую сложно понять, «кто на ком стоял».

Например:

- name: Play for all hosts    hosts: all       tasks:    - name: >   Include role bar   conditionally      include_role:   name: bar      when: foo_var is defined 

Верно:

[foo] bar1.example.com bar2.example.com  - name: Play for foo hosts   hosts: foo   tasks:    - name: Import role bar      import_role:    name: bar

Умело применяя оба этих подхода можно написать проект, который при изменении входных условий может ломаться в самых неожиданных местах и будет весьма неудобен в поддержке и развитии даже для того, кто его написал.

Разумеется, список негодных практик и антипаттернов не исчерпывается двумя описанными случаями. Можно вспомнить и более очевидные вещи, которые изрядно портят жизнь новичкам.

  • Так называемый «bashsible», когда вместо имеющихся специфических модулей не к месту применяются command и shell. При этом теряется идемпотентность и могут возникнуть лишние сторонние эффекты. 

  • Использование lineinfile вместо template — теряется предопределённость и декларативность конфигурации.

  • Использование имен переменных, не уникальных для данной роли — это, очевидно, рано или поздно приводит к конфликтам.

Push or pull

Наиболее часто применяющийся способ работы любого сложного ПО —  это  взаимодействие с удалёнными хостами через ssh. Оно происходит по модели push: сам Ansible запускается на «центральном» управляющем хосте, ходит на управляемые серверы и что-то там делает. И тут возникает проблема со скоростью работы и зависимость от стабильности сети. 

Справедливости ради добавлю: в  последние год-два разработчики уделяют большое внимание скорости работы Ansible, и это приносит видимые результаты. Доработки позволяют нам потихоньку отказываться от использования стороннего модуля Mitogen, который ранее использовали для увеличения скорости выполнения. Тем не менее в скорости работы он уступает тем системам, которые выполняются непосредственно на конечных хостах — по модели pull.

Я выбрал Ansible. Этот инструмент показался мне более понятным для начинающего, чем один его основной конкурент и более популярным, перспективным и стабильным чем другой. Слоган Ansible: «Simple IT automation».

НЕ Ansible – для кого, когда и зачем

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

Как средство настройки и поддержания конфигурации серверов он проигрывает в скорости работы таким распространённым системам, как SaltStack и Chef. Chef конкурирует с Ansible ещё и как средство деплоя.

В нише конфигурации сетевых устройств у Ansible тоже есть конкуренты, но это, как правило, решения от вендоров, которые пишут инструменты под своё железо Так делают, например, Cisco, D-Link.

В нише доставки приложений есть целый мир инструментов, заточенных под язык/фреймворк.

В моей практике были ситуации, когда эффективнее выбрать другой инструмент. Например, те операторы Kubernetes, которые требуют постоянного согласования описанной и действительной конфигураций (reconсiling), лучше писать на Go. Ansible – слишком медленный и однопоточный для подобных задач. Приходилось идти на компромиссы за неимением квалификации для полноценного использования Golang.

Я знаю случаи, когда с Ansible уходили на SaltStack, так как для конкретного кейса нужна была более распределённая система. С другой стороны, Ansible используют даже на Windows. Признаться, я в этом плохо разбираюсь, но раз используют, значит, видят преимущество перед «родными» системами управления конфигурациями.

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

Народная мудрость советует учиться на чужих ошибках.

Всеволод Севостьянов, автор курса «Ansible: Infrastructure as Code», собрал множество примеров и кейсов, демонстрирующих «что такое хорошо, а что такое плохо». Для закрепления наглядной теории студентам придется выполнить 78 тестовых и 46 практических заданий на стендах в личном кабинете. Один из 8 блоков курса посвящен горячо обсуждаемому в профессиональных сообществах вопросу: когда и как писать собственный модуль? А еще встречи со спикером, общение в чатах, настоящий IT-поединок и целая коллекция забавных мемов. Результат: быстрый «вход» в Ansible без порождения «монстров», о которых предупреждал Николай Месропян.


ссылка на оригинал статьи https://habr.com/ru/company/southbridge/blog/659945/


Комментарии

Добавить комментарий

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