Опубликован: 18.04.2021 | Доступ: свободный | Студентов: 870 / 414 | Длительность: 04:36:00
Лекция 6:

Configuration as Code. Ansible

< Лекция 5 || Лекция 6

Configuration as Code - принцип, схожий с Infrastructure as Code, однако функционирующий на другом уровне. Как следует из названия, данный паттерн позволяет хранить и распространять конфигурацию операционной системы представленную в виде кода. То есть любое изменение в системе должно быть отражено (теоретически) в коде.

Основные понятия и термины

Пример конфигураций:

  • установка новых пакетов
  • добавление или удаление пользователей
  • настройка файрволла
  • поиск и конфигурация разделов в дисковой подсистеме.

Преимущества подобного паттерна также весьма схожи с Infrastructure as Code:

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

В Configuration as Code существует основное разделение на два типа инструментов: с агентами и без, или которые работают в режиме pull или push.

  • Pull режим с агентом - вид инструментов, у которых есть серверная и клиентская часть. Клиентская часть устанавливается на конфигурируемые системы. В режиме pull агент самостоятельно забирает конфигурацию с сервера которую требуется выполнить.
  • Push режим без агента - когда сервер самостоятельно подключается к системам назначения и выполняет конфигурацию.

Инструменты которые работают в pull режиме:

  • chef
  • puppet
  • SaltStack

Инструменты которые работают в push режиме:

  • SaltStack
  • Ansible
  • Otter

Примеры использования pull-инструментов: большие распределенные системы с необходимостью поддерживать конфигурацию в актуальном состоянии. Системы в которых конфигурируемые сервера могут не иметь постоянного доступа к серверу конфигураций.

Примеры использования push-инструментов: автоматизация конфигурации сборки образов виртуальных машин. Провижининг новых серверов при запуске. Управление конфигурациями сетей.

Работа Ansible

Основные определения

  • Ansible сервер - машина на которой установлен Ansible и с которой запускаются плейбуки или таски.
  • Модуль - команда, или набор команд определённые в Ansible которые будут исполнены на стороне клиентского сервера.
  • Task (задача) - секция описывающая выполнение одной процедуры или команды
  • Role - набор задач, который позволяет реализовать некоторую смысловую роль клиентского сервера.
  • Inventory - файл, описывающий группы клиентских серверов.
  • Playbook - система описывающая ассоциацию групп серверов и назначенные им роли
  • Fact - информация собираемая с клиентских серверов
>Как установить Ansible на Linux

Используя пакетный менеджер apt:

sudo apt update
sudo apt install software-properties-common
sudo apt-add-repository ppa:ansible/ansible
sudo apt update
sudo apt install -y ansible

Используя пакетный менеджер yum:

sudo yum install epel-release
sudo  yum install -y ansible

Рассмотрим строение inventory файлов:

По умолчанию в inventory файлах присутствует две группы:

  • all - все хосты указанные в inventory файле
  • ungrouped - хосты не присутствующие ни в одной группе

Файлы могут быть в форматах yaml или ini.

Пример inventory файла в формате ini:

mail.example.com

[webservers]
web1.example.com
web2.example.com

[dbservers]
db1.example.com
db2.example.com
db3.example.com

В данном случае будет две объявленные группы - webservers и dbservers, и общие all/ungrouped. При этом в ungrouped попадает только хост mail.example.com

Такой же файл можно описать в yaml формате:

all:
  hosts:
    mail.example.com:
  children:
    webservers:
      hosts:
        web1.example.com:
        web2.example.com:
    dbservers:
      hosts:
        db1.example.com:
        db2.example.com:
        db3.example.com:

Если внутри команды не указывать inventory файл, то по умолчанию Ansible будет использовать файл по пути /etc/ansible/hosts

Использование непосредственных команд (модулей) с Ansible:

Пример описывает проверку доступности серверов описанных в inventory ansible -i inv.ini -m ping all

  • ansible - команда самого ansible
  • -i - флаг, позволяющий указать конкретный inventory файл
  • inv.ini - inventory файл в ini формате
  • -m - флаг, указывающий команду (модуль)
  • ping - название модуля. В данном случае он выполнит опрос всех хостов находящихся в inventory файле и проверит есть ли от них ответы
  • all - указание что команда будет применена ко всем хостам в inventory файле

Пример создания пользователя demo с помощью команды: ansible -i inv.ini -m user -a 'name=demo state=present' all

  • -a - флаг указывающий атрибуты команды
  • В одинарных кавычках можно указать документированные параметры команды и их значения, они будут переданы команде в момент исполнения
Использование Ansible-Playbook

Первое что необходимо знать про ansible-playbook - это рекомендуемое форматирование папок.

Начиная с корневой директории playbook:

production             # инвентори файл для production серверов
staging                   # инвентори файл для staging серверов


group_vars/
   group1.yml             # групповые переменные для групп хостов в инвентори файле
   group2.yml
host_vars/
   hostname1.yml          # переменные специфичные для отдельных хостов
   hostname2.yml

library/                  # Директория для сторонних модулей

site.yml                  # мастер playbook
webservers.yml      # playbook для веб-серверов
dbservers.yml         # playbook для серверов баз данных

roles/
    common/               # Иерархия представляющая роль
        tasks/            # Задачи находятся в директории tasks
            main.yml      #  Файл с задачами, может включать (импортировать) в себя другие файлы
        templates/        #  Папка для хранения шаблонов к ресурсам
            ntp.conf.j2   # Шаблон в формате j2 (jinja2)
        files/            # папка для хранения дополнительных файлов
        vars/             #
            main.yml      # переменные ассоциированные с данной ролью
        defaults/         #
            main.yml      # стандартные значения переменных
        meta/             #
            main.yml      #  Зависимости данной роли
        library/          # кастомные модули роли

Пример работы с ролью:

Все ресурсы в Ansible-playbook декларируются с помощью языка сериализации данных yaml.

Создадим role default, с задачей new_user, файл main.yaml

--- 
- name: Create new user
  user:
    name: demo
    state: present

Для исполнения данной роли создадим файл playbook - general.yaml

---
- hosts: all
  roles:
    - default

Для запуска используем команду:

ansible-playbook -i hosts.ini general.yaml

Команда применит роль ко всем возможным хостам найденным в hosts.ini

Выводы

Используя Ansible можно реализовывать как саму парадигму configuration as code и управлять множеством удаленных серверов, так и выполнять стандартизированную автоматизацию. Автоматизация в данном случае позволит заменить стандартные shell скрипты, на строгие и структурированные плейбуки, которые легко читать и обслуживать. Такую автоматизацию удобно использовать при подготовке образов виртуальных машин как для облачных вычислений, так и для локальных гипервизоров.

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

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

Разнообразие модулей позволяет использовать Ansible и для работы с облачными ресурсами по парадигме Infrastructure as Code, однако этого следует избегать, поскольку работая с Ansible вы будете описывать что вы хотите сделать, а не что вы хотите получить в результате скриптов. В результате может сложиться ситуация что прерванный скрипт Ansible при повторном запуске не учтёт результат прошлого скрипта, а просто создаст новую пачку серверов, что может быть крайне затратно и неудобно.

< Лекция 5 || Лекция 6
Рустам Тагаев
Рустам Тагаев

Очень много ошибок в тестах. Другие люди их тоже нашли. Но прошло очень много времени и похоже что ошибки не собираются исправлять. Очень обидно что на такой большой платформе такая медленная реакция.