Страховка от некорректных изменений в сети. Быстро. Недорого
По нашим наблюдениям, немногие заказчики используют инструменты автоматизации при внесении изменений в сетевую инфраструктуру. Если требуется что-то подстроить, администратор заходит в CLI устройства или нескольких устройств, вводит блок команд и вуаля – какой-то новый сервис в работе.
Такой подход к внесению изменений в инфраструктуру вполне себе ничего, когда изменения вносятся в одно устройство, и сервисы данного устройства не сложнее статической маршрутизации или пары политик межсетевого экрана, которые выпускают пользователей в интернет. Когда после изменений что-то не работает, достаточно немного внимательнее глянуть во введенные настройки, найти неточность и поправить ее. В крайнем случае, можно легко вернуться в исходное состояние, удалив все новые настройки.
Однако когда риск внесения некорректных изменений растет (например, или много устройств, или большой объем изменений), а последствия таких изменений могут быть ощутимы и неприятны для организации в целом, приходится посмотреть на задачу внесения изменений под другим углом. В этой статье я поделюсь идеями о некоторых проверках, которые помогут подстраховаться и избавить внесение изменений в инфраструктуру от ошибок. Как следствие можно сэкономить силы/ нервы/ время/ деньги, которые неизбежно затрачиваются на решение проблем, связанных с некорректными изменениями.
Прежде чем перейти непосредственно к объявленной теме статьи, хотелось бы обсудить способ (протокол) взаимодействия с сетевой инфраструктурой. Существуют, возможно, более подходящие для решения задач автоматизации протоколы, как, например, REST API или NETCONF, к несомненным преимуществам которых относится, например, обмен с устройствами сообщениями в структурированном формате данных JSON или XML. Однако вместе с тем использование указанных протоколов само по себе может вызвать некоторые сложности, т. к. отдельные функции управления, как, например, считывание состояния таблицы RIB может быть не реализовано через REST API и NETCONF.
Поэтому идеи, о которых пойдет речь, могут применяться независимо от протокола взаимодействия с устройствами. Это касается и крайнего случая, когда ничего кроме CLI для управления устройствами не применяется.
Проверка конфигурации до ее ввода в действие
Простая идея состоит в том, что команды (часть конфигурационного файла), проверяются прежде чем они будут применены в оборудовании в боевой среде. Такие проверки могут включать:
1) Синтаксис
2) Логическая целостность: учтены ли взаимосвязи между настройками конфигурационного файла, пример: задан ли список route map, на который ссылается BGP neighbor
3) Тест на согласованность с другими устройствами в сети, например, не использован ли один и тот же IP адрес на сетевых интерфейсах разных устройств
4) Тест на соответствие принятым в организации практикам настройки, например, есть ли комментарий, который поясняет назначение политики межсетевого экрана
5) Тест на соответствие наилучшим практикам производителя, например, использование 2-х heartbeat интерфейсов при настройке HA в кластере устройств
6) Любые другие проверки
Проверки №№ 1-2 могут быть выполнены на тестовом оборудовании, что редко встречается в жизни, или в эмуляторе. Проверка включает загрузку сначала текущего конфигурационного файла устройства, а затем предполагаемых изменений. Если изменения принимаются без ошибок, то проверка пройдена. Возможный набор инструментов такой:
1) физическое стендовое оборудование или при его отсутствии среда containerlab (https://containerlab.srlinux.dev), которая позволяет запустить виртуальную копию сетевой ОС,
2) для загрузки конфигураций в устройство и обработки результата загрузки – Ansible.
Тесты №№ 3-6 мы реализовали как мини-сценарии, например, на Python. Главный лайфхак: если прежде чем выполнять сами проверки, конфигурационный файл преобразовать в какой-то структурированный формат данных, например, JSON, проверки окажутся крайне простыми, а инструмент гибким, т. е. добавление новых тестов не станет проблемой.
Итак, новая конфигурация прошла все предварительные тесты успешно. Можно загружать конфигурационные файлы в оборудование.
Проверка конфигурации после ее применения
Цель данных проверок состоит в том, чтобы убедиться в работоспособности конфигурации, но уже на основании состояния сетевых сервисов в боевой среде.
Я остановлюсь на двух типах проверок, которые мы активно применяем, когда что-то изменяем в инфраструктуре заказчиков, – это проверки ожидаемого состояния и проверки неизменности состояния.
Проверки ожидаемого состояния
Смысл проверок состоит в сравнении текущего состояния с ожидаемым состоянием работоспособности сети. Состояние работоспособности может быть определено произвольно и зависит от задач, которые решает сеть (пример ниже).
Предположим, что мы тестирует сервис IP связности, который обеспечивается, в том числе, протоколом BGP. Пример проверки при перенастройке BGP:
- Запросить состояние BGP соседств на устройстве и убедиться, что новые BGP соседства установлены,
- Запросить таблицу маршрутизации и убедиться, что в таблице присутствуют маршруты к сетям назначения, которые заданы как условие теста.
В качестве среды исполнения таких проверок мы выбрали Ansible, т. к. данный инструмент обладает широким набором модулей для взаимодействия с системами разных типов. Пример выполнения такого тестирования можно найти на нашем GitHub – https://github.com/solidex/FortiADC-Check
Стоит заострить внимание на том, когда и какие тесты стоит выполнять. Не исключено, что какие-то изменения, которые мы вносим, вступят в конфликт с состоянием процессов и сервисов, которые уже находятся в работе. Результат – проблемы работоспособности, которые затрагивают как новые сервисы, так и старые. Поэтому проверки ожидаемого состояния имеет смысл выполнять каждый раз, когда хоть что-то изменяется, а тесты должны включать как новые, так и старые проверки.
Проверки неизменности состояния
Как-то раз перед нами стояла задача выполнить обновление сетевой ОС, сохранив конфигурационный файл и работоспособность сети. Проблема состояла в том, что поскольку мы не являлись авторами данного конфигурационного файла знать в деталях, что для чего настроено, мы не могли. Поэтому и описать ожидаемое состояние было невозможно. Что мы смогли сделать – это проверить, что состояние сети после обновления не изменилось.
Для выполнения тестирования мы создали сценарий, который считывает и сохраняет состояние ключевых сервисов, которыми оказались: ARP, OSPF, BGP, процесс маршрутизации и таблица RIB, VPN. Процедура состояла в сборе сведений о состоянии до обновления и после и сравнении двух состояний с ожиданием, что отличий в состояниях нет. Этот сценарий можно также найти на нашем GitHub – https://github.com/solidex/netmem.
В качестве завершения статьи хочется поделиться тем, как озвученные идеи укладываются в общий процесс управления конфигурацией сети и как они могут быть в конечном итоге реализованы.
Если посмотреть на процесс управления конфигурацией сети, то можно выделить несколько ключевых шагов (см. рисунок). Кстати, о некоторых шагах мы уже рассказывали в других наших статьях здесь и здесь.
Реализация шагов зависит от конкретной задачи, и, конечно, набора оборудования. Приведу ниже наш вариант реализации, который чаще всего используется:
1) Для задания конфигурационного состояния сети мы используем YAML файл, в котором перечисляются те сетевые сервисы и их параметры, которые мы хотим сконфигурировать. Текстовый конфигурационный файл как таковой не формируется. Вместо него создаются сценарии (playbook), которые, принимая на вход YAML файл, определяют целевое конфигурационное состояние устройств
2) Средой для проверки конфигураций является лабораторный стенд – физические устройства или виртуальные, – в которые загружается конфигурационное состояние. Проверки задаваемых параметров выполняются как через скрипты Python, так в сценариях Ansible (в зависимости от того, где проверку проще выполнить).
3) Загрузка конфигурационного состояния выполняется сценариями Ansible, которые программируют устройства через REST API
4) Проверочные сценарии Ansible используются для изъятия состояния сети и сравнения его с состоянием, которое является ожидаемым для данного набора конфигурационных параметров
Комментариев пока нет
Добавить комментарий