Русский
Русский
English
Статистика
Реклама

Блог компании мир plat.form (национальная система платежных карт)

Recovery mode От стартапа до тысяч серверов в десятке ЦОД. Как мы гнались за ростом Linux инфраструктуры

03.07.2020 20:16:17 | Автор: admin
Если ваша IT инфраструктура растёт слишком быстро, вы рано или поздно столкнётесь с выбором линейно увеличивать людские ресурсы на её поддержку или начинать автоматизацию. До какого-то момента мы жили в первой парадигме, а потом начался долгий путь к Infrastructure-as-Code.



Разумеется, НСПК не стартап, но такая атмосфера царила в компании в первые годы существования, и это были очень интересные годы. Меня зовут Корняков Дмитрий, более 10 лет я поддерживаю инфраструктуру Linux с высокими требованиями доступности. К команде НСПК присоединился в январе 2016 года и, к сожалению, не застал самого начала существования компании, но пришел на этапе больших изменений.

В целом, можно сказать, что наша команда поставляет для компании 2 продукта. Первый это инфраструктура. Почта должна ходить, DNS работать, а контроллеры домена пускать вас на сервера, которые не должны падать. IT ландшафт компании огромен! Это business&mission critical системы, требования по доступности некоторых 99,999. Второй продукт сами сервера, физические и виртуальные. За существующими нужно следить, а новые регулярно поставлять заказчикам из множества подразделений. В этой статье я хочу сделать акцент на том, как мы развивали инфраструктуру, которая отвечает за жизненный цикл серверов.

Начало пути

В начале пути наш стек технологий выглядел так:
ОС CentOS 7
Контроллеры домена FreeIPA
Автоматизация Ansible(+Tower), Cobbler


Всё это располагалось в 3х доменах, размазанных на нескольких ЦОДах. В одном ЦОД офисные системы и тестовые полигоны, в остальных ПРОД.

Создание серверов в какой-то момент выглядело так:



В шаблоне VM CentOS minimal и необходимый минимум вроде корректного /etc/resolv.conf, остальное приезжает через Ansible.

CMDB Excel.

Если сервер физический, то вместо копирования виртуальной машины на него устанавливалась ОС с помощью Cobbler в конфиг Cobbler добавляются MAC адреса целевого сервера, сервер по DHCP получает IP адрес, а дальше наливается ОС.

Поначалу мы даже пытались делать какой-то configuration management в Cobbler. Но со временем это стало приносить проблемы с переносимостью конфигураций как в другие ЦОД, так и в Ansible код для подготовки VM.

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

Например, мы захотели изменить какой-то конфиг на всех серверах:

  1. Изменяем конфигурацию на существующих серверах в логическом сегменте/ЦОД. Иногда не за один день требования к доступности и закон больших чисел не позволяет применять все изменения разом. А некоторые изменения потенциально деструктивны и требуют перезапуск чего-либо от служб до самой ОС.
  2. Исправляем в Ansible
  3. Исправляем в Cobbler
  4. Повторяем N раз для каждого логического сегмента/ЦОД

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

  • Рефакторинг ansible кода, конфигурационных файлов
  • Изменение внутренних best practice
  • Изменения по итогам разбора инцидентов/аварий
  • Изменение стандартов безопасности, как внутренних, так и внешних. Например, PCI DSS каждый год дополняется новыми требованиями

Рост инфраструктуры и начало пути

Количество серверов/логических доменов/ЦОД росло, а с ними количество ошибок в конфигурациях. В какой-то момент мы пришли к трём направлениям, в сторону которых нужно развивать configuration management:

  1. Автоматизация. Насколько возможно, нужно избегать человеческого фактора в повторяющихся операциях.
  2. Повторяемость. Управлять инфраструктурой намного проще, когда она предсказуема. Конфигурация серверов и инструментов для их подготовки должна быть везде одинаковой. Это так же важно для продуктовых команд приложение должно гарантированно после тестирования попадать в продуктивную среду, настроенную аналогично тестовой.
  3. Простота и прозрачность внесения изменений в configuration management.

Осталось добавить пару инструментов.

В качестве хранилища кода мы выбрали GitLab CE, не в последнюю очередь за наличие встроенных модулей CI/CD.

Хранилище секретов Hashicorp Vault, в т.ч. за прекрасное API.

Тестирование конфигураций и ansible ролей Molecule+Testinfra. Тесты идут намного быстрее, если подключаете к ansible mitogen. Параллельно мы начали писать собственную CMDB и оркестратор для автоматического деплоя (на картинке над Cobbler), но это уже совсем другая история, о которой в будущем расскажет мой коллега и главный разработчик этих систем.

Наш выбор:

Molecule + Testinfra
Ansible + Tower + AWX
Мир Серверов + DITNET(Собственная разработка)
Cobbler
Gitlab + GitLab runner
Hashicorp Vault




Кстати про ansible роли. Сначала она была одна, после нескольких рефакторингов их стало 17. Категорически рекомендую разбивать монолит на идемпотентные роли, которые можно потом запускать отдельно, дополнительно можно добавить теги. Мы роли разбили по функционалу network, logging, packages, hardware, molecule etc. А вообще, придерживались стратегии ниже. Не настаиваю на том, что это истина в единственной инстанции, но у нас сработало.

  • Копирование серверов из золотого образа зло!

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

    1. Оставьте /etc/sysctl.conf пустым, настройки должны лежать только в /etc/sysctl.d/. Ваш дефолт в один файл, кастом для приложения в другой.
    2. Используйте override файлы для редактирования systemd юнитов.
  • Шаблонизируйте все конфиги и подкладывайте целиком, по возможности никаких sed и его аналогов в плейбуках
  • Рефактория код системы управления конфигурациями:

    1. Разбейте задачи на логические сущности и перепишите монолит на роли
    2. Используйте линтеры! Ansible-lint, yaml-lint, etc
    3. Меняйте подход! Никакого bashsible. Нужно описывать состояние системы
  • Под все Ansible роли нужно написать тесты в molecule и раз в день генерировать отчёты.
  • В нашем случае, после подготовки тестов (которых больше 100) нашлось около 70000 ошибок. Исправляли несколько месяцев.


Наша реализация

Итак, ansible роли были готовы, шаблонизированы и проверены линтерами. И даже гиты везде подняты. Но вопрос надежной доставки кода в разные сегменты остался открытым. Решили синхронизировать скриптами. Выглядит так:



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

Вариантов создания серверов тоже много. Мы в итоге выбрали кастомные скрипты на питоне. А для CI ansible:

- name: create1.yml - Create a VM from a template  vmware_guest:    hostname: "{{datacenter}}".domain.ru    username: "{{ username_vc }}"    password: "{{ password_vc }}"    validate_certs: no    cluster: "{{cluster}}"    datacenter: "{{datacenter}}"    name: "{{ name }}"    state: poweredon    folder: "/{{folder}}"    template: "{{template}}"    customization:      hostname: "{{ name }}"      domain: domain.ru      dns_servers:        - "{{ ipa1_dns }}"        - "{{ ipa2_dns }}"    networks:      - name: "{{ network }}"        type: static        ip: "{{ip}}"        netmask: "{{netmask}}"        gateway: "{{gateway}}"        wake_on_lan: True        start_connected: True        allow_guest_control: True    wait_for_ip_address: yes    disk:      - size_gb: 1        type: thin        datastore: "{{datastore}}"      - size_gb: 20        type: thin        datastore: "{{datastore}}"

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

  • 17 ansible-ролей для настройки сервера. Каждая из ролей предназначена для решения отдельной логической задачи (логирование, аудит, авторизация пользователей, мониторинг и т.д.).
  • Тестирование ролей. Molecule + TestInfra.
  • Собственная разработка: CMDB + Оркестратор.
  • Время создания сервера ~30 минут, автоматизировано и практически не зависит от очереди задач.
  • Одинаковое состояние/именование инфраструктуры во всех сегментах плейбуки, репозитории, элементы виртуализации.
  • Ежедневная проверка состояния серверов с генерацией отчётов о расхождениях с эталоном.

Надеюсь мой рассказ будет полезен тем, кто в начале пути. А какой стек автоматизации используете вы?
Подробнее..

Как мы автоматизировали весь жизненный цикл серверов

15.07.2020 18:16:18 | Автор: admin

Привет, Хабр! Меня зовут Алексей Назаров. Я занимаюсь автоматизацией в отделе администрирования инфраструктурных систем в Национальной системе платежных карт (АО НСПК) и хотел рассказать немного о наших внутренних продуктах, которые помогают нам развиваться.
Если вы еще не читали пост про нашу инфраструктуру, то самое время! После прочтения этого поста я бы хотел рассказать о некоторых внутренних продуктах, которые мы разработали и внедрили.



В нашей компании, как и в любой другой, существуют свои регламенты и бизнес-процессы. Один из них это тот, по которому мы создаем сервера или стенд серверов по заявке Jira ServiceDesk. У сервера есть функциональный администратор, т.е. владелец. У серверов также имеется статус (Тестовый, Продуктивный, UAT и т.д.). Из-за статусов и других характеристик сервера должны находится в своем сегменте, датацентре, датасторе, сети и прочее. А значит, чтобы создать сервер сначала требуется: создать сервер в VMware, задать ему имя, ip, dns и другие немаловажные параметры, а потом уже прокатить ansible-playbook.


История развития


Я пришел в НСПК в январе 2015 года и работал в ситуационном центре дежурным линуксоидом. В наши основные обязанности входило создавать и настраивать сервера, поддерживать сервера в работоспособном состоянии. Когда система мониторинга показывала какие-то перебои c серверами, обращались к нам. 1-линии поддержки для эскалации требовалась информация о сервере: его назначение, за какую систему отвечает, кому он принадлежит и т.д. В случае срабатывания критичных триггеров в системе мониторинга 1-линия описывала подробную информацию о причинах и состоянии системы. Подробная информация о серверах на тот момент находилась у нас, так как серверами занимались мы. А значит мы также передавали подробную информацию о серверах 1-линии.


Для учета серверов мы использовали excel-файл. Для учета ip использовали phpIPAM https://phpipam.net/. phpIPAM open source продукт для учета адресным пространством. Еще некоторая информация могла находиться в самой системе мониторинга. Количество серверов насчитывалось не более 700.


В нашем отделе сотрудники отвечают за разные задачи: одни занимаются Виртуализацией и СХД, другие Windows, а мы Linux. Также есть отдел, где находятся сетевые инженеры и администраторы БД.


Создание серверов было не упорядочено. Продуктивные сервера создавались по заявкам, тестовые могли создаваться без них. Сервер создавался вручную. А значит:


1) Требовалось узнать в каком датацентре, датасторе, сети и прочее
2) Создать сервер в требуемом сегменте через Vcenter
3) Прогнать bash-скрипты и некоторые ansible-playbookи
4) Добавить корректные данные о сервере в excel-файл
5) Добавить ip в phpIPAM
6) Закрыть заявку, если она была


Через некоторое время стало понятно, требуется создавать все больше и больше серверов. И мы стали искать варианты систем для хранения информации и учета серверов.
На просторах интернета таких систем немало. Даже в phpIPAM можно хранить информацию о серверах. Но в таких системах неудобно смотреть и анализировать состояние серверов в разрезе. В них не было необходимых полей и связей, нет фильтров по полям как в excel, нет четкого разграничения прав на редактирование и просмотр определенных серверов.
Мне тогда нравился Python, и я хотел сделать что-то на Django. Поэтому решил написать свою CMDB для нужд отдела и компании. После ее создания мы решили автоматизировать процесс создания и настройки серверов. Что получилось? Об этом далее


Мир серверов


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



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



Кроме хранения данных о серверах Мир серверов имеет функционал:


  • Разграничение прав доступа на просмотр и редактирование данных (по департаменту, по управлению, по отделу)
  • Удобный просмотр серверов в табличном виде, фильтр по любым полям, показ/скрытие полей
  • Разнообразные оповещения по почте
  • Актуализация информации о серверах
  • Ежедневный сбор данных о серверах и хранение для аналитики по ресурсам систем


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


Интеграция Мира серверов с другими системами:
1) Автоматическое обновление ip в phpIPAM
2) Выполнение заявок Jira ServiceDesk на предоставление нового сервера (стенда серверов) через Мир серверов
3) Просмотр расположения физического сервера и правильность заполнения информации в системе dcTrack (https://www.sunbirddcim.com/)
1) Передача информации о серверах через REST API для Zabbix и других систем мониторинга
2) Передача информации о ПО установленного на серверах через REST API для нужд ИБ
3) Синхронизация владельцев серверов из 1С и Active Directory для получения ФИО, рабочей почты, принадлежность к подразделению, статусе сотрудника. Надо написать, что такие данные требуется для разграничения прав, а также для автоматического оповещения владельцев серверов о ряде событий, связанных с их серверами.


DitNet


Наша инфраструктура на данный момент имеет более 10 ЦОД. Из этого понятно, что Мир серверов не сможет в любом сегменте создать и настроить сервер из-за понятных требований PCI-DSS.
Поэтому при выполнении заявок на предоставление сервера мы формируем json с данными, которые требуется для создания в среде VMware. Передача json реализована через защищенный rsync или ftps зависит от сегмента.
Надо заметить, что наш отдел провел очень большую работу. Убрали bashsible, переработали ansible на идемпотентные роли для настройки серверов, настроили molecule (https://molecule.readthedocs.io/), унифицировали все артефакты VMware и много чего другого. Стандартизация артефактов VMware потребовалась по большей части для серверных подсетей во всех ЦОДах (у нас их уже больше 900).
Как пример:
Раньше Distributed Switch мог называться test2, а теперь 192.168.1.0|24_test2. Данное переименование требовалось, чтобы можно было на этапе формирования json сделать матчинг подсетей из phpIPAM и VMware.


Выполнение заявок по предоставлению серверов:
1) DitNet ежедневно или по запросу собирает все артефакты из VMware (кластеры, датасторы, сети, шаблоны и т.д). Упаковывает всю информацию в json и отправляет в Мир серверов
2) Мир серверов принимает данные и наполняет данные БД артефактами VMware
3) В Мире серверов имеется страница, которая обращается к Jira ServiceDesk и по jql-запросу получает список заявок на предоставление серверов со статусом Очередь. На этой странице исполнитель заполняет таблицу артефактами VMware и другими ресурсами (Рис. Ниже). Часть данных автоматически заполняется данными, которые были указаны в заявке.



4) После заполнения и нажатия кнопки Сотворить, заявка меняет статус в Jira ServiceDesk В работе
5) В этот момент Мир серверов формирует json с данными о создании ВМ (артефакты, dns, ip и т.д.) и перекладывает его в папку для своего сегмента (определяется по домену сервера)
6) Каждый DitNet в своем сегменте запрашивает данные из своей папки и обогащает данными таблицу с серверами на установку. В БД имеются дополнительные поля с информацией по статусу установки (по умолчанию: готов к установке)
7) На DitNet каждые 5 минут отрабатывает Celery beat, который по статусу установки определяет количество серверов, которые требуется установить и настроить
8) Celery worker запускает несколько последовательных задач:
a. Создает сервер в VMware (используем библиотеку pyvmomi)
b. Скачиваем или обновляем проект gitlab по настройке сервера
c. Запускается Ansible-playbook (используем данный гайд https://docs.ansible.com/ansible/latest/dev_guide/developing_api.html)
d. Запускается Molecule
e. Отправка почты исполнителю и Миру серверов о статусе выполнения
9) После каждой задачи проверяется статус. Если все задачи выполнены оповещаем исполнителя с сформированной ссылкой для закрытия заявки Jira ServiceDesk. Если какая-нибудь из задач провалилась, то оповещаем исполнителя с логом Vmware или Ansible.


Что еще умеет Ditnet на данный момент:


  • Собирает все данные и ресурсы со всех серверов. Для данной задачи мы используем Ansible с модулем setup. На хостах кроме локальных фактов используем также кастомные. Перед каждым запуском формируем инвентарь для Windows и Linux.
  • Собирает информацию SNMP о физических серверах. Сканируем определенные подсети и получаем серийный номер, версию BIOS, версия IPMI и т.д.
  • Собирает информацию о группах серверов в Freeipa (HBAC, SUDO правила), о группах в Active Directory. Для сбора и контроля ролевой модели доступа пользователей к информационным системам
  • Переустановка серверов
  • А еще там на заднем фоне котики. Рисунок ниже:


Вся информация, которую собирает DitNet, отправляется в Мир серверов. А там уже и проходит вся аналитика и актуализация данных о серверах.


Как мы обновляемся


В данный момент над Миром серверов и DitNet тружусь уже не только я. Нас уже три человека.
Весь исходный код хранится в наших Gitlab для удобной параллельной разработки. В каждом из проектов имеется свой Ansible-playbook, который запускает Gitlab CI и обновляет приложение. Pipeline:



По pipeline видно, что не хватает unit-тестов. Но, думаю, мы в скором будущем это исправим.
Также Ansible-playbook можно запустить через Ansible Tower (AWX) на новых серверах, если требуется новая инсталляция.
В случае с DitNet мы используем docker, чтобы доставлять нужные библиотеки во все сегменты. Он описан docker-compose. А docker-compose services завернуты в systemd.


Планируется в будущем


  • Автоматическое выполнение заявок на установку серверов без исполнителя
  • Плановое автоматическое обновление серверов
  • Добавление в Мир серверов сущности СХД и автоматический сбор данных
  • Сбор информации с физических серверов о всех комплектующих для отправки в Мир серверов для контроля ЗИПа серверов
  • Автоматическое оповещение об уходе из компании владельца сервера для последующей привязки серверов к будущему владельцу
  • Продолжение интеграции с другими системами компании
    и много еще интересного!

P.S. Спасибо за Ваше время! Критика и комментарии приветствуются!

Подробнее..

Системный подход к переменным в Ansible

07.08.2020 12:20:56 | Автор: admin

ansible devops codestyle


Hey! Меня зовут Денис Калюжный я работаю инженером в отделе автоматизации
процессов разработки. Каждый день новые сборки приложений раскатываются на сотнях
серверов кампании. И в этой статье я делюсь опытом использования Ansible для
этих целей.


Этот гайд предлагает способ организации переменных в деплое. Рассчитан данный
гайд на тех кто уже использует роли в своих плейбуках и читал Best
Practices
, но сталкивается с подобными проблемами:


  • Найдя переменную в коде, невозможно сходу понять за что она отвечает;
  • Есть несколько ролей, и переменные нужно связать одним значением, но никак
    не получается;
  • Возникают трудности в объяснении другим, как устроена логика переменных в
    ваших плейбуках

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



Переменные в ролях


Роль это отдельный Объект системы деплоя. Как и любой объект системы, он
должен иметь интерфейс взаимодействия с остальной системой. Таким интерфейсом
являются переменные роли.
Возьмём, для примера, роль api, которая устанавливает Java приложение на
сервер. Какие переменные у неё могут быть?



Переменные роли можно разделить на 2 вида по типу:


1. Свойства    a) независимые от среды    б) зависимые от среды2. Связи    a) слушатели     б) запросы внутри системы    в) запросы в среду

Переменные свойства это переменные, которые определяют поведение роли.


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


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


С другой стороны, 1а, 2а, 2б это переменные, которые не зависят от среды
(железо, внешние ресурсы и т.д.) и могут быть заполнены дефолтными значениями в
defaults роли. Однако переменные типа 1.б и 2.в заполнить кроме как 'example'
значениями невозможно, так как они будут меняться от стенда к стенду в
зависимости от окружения.


Code style


  • Название переменной обязательно должно начинаться с названия роли. Это позволит
    в дальнейшем легко разобраться, из какой роли переменная и за что она отвечает.


  • При использовании переменных в ролях вы должны обязательно следовать принципу
    инкапсуляции и использовать переменные определённые либо в самой роли, либо
    в ролях, от которых текущая зависит.


  • Старайтесь не использовать словари для переменных. Ansible не позволяет
    удобно переопределять отдельные значения в словаре.
    Пример плохой переменной:


    myrole_user:    login: admin    password: admin
    

    Здесь login средонезависимая переменная, а password зависимая. Но
    поскольку они объединены в словарь, вам придётся задавать её полностью
    всегда. Что очень неудобно. Лучше так:


    myrole_user_login: adminmyrole_user_password: admin
    


Переменные в плейбуках деплоя


При составлении плейбука деплоя (далее плейбук), мы придерживаемся правила, что
он должен размещаться в отдельном репозитории. Так же, как и роли: каждая в своем
git репозитории. Это позволяет осозновать, что роли и плейбук это разные
независимые объекты системы деплоя, и изменения в одном объекте не должны влиять
на работу другой. Достигается это изменением дефолтных значений переменных.


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


mydeploy                        # Каталог деплоя deploy.yml                  # Плейбук деплоя group_vars                  # Каталог переменных плейбука  all.yml                 # Файл для переменных связи всей системы  myapi.yml               # Файл переменных свойств группы myapi inventories                 #     prod                    # Каталог окружения prod       prod.ini            # Инвентори файл       group_vars          # Каталог для переменных инвентори         myapi           #           vars.yml    # Средозависимые переменные группы myapi           vault.yml   # Секреты (всегда средозависимы) *

* Variables and Vaults


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


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


Например, в одном проекте переменная, отвечающая за включение SSL долго была
средозависимой, поскольку мы не могли включить SSL по независящим от нас
причинам на одном из стендов. После того, как мы устранили эту проблему, она
стала средонезависимой и переместилась в переменные плейбука.


Переменные свойств для групп


Расширим нашу модель на рисунке 1, добавив 2 группы серверов с другим Java
приложением, но с разными настройками.



Представим, как будет выглядить плейбук в этом случае:


- hosts: myapi  roles:    - api- hosts: bbauth  roles:    - auth- hosts: ghauth  roles:    - auth

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


Code Style


  • Старайтесь вообще не использовать host_vars переменные, поскольку они не
    описывают систему, а только частный случай, что в перспективе приведёт к
    вопросам: "А почему этот хост отличается от остальных?", ответ на который не
    всегда легко найти.

Переменные связи


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


По началу была идея использовать монструозную конструкцию вида:
hostvars[groups['bbauth'][0]]['auth_bind_port'], но от неё сразу отказались
поскольку она имеет недостатки. Во-первых, громоздкость. Во-вторых, зависимость
от определенного хоста в группе. В-третьих, необходимо перед началом деплоя
собрать факты со всех хостов, если мы не хотим получить ошибку неопределённой
переменной.


В итоге решено было использовать переменные связи.


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


Переменные связи заполняются в общих переменных системы group_vars/all/vars и
образуются путём выноса всех переменных слушателей из каждой группы, и
добавлением в начало переменной название группы откуда слушатель был вынесен.
Таким образом обеспечивается однотипность и непересекаемость имён.


Попробуем связать переменные из примера выше:



Представим, что у нас есть переменные, которые друг от друга зависят:


# roles/api/defaults:# Переменная запросаapi_auth1_address: "http://example.com:80"api_auth2_address: "http://example2.com:80"# roles/auth/defaults:# Переменная слушательauth_bind_port: "20000"

Вынесем в общие переменные group_vars/all/vars всех слушателей, и добавим в
название имя группы:


# group_vars/all/varsbbauth_auth_bind_port: "20000"ghauth_auth_bind_port: "30000"# group_vars/bbauth/varsauth_bind_port: "{{ bbauth_auth_bind_port }}"# group_vars/ghauth/varsauth_bind_port: "{{ ghauth_auth_bind_port }}"# group_vars/myapi/varsapi_auth1_address: "http://{{ bbauth_auth_service_name }}:{{ bbauth_auth_bind_port }}"api_auth2_address: "http://{{ ghauth_auth_service_name }}:{{ ghauth_auth_bind_port }}"

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


Code Style


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

Средозависимые файлы


В ролях могут использоваться файлы, которые отличаются от среды к среде.
Примером таких файлов можно назвать SSL-сертификаты. Хранить их в текстовом виде
в переменной не очень удобно. Зато удобно хранить путь до них внутри переменной.
Например, используем переменную api_ssl_key_file: "/path/to/file".


Поскольку очевидно, что сертификат ключа будет меняться от среды к среде, то это
средозависимая переменная, а значит она должна расположиться в файле
group_vars/myapi/vars инвентори переменных, и содержать значение 'для примера'.


Удобнее всего в этом случае положить файл ключа в репозиторий плейбука по пути
files/prod/certs/myapi.key, тогда значение переменной будет:
api_ssl_key_file: "prod/certs/myapi.key". Удобство же заключается в том, что
люди отвечающие за разворачивание системы на конкретном стенде, так же имеют
своё выделенное место в репозитории для хранения своих файлов. В то же время
остаётся возможность указать абсолютный путь до сертификата на сервере, на
случай если сертификаты поставляются другой системой.





Несколько стендов в одной среде


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





Окончательная структура каталогов для проекта деплоя:


mydeploy                        # Каталог деплоя deploy.yml                  # Плейбук деплоя files                       # Каталог для файлов деплоя  prod                    # Католог для средозависимых файлов стенда prod   certs               #        myapi.key       #  test1                   # Каталог для средозависимых файлов стенда test1 group_vars                  # Каталог переменных плейбука  all.yml                 # Файл для переменных связи всей системы  myapi.yml               # Файл переменных свойств группы myapi  bbauth.yml              #   ghauth.yml              # inventories                 #     prod                    # Каталог окружения prod      group_vars          # Каталог для переменных инвентори       myapi           #        vars.yml    # Средозависимые переменные группы myapi        vault.yml   # Секреты (всегда средозависимы)       bbauth          #         vars.yml    #        vault.yml   #       ghauth          #           vars.yml    #           vault.yml   #      prod.ini            # Инвентори стенда prod     test                    # Каталог окружения test         group_vars          #          myapi           #           vars.yml    #           vault.yml   #          bbauth          #           vars.yml    #           vault.yml   #          ghauth          #              vars.yml    #              vault.yml   #         test1.ini           # Инвентори стенда test1 в среде test         test2.ini           # Инвентори стенда test2 в среде test

Подведение итога


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


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


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


Литература


  1. Документация

Автор


Калюжный Денис Александрович

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru