Как стать автором
Обновить
40.82
Hoff Tech
Разрабатываем удобные решения для OneRetail

Как мы Nautobot до ума доводили

Время на прочтение10 мин
Количество просмотров5.6K

Много слов было сказано про концепцию Source of Truth в мире сетей, много копий сломано в дискуссиях о том, как лучше её реализовать. Кто-то голосует за Git, кто-то жить не может без Netbox, а кто-то по старинке хранит всё в Excel и собственной памяти.

Мы же в Hoff Tech вот уже больше года активно используем Nautobot, и нам есть чем поделиться с теми, кого гложут мысли: «Так, Nautobot установил, где у него кнопка что делать дальше?»

Сперва небольшое отступление

  1. Статья рассчитана на тех, кто собирается заняться сетевой автоматизацией, начинает ей заниматься или делает это уже давно. Если же вы не в курсе про Nautobot, но почитать очень хочется, вот документация — тыц, а вот демонстрация — тыц.

  2. Nautobot — это форк Netbox, и, хотя с момента ветвления прошло достаточно много времени и интерфейсы сильно различаются, всё приведённое в статье можно применить и к Netbox. Сделай в тексте ниже :%s/Nautobot/Netbox/g, суть останется такой же.

  3. Статья обзорная: вы не найдёте в ней ни строчки кода (ну почти). Конкретные реализации приведённых практик будут сильно зависеть от окружения.

Этап 0. Для чего вообще всё это нужно?

Расскажу на примере Hoff Tech. У нас на обслуживании enterprise-сеть, в которой под сотню филиалов и свой ЦОД (не один). Больше тысячи виртуальных машин, десятки тысяч IP-адресов, разбитых по функциональным сегментам и бизнес-юнитам, сотни единиц оборудования (и сетевого, и просто подключённого к сети). А если компания динамично расширяется, в том числе и за счёт поглощения новых структур? Присоединяешь к себе большую слабодокументированную сетевую инфраструктуру и понимаешь: хорошо, что у нас информация о сети хранится в удобном виде, её и достать легко, и актуализировать, и использовать в процессах автоматизации.

Но так было не всегда. Используемые префиксы и VLAN хранились в Excel, более-менее актуальный список маршрутизаторов/коммутаторов можно было найти только в inventory-файле ansible, а свободен или нет IP-адрес — мог проверить исключительно сетевик. Не удивительно, что в определённый момент количество сетевой информации начало влиять на её качество и актуальность. В общем, боль сетевого инженера как она есть.

И тут нам на помощь пришла система документирования сети. IPAM или, если брать шире, самый настоящий Network Source of Truth

Этап 1. Установка

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

Что касается ресурсов, в этом плане Nautobot совсем не требователен. PostgreSQL с базой данных крутится на виртуалке с двумя ядрами и 4Gb памяти. Всё остальное — фронтенд, бэкенд, воркеры, реверс-прокси, брокер — на виртуалке 4 ядра/4 гига. Этого хватает, чтобы открыть без каких-либо задержек страницу с IP-адресами, коих у нас в базе больше 50 тыс. штук.

Сразу небольшой лайфхак. Для тестирования новых релизов и обучения приёмам работы с Nautobot мы подняли тестовый сервер, на который периодически переносим данные с продуктового. Чтобы пользователи случайно не перепутали сервера, логотип и favicon на тестовом сервере перекрасили из синего цвета в оранжевый. Теперь пользователю сразу понятно, в песочнице ли он и можно ли тренировать навыки удаления критически важных данных.

Для контроля доступа в Nautobot целесообразно использовать учетные данные корпоративного домена. В случае использования ADFS вам потребуется самостоятельно разработать плагин, например, на базе модуля django-adfs. Гораздо проще внедрить решения, аналогичные  Keycloak или Authelia, с ними не будет проблем. Во этом случае интеграция займет не более часа на чтение документации и правку конфигурационных файлов.

Итак, Nautobot установлен и доступен, пришла пора наполнить его жизнью.

Этап 2. Сетевые устройства, префиксы, VLAN

Официальная документация гласит, что Nautobot — это в первую очередь Network Source of Truth. То есть логично, что первыми в нём поселились сетевые устройства: маршрутизаторы и коммутаторы. Конечно, никто и не помышлял вносить данные руками. В это интересное для сетевиков время практически каждый из нас умеет в Python, поэтому у нас быстренько родились несколько джобов, обеспечивающих процесс наполнения данными (jobs — скрипты на Python, запускаемые прямо из интерфейса Nautobot).

AddDevices job. На входе получает список IP-адресов, тип устройства (коммутатор, роутер), платформу (Cisco IOS, Router OS, etc.) и сайт, к которому относятся добавляемые устройства. Джоб по SSH подключается к каждому девайсу из списка, парсит вывод show-команд и вносит структурированные данные в Nautubot. В результате получаем заполненные префиксы, вланы, устройства с интерфейсами и адресами. Этот джоб мы используем при появлении в сети новых устройств.

Небольшой лайфхак номер два. Перед добавлением новых устройств мы максимально заполнили используемые нами модели устройств (device_type). Данные взяли с https://github.com/netbox-community/devicetype-library. Теперь у каждого нового девайса всегда будут правильные набор портов и данные по электропотреблению, которые наследуются при создании от выбранного device type.

CheckDevices job. Проходит по всем сетевым устройствам и сравнивает информацию, хранящуюся в Nautobot (адреса интерфейсов, описания портов, разрешённые VLAN, etc.), с данными, полученными с девайса по SSH. Результаты работы джоба пушатся в git. Джоб регулярно выполняется по шедулеру и извещает сетевых инженеров об отличиях между ожидаемым и реальным состояниями устройства.

SearchDevices job. Проходит по всем сетевым устройствам и обнаруживает соседние устройства, которые видны по CDP/LLDP, но о которых ещё нет данных в Nautobot. Результаты работы джоба пушатся в git. Джоб регулярно выполняется по шедулеру и извещает сетевых инженеров о девайсах, которые по какой-то причине не добавлены в Nautobot.

UpdateDevices job. Проходит по всем сетевым устройствам и актуализирует данные в Nautobot в соответствии с реальным состоянием девайсов. Заодно джоб добавляет соединения между устройствами. Список обновляемых девайсов можно отфильтровать перед выполнением.

GetConfigs job. Проходит по всем сетевым устройствам, получает с них running- и startup-конфигурации и пушит их в git. Джоб регулярно выполняется по шедулеру и позволяет в любой момент увидеть актуальную конфигурацию и всю историю изменений. Этот джоб заменил нам всем известные Rancid и Oxidized

Все джобы используют под капотом модули scrapli и textfsm, под часть оборудования пришлось слегка адаптировать community-драйверы и подготовить собственные шаблоны textfsm. Общение с девайсами осуществляется по SSH, дополнительно рекомендую использовать asyncio, что может заметно уменьшить время работы джобов. Например, CheckDevices обходит все девайсы за пять минут, а это почти 800 единиц. При этом с каждого девайса он получает вывод в среднем шести команд, обрабатывает результаты и сравнивает с данными из Nautobot.

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

Этап 3. Перенос данных из исторических систем

Эта стадия внедрения у каждого своя, к сожалению, универсального рецепта пока никто не придумал.

У нас был развёрнут phpIPAM, из которого без особых усилий (2 модуля: phpypam и pynautobot, 1 вечер, 2 кружки кофе) были вытащены данные по статическим IP-адресам и серверным стойкам. Согласитесь, выполнять лишнюю работу никто не хочет, поэтому почему бы и не воспользоваться результатами чужого труда.

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

Скрипт переноса вытащил данные по стойке из phpIPAM, создал необходимые типы устройств, серверные стойки. После этого добавил нужное количество устройств с названиями «панель коммутационная» и «организатор кабельный», разместил их в нужные юниты. Мы порадовались и забыли про эти элементы СКС. Ровно до того момента, когда кому-то из пользователей понадобилось добавить ещё одну коммутационную панель.

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

Но в этой ложке мёда притаилась бочка дёгтя. Названия безымянных устройств в стойке выводятся как результат f"{self.device_type.manufacturer} {self.device_type.model} ({self.pk})", а это слишком длинно. Ну что же, пока ничего не остаётся, как править в коде Nautobot метод display() класса Device (совсем немножечко).  Для исправления ситуации мы после каждого обновления выполняем

sed -i.bak 's/{self.device_type.manufacturer} {self.device_type.model} ({self.pk})/{self.device_type.model}/' /opt/nautobot/lib/python3.8/site-packages/nautobot/dcim/models/devices.py

Небольшой лайфхак номер три. Не все изменения можно внести, используя Bulk edit в веб-интерфейсе. Для простых массовых действий мы часто используем nbshell. Например, для одноразовой очистки name у большого числа девайсов можно выполнить прямо в консоли следующую конструкцию:

for device in Device.objects.filter(device_type=DeviceType.objects.get(slug=’patch-panel’)):
  device.name = ’’
  device.save()

Не надо заморачиваться с подключением к API или импортом модулей. Среди прочего, в nbshell удобно смотреть справку по атрибутам и методам встроенных классов, используя стандартный help().

Этап 4. Концентрируемся на IPAM

Знания о том, какие VLAN разрешены на портах коммутатора или в каком VRF и с каким адресом настроен интерфейс маршрутизатора, очень полезны. Но «что сетевику хорошо, обычному админу, может, и не нужно». Обычного админа (основного пользователя Nautobot) больше интересует, какой IP-адрес у принтера или камеры или из какого диапазона назначить статический адрес новому устройству.

Часть этих вопросов мы закрыли, организовав регулярную синхронизацию данных в Nautobot с DHCP-серверами. DHCP у нас построен на базе Microsoft Windows Server, поэтому самый простой способ — использовать PowerShell:

  1. скрипт на PowerShell экспортирует диапазон выдаваемых адресов и зарезервированные адреса в XML-файл (командлет Export-DhcpServer);

  2. XML конвертируется в JSON;

  3. через API Nautobot вызывается джоб, которому передаётся сформированный JSON;

  4. джоб добавляет в Nautobot новые адреса и удаляет те, которые больше не выдаются.

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

job_script_name = f'job_{self.__module__}'
for group in self.request.user.groups.values_list('name', flat = True):
  if group.name == job_script_name:
    break
else:
  self.log_info(message='Неавторизованный запуск')
  return f'Вам не назначена группа безопасности "{job_script_name}"'

Так мы минимизируем угрозы от утери токена.

Таким образом, в Nautobot попадают все зарезервированные IP-адреса с заполненным полем "DNS name". Статус таких адресов определяется как DHCP reserved. А выдаваемые, но не зарезервированные, адреса имеют в Nautobot статус DHCP. Теперь мы можем определить степень заполненности подсети адресами: какие адреса действительно свободные, а какие могут быть выданы в любой момент.

Но это работает только с динамическими адресами. Что делать со статическими? Они, хоть и называются так, имеют тенденцию постоянно меняться. Тут нам помогает аналог switchmap — плагин porthistory. Я уже писал о нём статью на «Хабр». Этот плагин добавляет возможность хранить информацию о связке IP-MAC и последнем появлении MAC-адреса на том или ином порту коммутатора. Джоб, входящий в состав плагина, выполняет следующие действия:

  1. по SNMP получает с маршрутизаторов таблицу ARP;

  2. по SNMP получает с коммутаторов таблицу MAC-адресов;

  3. если IP-адреса из таблицы ARP нет среди выдаваемых по DHCP, значит, это статический адрес и его надо добавить в Nautobot (естественно, если его ещё там нет) со статусом Static;

  4. по каждому статическому IP-адресу уточнятся DNS-имя и при необходимости актуализируется в Nautobot;

  5. данные о привязке IP к MAC-адресу и порту коммутатора сохраняются в соответствующие модели учёта.

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

Этап 5. Не забываем про виртуализацию

В Hoff Tech мы жить не можем без виртуальных машин: их легко создать, настроить, а удалить и того проще. Естественно, у каждой виртуальной машины есть интерфейс с IP-адресом, а то и не один. Хотя мы не ставили целью сделать Nautobot системой учёта виртуализации, но, как IPAM-система, Nautobot должен знать всё о кластерах, хостах, самих виртуальных машинах и их адресации.

Тут нам опять на помощь приходит PowerShell, но теперь уже вместе с модулем VMware PowerCLI для управления ESXi и vSphere. Алгоритм синхронизации незначительно отличается от вышеописанных:

  1. скрипт на PowerShell через API Nautobot получает список адресов ESXi и VSphere;

  2. PowerCLI используется для подключения к API ESXi и VSphere;

  3. экспортируются данные (установленная ОС, интерфейсы, IP-адреса) обо всех рабочих ВМ в JSON;

  4. через API Nautobot вызывается джоб, которому передаётся сформированный JSON;

  5. джоб анализирует изменения и по результатам добавляет новые ВМ, изменяет существующие, назначает выключенным и удалённым соответствующий статус.

Синхронизация выполняется по шедулеру каждый час, при любых изменениях, вносимых админами виртуальной инфраструктуры через консоль управления облаком, эти изменения зеркалируются в Nautobot. Синхронизируется всё необходимое: объём памяти и количество vCPU, интерфейсы с IP- и MAC-адресами, привязка интерфейсов к VLAN, описание серверов и теги.

Существует готовый плагин для Nautobot — Nautobot SSoT vSphere. Он умеет практически всё то же самое, но нам не подошёл по внутренним причинам. В другом окружении использовать его как способ синхронизации данных с VSphere вполне реально.

Ну и последний на сегодня лайфхак. Результаты многочисленных джобов копятся и копятся, страница с историей и логами запусков открывается всё медленнее. А ведь эта история не особо и нужна. Увы, встроенной очистки результатов по шедулеру в Nautobot ещё не завезли. Так что рекомендую написать простенький джоб-терминатор, который по заданному алгоритму будет аннигилировать лишние записи. В нашем насчитывается не больше 50 строчек кода:

from nautobot.extras.jobs import *
from nautobot.extras.models import JobResult

class ClearJobHistory(Job):
  class Meta:
    name = "Delete old results of jobs"
    description = "Удаляет устаревшие записи о выполненных джобах"
    commit_default = False
    hidden = True
  def run(self, data, commit):
    results = JobResult.objects.all()
    old_count = 0
    for result in results:
      # тут логика (зависит от: кто запустил, когда, название джоба, статус и результаты)
      if waste_result:
        old_count += 1
        result.delete()
    self.log_success(message=f'Удалено результатов {old_count} из {results.count()}')

Промежуточные итоги

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

  1. Flexible Source of Truth for Networking. Это основной кейс, и мы постарались максимально его реализовать. Сейчас подавляющая часть данных о сети доступна в Nautobot, информация актуальна и автоматически поддерживается в таком состоянии. Не забываем и про уточнение Flexible — необходимые нам модели учёта мы добавляем с помощью плагинов.

  2. Extensible Data Platform for Automation. Вебхуки, REST API, GraphQL: всё это используется у нас для передачи данных во внешние системы автоматизации. Такие, например, как системы сканирования уязвимостей. А одной из дальнейших тем для рассказов может стать то, как мы готовим dynamic inventory для Ansible.

  3. Platform for Network Automation Apps. Nautobot обеспечивает лёгкое внедрение Python-скриптов сетевой автоматизации. Для этого у него есть готовые модули интерфейсов, доступные данные о сети, нативная синхронизация с Git, поддержка разных секретов для разных устройств/групп. И пусть наши джобы пока только собирают информацию из внешнего мира — в планах уже изменить вектор сетевой автоматизации и минимизировать действия сетевых инженеров напрямую на устройстве через CLI.

Сейчас могу смело сказать, что Nautobot отлично справляется с реализацией концепции Source of Truth. Но, конечно,  в основном это заслуга не выбранной системы, а людей, которые двигают автоматизацию. Уверен, что при наличии прямых рук и огонька в глазах абсолютно неважно, какую систему документирования сети вы выберете.

Теги:
Хабы:
Всего голосов 7: ↑7 и ↓0+7
Комментарии2

Публикации

Информация

Сайт
hofftech.ru
Дата регистрации
Дата основания
Численность
201–500 человек
Местоположение
Россия