Как сделать вашу ИТ-инфраструктуру скучной

Майкл ДеХаан — человек, который создал Ansible. Многие вещи, которые делают системные администраторы, релиз- и DevOps-инженеры на регулярной основе, мягко говоря, неинтересны. ДеХаан хочет, чтобы эти люди освободили свое время для более интересных вещей (на работе или за дверью офиса), и написал код продукта, который освобождает время администратора.
Больше времени, меньше адреналина в рабочие часы, меньше скриптов и меньше ошибок.
Кстати, вы можете закончить чтение на этом абзаце, вместо этого подключившись к livestream 6 июня вот здесь.

4pxib6asllealgf8sje7orcjsbg.png
Если вы все-таки продолжили читать…

Ansible: непрерывная интеграция и доставка


Ansible — это мощный язык автоматизации с открытым исходным кодом. Да, он отлично подходит не только для управления, но и для развертывания и оркестрации ИТ-систем. Ansible изначально создавался и для эффективного решения широкого круга задач автоматизации, и как простой универсальный базис для замены традиционных средств управления, а в итоге оказался весьма полезен во многих областях. Например, при обеспечении нулевых простоев в ходе непрерывной интеграции и доставки приложений (CI/CD). Обычно эта задача решается за счет обширной доработки софта, применения различных программных пакетов и массы ухищрений, уникальных для каждой конкретной конфигурации. Ansible же изначально спроектирован в расчете именно на такие сценарии оркестрации и предлагает готовое решение «все в одном».

Непрерывная интеграция и доставка приложений (CI/CD)


Немного прописных истин. Практика разработки программных систем за последние 10 лет показывает, что длинный жизненный цикл версий ПО (каскадная модель разработки) имеет гораздо более высокие накладные расходы по сравнению с коротким циклом (так называемая «итеративная» или agile-разработка). Все дело в аритмичности: когда программисты только начинают работать над новой версией, ИТ-специалистам, отвечающим за тестирование и развертывание, попросту нечего делать. Но чем ближе версия к выпуску, тем сильнее заняты ИТ-специалисты, и тем чаще программистам приходится переключать контекст, чередуя работу над ошибками и планирование следующей версии.

qvslb1fsnltkxftsz2hxtgebghg.pngКроме того, длинный цикл увеличивает интервал между выявлением и устранением программных ошибок и недочетов, что особенно критично для больших веб-систем с многомиллионной пользовательской аудиторией. Поэтому индустрия производства ПО стремительно осваивает методологии agile под лозунгом «выпускать быстрее и чаще», чтобы участники процесса разработки могли реже переключать контекст работы и гораздо быстрее создавать, отлаживать и внедрять доработки и новшества.

Автоматизация контроля качества, TDD-разработка через тестирование и другие сопутствующие техники еще больше повышают эффективность новых методов работы. А где автоматизация? Где технологии, заставляющим шестеренки крутиться быстрее и сводящим участие человека к строго необходимому минимуму?

А вот, например, Ansible и Ansible Tower от Red Hat для оркестрации ИТ-систем в рамках современных процессов разработки ПО.

Нулевые простои


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

Добиться нулевых простоев вполне реально, но для этого нужны соответствующие инструменты — такие, что обеспечивают расширенную, многоуровневую и многоступенчатую оркестрацию, как, например, система Ansible.

Системы сборки приложений


Непрерывная доставка (CD) начинается с непрерывной интеграции (CI). Система, которая мониторит репозитории исходных кодов на предмет изменений, самостоятельно прогоняет соответствующие тесты и автоматически выполняет сборку (а в идеале и тестирование) новой версии приложения при каждом обновлении кода это, например, проект Jenkins (jenkins.io).

Для передачи эстафеты CD-системе после успешной сборки новой версии приложения подсистема сборки CI-системы может вызывать Ansible, чтобы сразу же предоставить эту новую версию тем, кто выполняет модульное или интеграционное тестирование. В частности, Jenkins может задействовать Tower для развертывания сборок в различных средах, причем тестовая или промежуточная среда могут моделироваться на основе производственной среды, что сильно повышает предсказуемость на всем жизненном цикле ПО. Данные, возвращаемые Ansible по результатам выполнения сценариев автоматизации, можно напрямую задействовать в заданиях Build Systems системы Tower. На самом деле, Tower даже позволяет тестировать сценарии развертывания в промежуточной среде, прежде чем запускать их на «боевых» серверах.

Поочередное обновление многоуровневых приложений


CD-система в обязательном порядке должна уметь оркестрировать процессы поочередного обновления (rolling update) многоуровневых приложений. Благодаря push-архитектуре и возможностям многоуровневой многоступенчатой оркестрации, Ansible вполне справляется с этой задачей, обновляя любое приложение уровень за уровнем, обмениваясь при этом данными между ними.

Для реализации поочередного обновления в Ansible используются сценарии Play, которые позволяют точно задать группу целевых хостов и назначить задачи (Role), которые должны быть на них выполнены. Задачи — это обычно объявления о том, что конкретный ИТ-ресурс должен находиться в заданном состоянии, например, для одной версии ПО должен быть установлен определенный пакет, а для другой требуется свериться с репозиторием кода. Топологии веб-приложений, как правило, требуют обновлять их в строгой последовательности, а еще нельзя обновлять приложения и системные конфигурации на всех машинах одновременно.

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

Непрерывное развертывание для сценариев автоматизации


Помимо CD-функционала для сервисов, действующих в режиме промышленной эксплуатации, можно также организовать непрерывное развертывание самих сценариев автоматизации (наборов инструкций Ansible Playbook. Не прекращайте читать, во второй части будут примеры плэйбуков). Это позволяет системным администраторам и разработчикам управлять сценариями с помощью репозитория исходных кодов, тестировать эти сценарии в промежуточной среде и автоматически переносить их в производственную среду в случае успешной обкатки. Иначе говоря, при работе со сценариями вы получаете все методологические и другие преимущества центрального репозитория кода, к которым привыкли при разработке софта.

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

Поочередные обновления и системы балансировки нагрузки


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

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

Интегрированное промежуточное тестирование


Tower может работать с различными файлами инвентаризации ресурсов (Inventory), что позволяет легко тестировать сценарии поочередного обновления в промежуточной среде, прежде чем запускать их на «боевых» серверах. Для этого достаточно смоделировать производственную среду в тестовой, запустить Ansible с параметром »-i» и указать, какой файл инвентаризации должен использоваться при выполнении сценария — для тестовой среды или для производственной. Сам сценарий при этом модифицировать не нужно.

Развертывание на основе системы контроля версий


Некоторые любят погорячее выполнять упаковку приложений вместе с пакетами ОС (RPM, debs, и т. п.), однако зачастую, особенно для веб-приложений, такая упаковка не нужна. Поэтому в состав Ansible входят сразу несколько модулей для развертывания приложений непосредственно из систем управления версиями. В сценарии Playbook можно прописать сверку с репозиторием кода по заданному тегу или номеру версии, после чего Ansible проверит выполнение этого условия на всех целевых серверах и активирует последующие действия, только если версия нуждается в замене, устранив, таким образом, ненужные перезапуски служб.

Интеграция со средствами мониторинга


Как полноценная система оркестрации, Ansible поддерживает интеграцию с APM-системами управления производительностью приложений на уровне мониторинга. Допустим, на этапе развертывания или интеграционного тестирования вместе с приложением необходимо установить или обновить программный агент APM. В Ansible для этого есть специальная роль, и после установки и активирования агента, Ansible может настроить его в стеке APM-мониторинга (если он еще не настроен), чтобы специалисты по управлению приложениями могли сразу же проконтролировать, что новая версия установилась и работает без проблем.

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

Уведомление о событиях


В парадигме CI/CD все хотят получать уведомления о событиях как можно быстрее. Ansible предлагает как встроенные функции, включая модуль электронной почты, так и интеграцию с внешними инструментами оповещения, наподобие мессенджеров, социальных сетей или систем регистрации событий.

Развертывание с использованием модели состояния ресурсов


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

В Ansible можно очень точно прописать и проконтролировать порядок событий на разных уровнях архитектуры, что позволяет делегировать действия другим системам, а также комбинировать директивы ресурсной модели (по типу «пакет X должен быть в состоянии Y») и традиционные сценарные команды (наподобие «run script.sh») в рамках одного процесса.

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

Тестирование в ходе развертывания


Чем больше возможностей, тем выше ответственность. Автоматизация процессов непрерывной доставки резко повышает опасность развертывания сбойной конфигурации на всех узлах системы. Чтобы снизить риски, Ansible предлагает вставлять в сценарии контрольные тесты, которые прервут поочередное обновление, если что-то пойдет не так. Для проверки различных условий, включая статус функционирования служб, можно развертывать произвольные тесты с использованием модулей Command или Script, и даже создавать такие тесты в виде отдельных модулей Ansible.

Модуль Fail может прервать выполнение сценария на хосте в любой момент, что позволяет отловить сбои на ранней стадии поочередного обновления. Например, из-за отличия промежуточной среды от производственной в последней возникает конфигурационная ошибка, которая выводит из строя «боевые» сервера. На этот случай в сценарии Playbooks можно прописать аварийный выход на первом же этапе поочередного обновления. И если у вас 100 серверов, а размер окна поочередного обновления равен 10, то такая аварийная остановка даст время спокойно во всем разобраться, исправить сценарий и продолжить обновление.

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

Проверка соответствия


Есть среды, где конфигурации меняют только тогда, когда без этого уже никак. Любые изменения в таких средах предварительно анализируются. Тут используются системы непрерывной доставки «с оговорками».

В Ansible есть режим имитационного прогона (активируется флагом »--check»), когда система формирует отчет о том, какие изменения были бы проведены при выполнении сценария. Реального выполнения сценария при этом не происходит, имитационный прогон не позволяет отловить ошибки, но помогает лучше понять и проанализировать детали и результаты предлагаемых изменений.

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

Развертывание на автопилоте


Если вы живете в мире многоуровневой многоступенчатой оркестрации процессов поочередного обновления ПО с нулевыми простоями, то вероятней всего CI/CD у вас выполняется исключительно операторами (как вручную, так и с частичной автоматизацией) и требуют, как в хороводе, согласованных действий всех участников процесса. Ansible вместе с его уникальной архитектурой и отсутствием программных агентов на целевых хостах (повышающим безопасность и избавляющее от необходимости управлять самой системой управления) может доступно описать и легко автоматизировать сложные процессы развертывания, то есть Ansible реализует здесь режим полного автопилота.

Примеры сценариев автоматизации Ansible можно найти на GitHub, а сейчас мы дадим базис и пример, как написать сценарий Playbook, который можно выполнять в Ansible или Ansible Tower. Вместе со списком модулей и другими документами она поможет научиться создавать свои сценарии Playbooks.

Что такое Playbook?


Сценарий Playbook — это, по сути, набор инструкций (plays), который отправляется для выполнения какому-то одному удаленному хосту или группе хостов. Это как руководство по сборке мебели из IKEA: точно следуете инструкциям и получаете именно то, что видели в магазине. Примерно так и работают сценарии.

Модули (Modules)


Мы создадим Playbook, который будет устанавливать веб-сервер на хост RHEL/CentOS 7 и создавать на нем файл index.html на основе шаблона, указанного в сценарии. Приведенный здесь пример сценария полностью работоспособен и готов к использованию. Ниже мы рассмотрим пример сценария Playbook и покажем, как использовать модули.

Авторы (Authors)


Автор — это тот, кто создает инструкции, которые будут выполняться модулями (зачастую вместе с дополнительными значениями: аргументами, местоположениями и т. п.). Модули выполняются на целевом хосте в том порядке, в каком они следуют в сценарии Playbook (включая include«ы и другие входящие в него дополнительные файлы). Состояние хоста меняется (или не меняется) в зависимости от результатов выполнения модуля, которые отображаются в виде вывода Ansible и Tower.

Выполнение сценария Playbook


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

1. Целевая система (Target)
Поскольку сценарии Playbook выдают указания модулям и обеспечивают взаимодействие с ними, Ansible считает, что вы разбираетесь в том, что пытаетесь сделать, и просто автоматизирует это. Именно поэтому мы и говорим, что Playbooks — это как инструкции или указания: вы говорите автоматизированным элементам, как хотите сконфигурировать задачу. Но при этом вам нужно самому хорошо понимать, как работает целевой хост, на котором выполняется сценарий Playbook.

2. Задачи (Tasks)
Если в какой-то части Playbook требуется запустить веб-сервер, вам надо понимать, как это делается, чтобы знать, какой именно служебный модуль для этого использовать, и запустить веб-сервер по имени. Если Playbook устанавливает пакет ПО, вы должны знать, как это делается на целевом хосте. Вы также должны понимать, хотя бы на базовом уровне, суть выполняемых задач. Требуется ли дополнительная настройка хоста для ПО, которое вы хотите установить? Есть ли ветвления в зависимости от условий и значений аргументов? Если в процессе передаются какие-то переменные, вы должны точно понимать, какие и зачем.

Пример сценария Playbook
Приведенный ниже пример сценария Playbook поможет уяснить то, что вы только что прочитали. Целевым хостом в нем выступает сервер RHEL/CentOS 7, на который наш сценарий устанавливает веб-сервер NGINX, а затем создает файл index.html в каталоге webroot по умолчанию. После выполнения установки и создания индекса, выполняется запуск веб-сервера.

*Примечание: для запуска этого примера сценария Playbook в Ansible Tower требуется предварительно настроить inventory и аккаунты.

Playbooks начинается с трех дефисов YAML (---), за которыми следуют:

Name: просто имя сценария, чтобы сохранить удобочитаемость Playbook.

Hosts: список целевых хостов, на которых должен отработать Ansible.

Become: здесь мы прописали истинное утверждение, чтобы удостовериться, что nginx установился без проблем (это поле требуется не всегда).

1    ---
2       - name: Install nginx
3         hosts: host.name.ip
4         become: true


С тем отступом, что и три предыдущих строки, идет директива tasks:, после которой с дополнительным отступом (согласно правилам вложенности YAML) перечисляются задачи (plays). В этом примере у нас две задачи, и обе используют модуль Yum. Первая задача добавляет репозиторий epel-release, чтобы можно было установить nginx. После того, как в системе появится epel, вторая задача устанавливает пакет nginx.

Директива state: означает, что Ansible должен проверить состояние целевого хоста, прежде чем выполнять любые дальнейшие действия. В нашем примере, если репозиторий или nginx на хосте уже есть, Ansible понимает, что выполнять эти две задачи не нужно, и переходит к следующим.

1    tasks:
2         - name: Add epel-release repo
3           yum:
4             name: epel-release
5             state: present
6       
7         - name: Install nginx
8           yum:
9             name: nginx
10            state: present


Страница загрузки, которая используется в nginx по умолчанию, отлично подходит, чтобы проверить, что nginx установился правильно, но вам, скорее всего, захочется сделать это с помощью своего стартового html-файла. В этом примере для простоты шаблон index-файла находится в том же каталоге, откуда запускается Playbook. Destination — это просто путь по умолчанию в nginix без настроенных сайтов.

1      - name: Insert Index Page
2           template:
3             src: index.html
4             dest: /usr/share/nginx/html/index.html


Последняя строка в нашем Playbook служит лишь для того, чтобы проверить, что служба nginx была успешно запущена (или запустить ее, если нет).

1      - name: Start NGiNX
2           service:
3             name: nginx
4             state: started


Весь сценарий Playbook получился примерно такой же длины, что и вступительный абзац в этом посте:

1    ---
2       - name: Install nginx
3         hosts: host.name.ip
4         become: true
5       
6       tasks:
7         - name: Add epel-release repo
8           yum:
9             name: epel-release
10            state: present
11      
12        - name: Install nginx
13          yum:
14            name: nginx
15            state: present
16      
17        - name: Insert Index Page
18          template:
19            src: index.html
20            dest: /usr/share/nginx/html/index.html
21      
22        - name: Start NGiNX
23          service:
24            name: nginx
25            state: started


Резюме


Сценарии Playbook — это простой и удобный способ сделать много дел малым количеством кода. В рассмотренном выше примере мы использовали три модуля — yum, template и service, чтобы установить на сервер репозиторий и пакет ПО, создать файл из локального шаблона и затем запустить только что установленную службу. При этом наш сценарий Playbook вышел чуть длиннее этого предложения! И хотя мы выполняли его на одном хосте, он с тем же успехом может сделать это и на десятках и сотнях серверов, для этого лишь требуется внести в него совсем небольшие изменения. Кроме того, Tower позволяет поместить сценарий Playbook в шаблон задания для запуска на группе серверов в облаке AWS или в корпоративном дата-центре.

Архитектурные особенности Ansible и возможность интеграции с CI-системами, наподобие Jenkins, обеспечивают автоматизацию не только процессов управления конфигурациями, но и гораздо более широкого круга ИТ-задач. Именно поэтому мы ласково зовем Ansible комплексной системой оркестрации, а не просто инструментом развертывания ПО и управления конфигурациями.

© Habrahabr.ru