4. Источник истины#
Новый сервис должен был запуститься к концу недели. Изменение было простым: новый VLAN, новая подсеть, обновлённые правила брандмауэра и новое BGP-сообщество на пограничных маршрутизаторах. Сетевой инженер точно знал, что делать. Последовали четыре дня координации между пятью системами: инструментом IPAM для резервирования подсети, CMDB для регистрации сервиса, платформой управления брандмауэром для применения новой политики, системой конфигурации маршрутизаторов для BGP-сообщества и платформой мониторинга для добавления новых порогов. У каждой системы был свой интерфейс, своя модель данных, свой рабочий процесс согласования. А поскольку общей ссылки не существовало, инженеру пришлось нести контекст вручную: копировать значения из одной системы в другую, надеясь, что ничего не изменится между шагами.
Шесть месяцев спустя сервис был выведен из эксплуатации. VLAN убрали. Подсеть освободили. Но правило брандмауэра осталось. Никто не помнил, что оно было связано с этим сервисом. BGP-сообщество сохранялось на двух пограничных маршрутизаторах. Порог мониторинга продолжал генерировать низкоприоритетные оповещения, которые NOC научился игнорировать. Со временем сеть накапливала слои осиротевшей конфигурации: остатки изменений, которые никогда не отслеживались полностью, никогда не отменялись полностью, никогда не были связаны с общей записью намерения.
Вот как на самом деле выглядит работа сети без источника истины. Не единый драматический сбой, а медленное накопление несогласованности, когда каждое изменение требует обновления нескольких разрозненных систем, и ничто не отслеживает, что принадлежит друг другу.
Каждая система автоматизации начинается с одного вопроса: Что я на самом деле собираюсь делать? Когда вы развёртываете правило брандмауэра, добавляете IP-адрес или настраиваете VLAN, вы делаете это на основе какого-то представления намерения. Это представление и есть ваш источник истины: единственная, надёжная версия того, что должно быть развёрнуто.
Я использую “Источник истины” и “Намерение” как взаимозаменяемые. Это в точности одна и та же концепция.
Без надёжного источника истины сетевые операции превращаются в беспорядок из скрытых знаний. Инженеры расходятся во мнениях о том, что развёрнуто. Таблицы противоречат тому, что реально работает. Две разные системы автоматизации вносят конфликтующие изменения в одно и то же устройство. Когда что-то ломается, вы занимаетесь археологией: “Почему это было настроено именно так? Кто это одобрил? Когда это изменилось?”
В этой главе рассматривается, как построить источник истины, который работает вне зависимости от того, имеете ли вы десятки устройств или сотни тысяч, обслуживает всех, кому нужны данные (людей, автоматизацию, другие системы), сохраняет данные точными и заслуживающими доверия, и справляется со сложностью получения данных из нескольких источников. Мы рассмотрим шесть строительных блоков: Моделирование, Потребление, Применение, Версионирование, Агрегация и Проектно-ориентированный подход, которые вместе создают прочную основу для сетевой автоматизации. Я также коснусь практических вопросов включения существующих сетей в эту систему и покажу, какие решения реально доступны.
4.1. Основы#
Источник истины делает три вещи: определяет как вы выражаете то, что хотите, где живёт это намерение, и как вы поддерживаете его надёжность с течением времени. Без него другие строительные блоки становятся автономными инструментами без общей ссылки. С ним они работают вместе.
4.1.1. Цели#
Ваш источник истины должен делать шесть вещей:
Захватывать всё необходимое. Хранить полную картину вашей сети: конфигурации, активы, топологию, сервисы, IP-адреса, каналы, спецификации устройств, секреты, окна обслуживания, требования соответствия и сведения о владельцах. Включать не только то, что работает сегодня, но и то, что запланировано, и то, что выводится из эксплуатации. Когда все эти данные хранятся в одном месте, а не разбросаны по таблицам и головам людей, системы автоматизации получают контекст, необходимый для принятия разумных решений.
Позволять операторам думать в бизнес-терминах, а не в синтаксисе устройств. Сотрудники должны работать на бизнес-уровне (“добавить новый филиал” или “настроить MPLS-сервис”), а не на уровне Command Line Interface (CLI). За кулисами система выясняет реальные конфигурации для конкретных устройств. Это сохраняет фокус на том, чего стараются достичь, а не на низкоуровневых деталях.
Позволять людям и машинам легко получать доступ к данным. Система нуждается в Application Programming Interface (API) (Representational State Transfer (REST), GraphQL), чтобы автоматизация могла получать и изменять данные. Ей нужен веб-интерфейс и Command Line Interface (CLI), чтобы люди могли просматривать и редактировать. Всем нужен надёжный контроль доступа, чтобы видеть только то, что им положено. Могут работать сотня рабочих процессов автоматизации одновременно, десятки сотрудников редактируют данные, и внешние системы синхронизируются — и всё это остаётся согласованным и быстрым.
Поддерживать данные чистыми и заслуживающими доверия. Проверять всё: правильность типов данных, осмысленность связей, допустимые диапазоны VLAN, отсутствие дублирующихся IP-адресов. Отслеживать, кто и когда что изменил. Позволять людям одобрять крупные изменения до их вступления в силу. При возникновении проблем — откатываться. Автоматизации необходимо доверять точности данных, потому что плохие данные приводят к плохому состоянию сети и сбоям.
Позволять людям работать параллельно, не мешая друг другу. Несколько команд должны иметь возможность предлагать изменения одновременно. Изменения группируются в атомарные пакеты: либо все принимаются, либо все отклоняются, без промежуточных состояний. Можно тестировать изменения в промежуточной среде до перехода на продуктив. Для больших миграций можно создать ветку, выполнить работу и слить обратно. Всегда понятно, какое намерение используется сейчас, а что только предлагается.
Получать данные из других систем. У вас, вероятно, уже есть управление активами для оборудования, IP-системы для адресов, поставщики каналов для подключения, CMDB для сервисов. Не дублируйте это. Вместо этого синхронизируйте. Установите чёткие правила о том, какая система владеет какими данными. Поддерживайте синхронизацию в обоих направлениях. Это даёт унифицированное представление всего без изобретения велосипеда.
4.1.2. Столпы#
Эти шесть столпов — не независимые функции; они образуют многоуровневую архитектуру. Моделирование определяет, что может быть выражено. Проектно-ориентированный подход переводит это выражение в технические артефакты. Потребление делает эти артефакты доступными для каждой системы, которой они нужны. Применение сохраняет надёжность данных при входе. Версионирование сохраняет запись намерения с течением времени, обеспечивая откат и аудит. Агрегация предотвращает превращение SoT в ещё один изолированный силос, получая авторитетные данные из систем, которые ими уже владеют.
Уберите любой из них — остальные деградируют. Без Применения Потребление обслуживает плохие данные. Без Версионирования нет способа рассуждать о том, что изменилось при возникновении проблемы. Без Агрегации операторы поддерживают дублирующиеся данные в разных системах, и SoT теряет доверие. Раздел 4.2 подробно рассматривает каждый из них.
Прежде чем детализировать шесть функциональностей, давайте уточним, что входит в область ответственности Источника истины.
4.1.3. Область ответственности#
Прежде чем погружаться в детали реализации, важно понять, за что отвечает источник истины, а за что — нет.
Что входит в область ответственности:
Источник истины управляет всеми данными намерения: полным определением того, как должна выглядеть ваша сеть. Это включает производственные конфигурации, промежуточные среды, ветки разработки и тестовые сценарии. Всё, что описывает “что вы хотите”, живёт здесь.
Что не входит в область ответственности:
Источник истины не выполняет несколько вещей, которые могут казаться связанными:
Данные наблюдаемости: Источник истины не хранит метрики, логи или состояние времени выполнения. Однако он определяет ожидания, с которыми вы будете сравнивать, например пороговые значения для оповещений или базовые показатели производительности. Реальные данные наблюдаемости хранятся в другом месте (рассматривается в Главе 6).
Взаимодействие с сетью: Источник истины не обращается к устройствам и не применяет конфигурации. Он предоставляет необходимые артефакты (конфигурации устройств, правила валидации, манифесты развёртывания), но не выполняет их. Это работа Исполнителя (Глава 5).
Логика оркестрации: Источник истины не определяет последовательность шагов или рабочих процессов для развёртывания изменений. Он определяет намеченное конечное состояние. То, как туда добраться (какие устройства первыми, какие шаги валидации, процедуры отката), принадлежит Оркестратору (Глава 7).
Думайте об источнике истины как о путеводной звезде вашей стратегии сетевой автоматизации. Это единственный, авторитетный ответ на вопрос “как должна выглядеть сеть?” Всё остальное в вашей системе автоматизации (выполнение, мониторинг, оркестрация) ссылается на эту истину для выполнения своей работы. Когда реальность отклоняется от намерения, источник истины говорит вам, чем реальность должна стать.
4.2. Функциональности#
Теперь поговорим о шести функциональностях, реализующих всё это на практике.
Каждая соответствует цели и столпу:
Моделирование: Определяет, какие данные хранятся и как они связаны. Модели устройств, интерфейсы, VLAN, каналы, сервисы. Позволяет развиваться по мере изменения потребностей.
Проектно-ориентированный подход: Переводит высокоуровневое намерение в реальные конфигурации устройств через шаблоны и логику.
Потребление: Как люди и системы реально получают и используют данные. Application Programming Interface (API), веб-интерфейс, Command Line Interface (CLI). Каждый получает контроль доступа, соответствующий его роли.
Применение: Гарантирует, что плохие данные не проникнут. Валидация, проверки уникальности, ссылочная целостность. Чёткие сообщения об ошибках.
Версионирование: Сохраняет полную историю. Кто, что и когда изменил, и зачем. Откат при необходимости.
Агрегация: Получает данные из других систем (CMDB, IPAM и т.д.) и поддерживает их синхронизацию.
graph LR
%% --- Subgraphs ---
subgraph Goals
direction TB
A1[Capture everything you need]
A2[Let operators think in business terms, not device syntax]
A3[Let people and machines access the data easily]
A4[Keep the data clean and trustworthy]
A5[Let people work in parallel without stepping on each other]
A6[Bring data in from other systems]
end
subgraph Pillars
direction TB
B1[Flexible Data Modeling Framework]
B2[Design and templates]
B3[APIs and interfaces]
B4[Data validation]
B5[Change history]
B6[Data aggregation]
end
subgraph Functionalities
direction TB
C1[Modeling]
C2[Design-Driven]
C3[Consumption]
C4[Enforcement]
C5[Versioning]
C6[Aggregation]
end
%% --- Row connections ---
A1 --> B1 --> C1
A2 --> B2 --> C2
A3 --> B3 --> C3
A4 --> B4 --> C4
A5 --> B5 --> C5
A6 --> B6 --> C6
%% --- Row gradient classes ---
classDef row1 fill:#eef7ff,stroke:#4a90e2,stroke-width:1px;
classDef row2 fill:#ddeeff,stroke:#4a90e2,stroke-width:1px;
classDef row3 fill:#cce5ff,stroke:#4a90e2,stroke-width:1px;
classDef row4 fill:#b3d8ff,stroke:#4a90e2,stroke-width:1px;
classDef row5 fill:#99ccff,stroke:#4a90e2,stroke-width:1px;
classDef row6 fill:#80bfff,stroke:#4a90e2,stroke-width:1px;
%% --- Apply classes per row ---
class A1,B1,C1 row1;
class A2,B2,C2 row2;
class A3,B3,C3 row3;
class A4,B4,C4 row4;
class A5,B5,C5 row5;
class A6,B6,C6 row6;
Ниже представлено архитектурное представление блока Намерения:
graph TB
%% Tier 1
subgraph T1[External]
A[Consumption]
end
%% Tier 2
subgraph T2[Data]
B[Design-Driven]
D[Modeling]
end
%% Tier 3
subgraph T3[Engine]
C[Aggregation]
E[Enforcement]
F[Versioning]
end
%% Tier connections
A <--> B
A <--> D
B <--> D
D <--> C
D <--> E
D <--> F
4.2.1. Моделирование#
Ваша модель данных критически важна: она определяет, что вы можете представить и насколько легко с ней работать. Как заметил Джордж Бокс: “Все модели неверны, но некоторые полезны.” Не существует идеальной модели, подходящей всем. По моему опыту, моделирование данных — это больше искусство, чем наука. Но определённые паттерны неизменно встречаются в успешных проектах.
4.2.1.1. Основополагающие принципы#
То, как вы организуете данные, имеет значение. Это определяет, что вы можете выразить и насколько эффективно системы могут проверять и использовать данные. Разные форматы имеют разные компромиссы. YAML читаем, но мало что проверяет. JavaScript Object Notation (JSON) работает везде, но многословен. Yet Another Next Generation (YANG) добавляет валидацию, но имеет крутую кривую обучения. Выбирайте исходя из реальных потребностей.
| Формат | Вариант использования | Преимущества | Компромиссы |
|---|---|---|---|
| YAML | Конфигурация, ручное редактирование | Читаем, краток | Ограниченная валидация схемы |
| JavaScript Object Notation (JSON) | Application Programming Interface (API), хранение документов | Инструментарий, экосистема | Многословен для людей |
| XML | Стандартизированный обмен | Обработка XSLT, схемы | Тяжёлый синтаксис |
| Protocol Buffers | Производительность, сериализация | Компактность, версионирование | Бинарный, требует генерации кода |
| YANG | Моделирование сетевых устройств | Отраслевой стандарт (RFC 6020), иерархические ограничения | Крутая кривая обучения |
Ваши данные существуют на разных уровнях. Одна и та же сетевая сущность может быть описана несколькими способами для разных целей:
- Сервисный уровень: Понятный для бизнеса (“настроить MPLS L3VPN для филиала X”)
- Технический уровень: Технические спецификации (“BGP AS 65001, route targets 65001:100, политики…”)
- Уровень устройства: Реальные конфигурации (“interface xe-0/0/0; unit 100;…”)
Хорошие модели соединяют эти уровни. Можно начать с бизнес-уровня, а затем автоматически генерировать конфигурации устройств. Но не всегда нужны все три уровня: зависит от того, что вы строите.
4.2.1.2. Хранение данных и масштаб#
Выбор способа хранения данных модели имеет глубокие последствия для согласованности, производительности и эволюции. Эти последствия становятся критическими по мере роста сети от сотен до сотен тысяч управляемых объектов.
Реляционные базы данных (например, MySQL, PostgreSQL): Это надёжный выбор для большинства команд — и я имею это как комплимент. Они обеспечивают согласованность схемы, предоставляют ACID-транзакции, и каждый инженер в вашей команде уже знает SQL. Они отлично справляются с представлением нормализованных иерархий (VLAN, содержащие интерфейсы) и предотвращением аномалий данных. Недостаток: изменения схемы болезненны при масштабировании, и производительность падает при глубоких соединениях по миллионам строк. Но это хорошая проблема: это значит, что вы действительно что-то развернули.
Документо-ориентированные базы данных (например, MongoDB, CouchDB): Хороши при необходимости гибкости схемы и горизонтальной масштабируемости. Документы естественно моделируют вложенные структуры (устройство со всеми конфигурациями и метаданными как один объект). Но вот загвоздка: теперь вы несёте ответственность за согласованность между документами, и сложные запросы быстро становятся дорогостоящими. Если у вас нет конкретной причины выбирать документо-ориентированный подход, оставайтесь с реляционным.
Графовые базы данных (например, Neo4j): Они реально лучше, когда связи важнее объектов: “к каким VLAN подключён этот интерфейс? Какие устройства маршрутизируют между этими двумя локациями?” Они эффективно обходят связи произвольной глубины. Но если вы не делаете постоянно сложные запросы топологии, вы выбираете экзотический вариант. Ваша операционная команда этого не знает, инструментарий менее зрелый, и производительность записи отстаёт при простых обновлениях. Графовые базы данных решают реальные проблемы, но сначала убедитесь, что эти проблемы у вас реально есть.
flowchart TD
Q1{Primary requirement?}
Q1 -->|Traverse complex relationships at depth| Q2{Constant topology queries?}
Q1 -->|Schema evolves frequently| DB_D[Document store]
Q1 -->|Structured queries, referential integrity| DB_R[Relational database]
Q2 -->|Yes| DB_G[Graph database]
Q2 -->|Occasionally| DB_R
style DB_R fill:#ccffcc,stroke:#28a745
style DB_G fill:#cce5ff,stroke:#4a90e2
style DB_D fill:#ffffcc,stroke:#ffc107
Подробнее о хранении данных, с иной точки зрения, в главе об Наблюдаемости.
Выбор базы данных — один из ключевых дифференциаторов среди продуктов в этой области. Например, NetBox и Nautobot используют реляционные базы данных, тогда как Infrahub использует графовую базу данных, как показано в разделе 4.2.8.
Хранение также может быть реализовано с использованием файлового хранилища с моделями данных типа YAML или JavaScript Object Notation (JSON) (или CSV), обычно отслеживаемых в системах Git для управления версиями.
Большинство производственных систем Источника истины используют полиглот-хранение: реляционная база данных для авторитетного намерения и связей, документальное хранилище или Git для гибкости и кэширования, и возможности графа для анализа топологии.
Насколько детальной должна быть модель? Это важно для производительности. Если вы моделируете каждый интерфейс на каждом устройстве как отдельный объект, в итоге получите более 50 000 объектов для средней сети. Запросы замедляются. Обновления становятся болезненными.
Практический подход: используйте шаблоны для общих паттернов. Скажите “интерфейсы 1-40 используют этот стандартный шаблон” и отслеживайте только исключения. Это 2 объекта вместо 40, запросы остаются быстрыми, и рендеринг по-прежнему работает.
В Главе 11 мы рассмотрим, как такие решения влияют на производительность.
4.2.1.3. Сетевые домены данных#
Комплексные реализации Источника истины обычно моделируют следующие взаимосвязанные домены:
- Инвентарь и активы: Физические и логические устройства, спецификации оборудования, серийные номера, дата закупки, условия контракта, стадия жизненного цикла
- Инфраструктура датацентра: Местоположения (географические и иерархические), здания, этажи, комнаты, стойки, распределение питания, маршруты кабелей
- Управление IP-адресами (IPAM): Пулы адресов, подсети, назначения, разрешение DNS, области DHCP, отслеживание использования
- Виртуализация и облако: VPC, подсети, группы безопасности, вычислительные экземпляры, хранилище, отношения оркестрации контейнеров
- Подключение: Физические каналы (MPLS, Ethernet), виртуальные туннели, отношения пиринга, выделение полосы пропускания, политики QoS
- Маршрутизация: BGP-сообщества, автономные системы, политики маршрутизации, списки префиксов, route targets для сервисов L3VPN
- Сервисы: Определения логических сервисов (L3VPN, L2VPN, прохождение брандмауэра), соответствия сервис-устройство, SLA
- Безопасность и соответствие требованиям: Списки контроля доступа, правила брандмауэра, зоны безопасности, теги соответствия, требования аудита
- Управление: Параметры SNMP, подписки gNMI, источники NTP, получатели syslog, интеграция TACACS+/RADIUS
Эти домены взаимозависимы: Маршрутизация ссылается на Подключение, Сервисы охватывают Инвентарь и IPAM, Политики безопасности применяются как к Устройствам, так и к Сервисам. Хорошо спроектированный SoT моделирует эти связи явно, а не рассматривает каждый домен как изолированную таблицу.
graph TD
INV[Inventory and Assets]
DC[DC Infrastructure]
IPAM[IP Address Management]
VIRT[Virtualization and Cloud]
CONN[Connectivity]
ROUTE[Routing]
SVC[Services]
SEC[Security and Compliance]
MGMT[Management]
DC --> INV
INV --> IPAM
INV --> MGMT
CONN --> INV
VIRT --> IPAM
ROUTE --> CONN
SVC --> INV
SVC --> ROUTE
SVC --> IPAM
SEC --> INV
SEC --> SVC
classDef foundation fill:#ddeeff,stroke:#4a90e2,stroke-width:2px
classDef overlay fill:#e8f5e9,stroke:#28a745
classDef policy fill:#fff3cd,stroke:#ffc107
class INV,IPAM,CONN foundation
class ROUTE,VIRT,DC,MGMT overlay
class SVC,SEC policy
Помимо сетевых доменов, необходимы и многие другие типы данных. Например, хранилище секретов для учётных данных. В более широком смысле, комплексное управление данными вписывается в глобальную систему управления ИТ-инфраструктурой.
Хочу поделиться распространённым вопросом для многих команд, выбирающих между сетевым источником данных, таким как NetBox, и универсальным, таким как ServiceNow. По моему опыту, даже несмотря на возможность достичь аналогичных результатов, тот факт, что ServiceNow является общекорпоративной системой, делает её сложнее (и медленнее) в эволюции, замедляя сетевые команды в использовании полного сетевого представления.
Классификация данных и общие атрибуты
В сетевых доменах определённые паттерны классификации встречаются постоянно. Хорошо спроектированные модели включают следующие основополагающие атрибуты для обеспечения согласованного управления данными:
- Роль: Какую цель служит этот объект? (core, distribution, access; primary, secondary)
- Статус: Активен, запланирован, выводится из эксплуатации или выведен?
- Тип: Что это за объект? (VLAN, устройство, канал, сервис)
- Владение: Какая команда или бизнес-единица управляет этим?
- Расположение: Где находится этот ресурс географически или организационно?
4.2.1.4. Паттерны проектирования моделей: расширяемость, полиморфизм и миграции#
Некоторые решения поставляются со встроенной моделью, основанной на представлении создателей о том, как должны выглядеть сети. Это замечательно, если ваша сеть соответствует этому предположению, и не так хорошо, если не соответствует. Другие решения позволяют строить с нуля: отличная гибкость, но требует дисциплины. Обычно лучшим подходом является гибрид: используйте встроенные модели для общих случаев (80%, которые делают все), но убедитесь, что можно расширить их для конкретных потребностей.
Спектр: от мнения к пользовательскому
Здесь есть спектр, и стоит понять, где вы находитесь:
Строго ориентированные модели (например, NetBox “из коробки”):
- Плюсы: Быстрое развёртывание, меньше принятия решений, встроенные лучшие практики
- Минусы: Болезненно, если ваша сеть не вписывается в шаблон, изменить модель сложно
Полностью пользовательские модели (построить своё с нуля, как Infrahub):
- Плюсы: Идеальное соответствие конкретным потребностям, никаких лишних полей
- Минусы: Дополнительное время на проектирование, много проб и ошибок, не от кого копировать (но есть ориентиры)
Хотя Infrahub позволяет строить полностью пользовательские модели, он также поставляется с мнениевыми моделями для быстрого начала.
С чего фактически начать? Вот что я говорю всем: начинайте с инструментами с мнениевыми моделями, такими как NetBox, Nautobot или Infrahub. Точка. Мне всё равно, насколько особенной вы считаете свою сеть. Команды “мы построим собственную идеальную модель” всё ещё моделируют спустя два года, тогда как команды с этими инструментами отгрузили рабочие модели много месяцев назад.
Вы не Google (или может быть, да?). Во многих случаях вы не строите гиперскейловое облако. Используйте то, что есть, расширяйте, когда достигнете реальных ограничений (не воображаемых), и поставьте что-то работающее.
Очевидно, если вы заранее предвидите особый сетевой случай использования, можно рассмотреть, какой инструмент лучше его поддержит, но не изобретайте колесо полностью с первого дня.
Единственное решение, которое имеет значение: можно ли расширять, не переписывая? Если добавление пользовательского поля для отслеживания “центра затрат” требует пересборки всей схемы — бегите. Если можно добавить его как пользовательский атрибут за 20 минут — вы нашли правильный инструмент.
Вам нужна 80%-я стандартизация с 20%-й гибкостью (справиться со своей конкретной реальностью). Всё, претендующее на “бесконечную гибкость”, потребует бесконечного времени на настройку.
Полиморфизм: одна модель, много вариантов
Не все интерфейсы одинаковы. Физический оптический порт и туннельный интерфейс имеют некоторые общие свойства, но это разные сущности. Можно создать полностью отдельные модели для каждого, но это быстро запутает и ограничит удобство использования.
Лучший подход: определить общую базовую модель для общего, а затем создать специализированные варианты для отличающихся деталей.
# All interfaces share these basics
interfaces:
- name: "eth0"
type: "physical"
status: "up"
mtu: 1500
ipv4_address: "192.0.2.1/24"
# But a physical optical port has extra stuff
- name: "eth0"
type: "physical_optical"
status: "up"
mtu: 1500
ipv4_address: "192.0.2.1/24"
optics_module: "100GBASE-LR4"
tx_power_dbm: -2.5
rx_power_dbm: -8.3
laser_temperature: 48.2
# And a tunnel looks totally different underneath the covers
- name: "tun-vpn-dallas"
type: "tunnel_gre"
status: "up"
mtu: 1476
ipv4_address: "10.0.0.1/30"
tunnel_source: "203.0.113.1"
tunnel_destination: "198.51.100.5"
tunnel_encap: "GRE"
tunnel_key: 100Таким образом, скрипты могут запрашивать “все интерфейсы этого устройства”, не зная, имеют ли они дело с оптикой или туннелями. Но когда нужны оптические специфические детали (считать значения TX мощности), можно обратиться к специализированным полям. Добавить новый тип интерфейса в будущем? Без проблем: просто добавить ещё один вариант.
Модели меняются: планируйте это
Сети живут десятилетиями. Ваша модель не останется статичной. Вы будете добавлять новые поля, изменять связи, устаревшие вещи не работают — всё это не редкость. Но нельзя просто переключить тумблер и сломать всё, что работает на старой схеме.
Задача в том, что при изменении модели многое ниже по потоку может сломаться: валидаторы нуждаются в новых правилах, API изменяют возвращаемые данные, запросы к базе данных предполагают определённые столбцы, шаблоны нуждаются в других путях полей, отчёты написаны под старую структуру. Всё это нужно адаптировать или, по крайней мере, не катастрофически сломать. Вот как справляться с изменениями без взрыва:
Помечайте вещи как устаревшие перед удалением. Если поле уходит, предупредите об этом за 2-3 релиза. Дайте время для миграции.
Поддерживайте псевдонимы полей в период перехода. Старый код запрашивает
device_name? Перенаправляйте под капотом наhostname. Ваш API по-прежнему работает, у людей есть время обновить автоматизацию.Создавайте помощники для миграции. При реструктуризации данных (например, перемещение интерфейсов из плоского списка в вложенные под устройства) предоставляйте скрипты, выполняющие эту работу.
Тестируйте со всем, что зависит от ваших данных. Перед развёртыванием изменений схемы:
- API по-прежнему возвращает данные по-старому? (через псевдонимы)
- Шаблоны по-прежнему рендерятся?
- SQL-запросы по-прежнему работают?
- Интеграции с внешними системами по-прежнему парсят то, что получают?
Ожидайте смешанных версий в производстве некоторое время. Крупные организации часто имеют устройства на трёх разных версиях схемы одновременно:
150 devices on schema 1.9 (old) 300 devices on schema 2.0 (current) 50 devices on schema 2.1 (beta testing)
Вашей системе нужно обрабатывать все три без сбоев. Эта сложность того стоит: сети слишком важны, чтобы ломать их небрежными изменениями схемы.
4.2.1.5. Шаблоны конфигурации#
Шаблоны превращают абстрактное намерение (“я хочу VLAN”) в реальные команды Command Line Interface (CLI). Вот ключевое правило: шаблоны содержат логику, не данные. Шаблон говорит “использовать ID VLAN из модели данных, вывести его здесь.” Реальный ID VLAN приходит из данных, а не из шаблона. Это сохраняет переносимость и тестируемость данных. Jinja2 популярен из-за читаемости, интеграции с Python и Ansible и практичности для реальных сетей. Однако это не единственный вариант — существует множество допустимых альтернатив.
Например, при наличии структуры данных для интерфейсов:
interfaces:
- name: Ethernet1
description: Uplink to core
enabled: true
- name: Ethernet2
description: Server port
enabled: falseИ шаблона Jinja2 для конфигурации CLI:
# Interfaces
{% for iface in interfaces %}
interface {{ iface.name }}
description {{ iface.description }}
{% if iface.enabled %}
no shutdown
{% else %}
shutdown
{% endif %}
{% endfor %}Генерируется следующий вывод CLI:
# Interfaces
interface Ethernet1
description Uplink to core
no shutdown
interface Ethernet2
description Server port
shutdownОбратите внимание на чёткое разделение задач между данными и артефактом конфигурации.
Интересной альтернативой Jinja является декларативный язык конфигурации CUE, объединяющий несколько функциональных возможностей работы с данными:
- Необработанные данные, как YAML
- Валидация и схема данных, как JSON Schema (подробнее в разделе о применении)
- Динамическая генерация данных, как Jinja
CUE рассматривает конфигурацию как типизированные, компонуемые данные с принудительными инвариантами, а не как слабо структурированный текст (как Jinja).
4.2.2. Проектирование по намерению#
Когда у вас 50 устройств и 30 VLAN, ими можно управлять по отдельности: создавать каждый VLAN, настраивать каждый интерфейс, вручную выделять каждый IP-адрес. Это утомительно, но выполнимо.
Когда у вас 5 000 устройств и сотни сервисов, ручное управление невозможно. Добавление нового филиала потребовало бы вручную указывать более 100 параметров конфигурации для каждого местоположения. Блок проектирования по намерению решает эту проблему: операторы описывают желаемое на высоком уровне (“добавить филиал”), а система разворачивает это в полные технические спецификации.
4.2.2.1. От бизнес-намерения к техническим данным#
Пример сценария - “Добавить офис в Далласе”:
Бизнес-намерение (высокий уровень):
{
"type": "branch_office",
"location": "dallas-tx",
"site_code": "DAL-01",
"circuit_count": 2,
"employee_count": 50,
"applications": ["erp", "voip", "video"]
}Обработка проекта
flowchart LR
A[Business Intent]
B[Apply Template]
C[Allocate Resources]
D[Resolve Logic]
E[Render Details]
F[Objects for Executor]
A --> B --> C --> D --> E --> F
style A fill:#fff3cd,stroke:#ffc107
style B fill:#ffe6cc,stroke:#fd7e14
style C fill:#d4edda,stroke:#28a745
style D fill:#cce5ff,stroke:#4a90e2
style E fill:#e2d9f3,stroke:#6f42c1
style F fill:#d1ecf1,stroke:#17a2b8
| Фаза | Задачи |
|---|---|
| 1. Применение шаблона | Создание объекта площадки Выделение подсетей из пула делегирования (региональный IPAM) Создание VLAN для данных, голоса и гостевого доступа Определение зон безопасности и правил межсетевого экрана |
| 2. Выделение ресурсов | Следующая доступная подсеть /22 для площадки: 10.15.0.0/22 Следующий доступный диапазон VLAN: 2010-2014 Следующее доступное BGP-сообщество: 65001:2010 |
| 3. Разрешение логики | site_count < 100 сотрудников? Да - шаблон малого офиса Нужны резервные каналы? Да - создать 2 BGP-соседа Приложения = [erp, voip]? Да - добавить политики межсетевого экрана |
| 4. Рендеринг деталей | Конфигурация PE-устройства (BGP, маршрутные цели, QoS для голоса) Конфигурация CE-устройства (LAN-интерфейсы, VLAN, NTP) Политика межсетевого экрана (разрешить трафик ERP, приоритет голосу) DNS-записи для сервисов офиса Настройка мониторинга (SNMP, syslog, оповещения) |
| 5. Результат | Более 50 объектов конфигурации, готовых к развёртыванию |
Это преобразует намерение высокого уровня с минимальными усилиями в исчерпывающие технические детали.
4.2.2.2. Шаблоны проектирования и многократно используемые строительные блоки#
Эффективные системы проектирования опираются на библиотеки шаблонов.
Библиотека шаблонов сетевого проектирования
| Шаблон | Компоненты |
|---|---|
| Малый филиальный офис | Один граничный маршрутизатор (с резервированием через резервный канал) 2-3 VLAN (данные, голос, гостевой) Один MPLS VPN с резервным BGP-пиром QoS для голоса (классы EF, AF) Правила межсетевого экрана: ограниченный доступ, кроме ERP и VoIP |
| Средний региональный узел | Резервные граничные маршрутизаторы (активный-резервный) 10-15 VLAN (по отделам + гостевой + OOB) Несколько MPLS VPN (некоторые настраиваются под конкретные приложения) Сложный QoS (6 классов) Продвинутые политики межсетевого экрана (уровень приложений) |
| Граница центра обработки данных | Четырёхкратно резервированная топология Clos Более 100 VLAN (автогенерация для каждого клиента) BGP unnumbered, multipath Автоматическое выделение VLAN |
Каждый шаблон закодирует проверенные архитектурные решения. Отклонение от них требует явного согласования, но применение шаблонов должно рассматриваться как штатная операция.
4.2.2.3. Воспроизводимость проектирования#
Вот в чём проблема: вы создаёте проект площадки в понедельник и выделяете VLAN 100. Во вторник проектируете другую площадку и выделяете VLAN 101. Но если вы повторно запустите проект понедельника через шесть месяцев для валидации, система может выделить VLAN 102, потому что VLAN 100 уже занят.
Это не воспроизводимо. Решение: при каждом запросе на проектирование записывайте, какой проект получил какие ресурсы. Если тот же запрос поступит снова, вы получите тот же VLAN. Для этого требуется постоянно отслеживать соответствия запрос-ресурс и всегда выделять ресурсы в одном порядке.
- Детерминированный порядок выделения: всегда перебирать кандидатов в одном и том же порядке
- Атомарное выделение: резервирование ресурсов атомарно; частичное выделение невозможно
Именно поэтому многие системы проектирования используют контентно-адресуемое хранилище (хэш проекта) для обеспечения согласованности.
4.2.2.4. Различие между рендерингом и сборкой#
Системы проектирования разделяют две фазы:
| Фаза | Входные данные | Выходные данные | Побочные эффекты | Отвечает на вопросы | Варианты использования |
|---|---|---|---|---|---|
| Рендеринг | Проект высокого уровня | Технические спецификации | Нет - ресурсы не выделяются, изменения не применяются | “Что будет создано?" “Есть ли ошибки?" “Могу ли я увидеть предлагаемое расширение данных?” | Просмотр перед утверждением Тестирование валидации Оценка масштаба изменений |
| Сборка | Отрендеренные спецификации | Реальные изменения (IP закреплены, VLAN созданы, конфигурации применены, след аудита) | Atomic Operation, Идемпотентность, отслеживаемость, возможность отката | “Что было реально развёрнуто?" “Когда это произошло?" “Могу ли я откатиться?” | Развёртывание в продакшн Резервирование ресурсов Запуск исполнительных рабочих процессов |
Поддержка рендеринга без сборки обеспечивает:
- Безопасную валидацию перед фиксацией
- Анализ гипотетических сценариев без риска
- Рабочие процессы командного просмотра и утверждения
- Предварительное развёртывание в тестовой среде
4.2.2.5. Версионирование и эволюция проектов#
Сетевые проекты со временем развиваются. Появляются новые шаблоны. Инструменты улучшаются. Проекты 2020 года могут требовать обновления к 2025 году.
Проблемы версионирования проектов:
Версия проекта 1 (2020): Шаблон филиального офиса: один маршрутизатор, 2 VLAN
Версия проекта 2 (2023): Шаблон филиального офиса: двойной маршрутизатор (резервирование), 4 VLAN, улучшенная безопасность
Что происходит с филиалами, развёрнутыми по версии 1?
- Продолжать работу на старой версии? (технический долг по безопасности)
- Принудительно обновить все филиалы? (риск при изменениях)
- Постепенная миграция? (операционная сложность)
Решения:
Проект как код с версионированием
designs/
├─ branch_office_v1.yaml (deprecated 2023-01-01)
├─ branch_office_v2.yaml (current)
└─ branch_office_v2_beta.yaml (testing)
Sites:
- site: DAL-01
design: branch_office_v2 (references specific version)
design_parameters: {...}Это позволяет:
- Точно знать, какая версия проекта сгенерировала каждую площадку
- Постепенную миграцию (обновление площадка за площадкой)
- Откат к v1, если v2 содержит проблемы
- Тестирование v3 в среде разработки перед выкаткой
Работа с исключениями (snowflake)
Большинство площадок используют шаблон design_v2. Но площадка DAL-01 имеет особые требования:
- Дополнительное стоечное пространство (особенность старого здания)
- Нестандартная IP-адресация (унаследованное выделение)
- Особое правило межсетевого экрана (историческое бизнес-требование)
Решение:
- Применить design_v2 как базу
- Применить переопределения для конкретной площадки
- Отслеживать переопределения отдельно (документировать исключение)
Это предотвращает:
- Встраивание исключений в шаблон (загрязняет проект)
- Ручную настройку исключений (дрейф со временем)
- Потерю контекста о том, почему исключения существуют
4.2.3. Потребление#
Данные, заблокированные в базе данных, бесполезны. Уровень потребления - это то, как люди и системы реально получают доступ к данным. Сделайте его простым - и получите доверие. Сделайте его сложным - и люди найдут обходные пути.
4.2.3.1. Проектирование и безопасность API#
Разные стили API служат разным паттернам потребления. Ниже приведены некоторые из наиболее популярных на сегодняшний день:
Сравнение стилей API
| Интерфейс | Паттерн запроса | Вариант использования | Сильные стороны | Компромиссы |
|---|---|---|---|---|
| Representational State Transfer (REST) | HTTP-глаголы (GET, POST, PATCH, DELETE) по URL ресурсов | CRUD общего назначения | Прост, широко понятен, без состояния | Может требовать множества запросов; проблемы Versioning |
| GraphQL | Единая точка входа, клиент указывает точные нужные поля | Сложные запросы по нескольким ресурсам | Гибкость, клиент-ориентированность, снижение избыточной выборки | Более сложная реализация сервера, риск запроса N+1 |
| gRPC | RPC на основе Protobuf через HTTP/2 | Высокая производительность, малая задержка | Двунаправленная потоковая передача, бинарная эффективность, в 10-100 раз быстрее REST | Кривая обучения, ограниченная поддержка браузеров |
| Webhooks | Сервер отправляет изменения на зарегистрированные точки входа | Реактивная автоматизация, синхронизация в реальном времени | Асинхронность, слабая связанность, отсутствие накладных расходов на опрос | Ненадёжная доставка, сложность повторных попыток, проблемы безопасности |
Эффективные стратегии потребления часто сочетают несколько интерфейсов:
- REST для удобных человеку простых операций
- GraphQL для сложных мультидоменных запросов с фильтрацией авторизации
- gRPC/потоковая передача для высокопроизводительной автоматизации
- Webhooks для реактивных нижестоящих систем
Заметка об MCP (Model Context Protocol) Помимо традиционных стилей API, новые модели взаимодействия, такие как Model Context Protocol (MCP), позволяют ИИ-агентам взаимодействовать с системами структурированным, инструментально-ориентированным способом. В отличие от REST или gRPC, которые определяют транспорт и семантику запросов, MCP фокусируется на безопасном обнаружении возможностей, контекстуальном извлечении данных и контролируемом выполнении действий для агентных рабочих процессов. Этот паттерн особенно актуален в операциях с поддержкой ИИ и в случаях наблюдаемости, где автоматизированным системам рассуждения требуется структурированный доступ к телеметрии, конфигурации и инструментам исправления. Несмотря на то что стандарт ещё развивается, MCP представляет собой сдвиг от ресурсно-ориентированных API к агентно-ориентированным моделям взаимодействия.
Одно критическое правило: аутентификацию и авторизацию следует выполнять на уровне API, а не ниже по стеку. Это предотвращает дыры в безопасности и обеспечивает корректный аудит.
Подробнее о последствиях для безопасности - в Главе 12.
4.2.3.2. Операции API: версионирование, производительность и кэширование#
После проектирования и обеспечения безопасности API критически важными становятся операционные вопросы эволюции и производительности.
Версионирование и эволюция API
Сетевая инфраструктура долговечна; системы автоматизации должны развиваться, не нарушая операционные рабочие процессы.
Версионирование по URL:
/api/v1/devicesи/api/v2/devicesподдерживают отдельные реализации- Плюс: явное, удобное для отладки, клиенты сами выбирают момент обновления
- Минус: вы поддерживаете несколько реализаций (это на самом деле хорошо: это вынуждает планировать миграции)
Версионирование через заголовок: та же точка входа, версия в
Accept: application/vnd.company+json; version=2- Плюс: единая точка входа, более чистые URL
- Минус: не видно в логах, сложнее отлаживать, клиенты постоянно путаются
В любом случае объявляйте о критических изменениях за 6-12 месяцев через заголовки устаревания:
Deprecation: true
Sunset: Mon, 01 Jan 2026 00:00:00 GMT
Link: <https://docs/migration>; rel="deprecation"Я рекомендую использовать версионирование по URL: /api/v1/devices и /api/v2/devices. Да, версионирование через заголовок выглядит чище в документации. Но когда что-то ломается в 3 часа ночи и вы ищете в логах, вы хотите сразу видеть /v1/ против /v2/, а не копаться в заголовках запроса, чтобы выяснить, какая версия API вызвала проблему. Ваше будущее дежурное “я” скажет вам спасибо.
Производительность и кэширование
Потребление данных по одному объекту может хорошо работать для некоторых случаев использования, но по мере роста масштаба в конечном итоге достигаются пределы производительности.
Массовые операции позволяют обновлять тысячи объектов в одном вызове API. Это необходимо для масштаба, но влечёт компромиссы:
API для одного объекта:
POST /api/devices/deviceПреимущества: валидирует каждое изменение, чёткие сообщения об ошибках для каждого объекта Стоимость: 10 000 обновлений устройств = 10 000 API-запросов + циклы обмена = минутыМассовый API:
POST /api/devices/bulk-updateПреимущества: один цикл обмена для 10 000 обновлений, можно распараллелить обработку на бэкенде Стоимость: сокращённая валидация (пропуск дорогостоящих проверок), сложнее сообщать об ошибках для каждого объекта
Другие альтернативы для улучшения потребления данных включают ограничение области через:
Пагинация и фильтрация не дают клиентам случайно загружать в память миллионы объектов или получать таймауты:
GET /api/devices?location=datacenter-1&status=active&limit=100&offset=0Пагинация на основе курсора имеет преимущества перед пагинацией на основе смещения при работе с большими наборами данных, так как более эффективна для распределённых систем и остаётся согласованной даже при изменении данных между запросами.
Стратегии кэширования существенно улучшают производительность:
- Кэширование на стороне сервера: кэш Redis для “всех устройств в местоположении X” инвалидируется при изменении любого устройства в этом местоположении
- Кэширование на стороне клиента: HTTP ETag позволяет клиентам проверять кэшированные данные без повторного запроса
- Обход уровня валидации: для запросов только на чтение пропускать проверки валидации
Ограничение частоты запросов защищает бэкенды от перегрузки. Например:
- 10 запросов/секунду на пользователя
- 1 000 запросов/минуту на API-ключ
- Сигналы обратного давления (HTTP 429) сообщают клиентам, что нужно замедлиться
4.2.3.3. Контекстно-зависимое моделирование данных#
Разным людям нужны разные вещи. Сетевые инженеры хотят искать и находить данные, редактировать конкретные поля с обратной связью о валидации, видеть взаимосвязи. Рабочим процессам автоматизации нужны API, транзакции и webhooks. Операционным командам нужны ориентированные на задачи представления и журналы аудита. Бизнесу нужны отчёты без технических деталей. Внешние системы должны синхронизировать данные в обоих направлениях.
Обратите внимание, что пользовательский интерфейс блока потребления относится к уровню Представления. Подробнее об этом - в Главе 8.
Данные должны адаптироваться к контексту каждого потребителя. Например, не все детали устройства должны быть доступны каждой персоне. Контекстно-зависимая настройка делает потребление данных более эффективным.
Сетевому инженеру нужны интерфейсы и детали маршрутизации. Финансовому отделу - стоимость и информация о гарантии. Службе безопасности - зона соответствия требованиям. Вместо того чтобы возвращать все 500 полей всем, давайте каждому потребителю только то, что ему нужно. Это можно сделать с помощью параметров API-запроса (?view=network_engineer) или GraphQL, позволяя запрашивать конкретные поля.
Проблема: одна модель данных не может подойти всем потребителям
Рассмотрим один объект устройства в SoT, содержащий сотни атрибутов:
- Аппаратные детали (модель, серийный номер, версия прошивки)
- Конфигурация сети (IP-адреса, VLAN, протоколы маршрутизации)
- Операционные метаданные (местоположение, центр затрат, истечение гарантии)
- Связи с сервисами (какие клиенты используют это устройство)
- Контекст безопасности (зона соответствия требованиям, политики доступа)
Разным потребителям нужны принципиально разные представления этих данных:
Пример: устройство “router-core-01” в разных контекстах
| Потребитель | Контекст | Представление данных | Ключевые атрибуты |
|---|---|---|---|
| Сетевой инженер | Устранение проблем с подключением | Сетевое представление | Интерфейсы, IP-адреса, BGP-пиры, маршруты, VLAN, статус аплинка |
| Финансовый отдел | Распределение затрат | Бизнес-представление | Центр затрат, график амортизации, статус гарантии, дата покупки, поставщик |
| Служба безопасности | Аудит соответствия требованиям | Представление безопасности | Зона соответствия, политики доступа, последнее сканирование безопасности, уровень патчей, открытые уязвимости |
| Рабочий процесс автоматизации | Развёртывание конфигурации | Исполнительное представление | IP-адрес управления, ссылка на учётные данные, платформа устройства, имя шаблона конфигурации |
| Каталог сервисов | Анализ влияния на клиентов | Сервисное представление | Обслуживаемые клиенты, размещённые сервисы, уровень SLA, группа резервирования |
Паттерны реализации
Трансформации на основе представлений: API-запросы указывают желаемый контекст, сервер трансформирует модель данных соответственно
GET /api/devices/router-core-01?view=network-engineer → Returns: {interfaces: [...], bgp_peers: [...], vlans: [...]} GET /api/devices/router-core-01?view=finance → Returns: {cost_center: "...", warranty_expiry: "...", purchase_cost: ...}Выбор полей в GraphQL: потребители явно запрашивают только нужные поля
query NetworkEngineerView { device(name: "router-core-01") { interfaces { name, ip_address, status } bgp_neighbors { peer_ip, state } } } query FinanceView { device(name: "router-core-01") { cost_center purchase_date warranty_expiration } }Проекционные слои: бэкенд вычисляет производные представления, оптимизированные для конкретных паттернов доступа
- Граф сетевой топологии: устройства как узлы, соединения как рёбра (для визуализации топологии)
- Дерево зависимостей сервисов: иерархическое представление сервисов - устройств - компонентов (для анализа влияния)
- Матрица соответствия: устройства, сгруппированные по зонам со статусом соблюдения политик (для аудита)
Предметно-специфические языки (DSL): специализированные языки запросов, ориентированные на ментальные модели пользователей
- Сетевой инженер: “Показать все устройства с опущенной BGP-сессией в datacenter-1”
- Финансы: “Рассчитать ежемесячную амортизацию для устройств, купленных в Q3 2025”
- Безопасность: “Перечислить устройства в зоне PCI с критическими CVE”
Преимущества контекстно-зависимого моделирования
| Преимущество | Влияние | Пример |
|---|---|---|
| Снижение когнитивной нагрузки | Пользователи видят только релевантные данные для своей задачи | Финансовый отдел никогда не видит конфигурации VLAN; сетевые инженеры не видят заявки на покупку |
| Оптимизация производительности | API возвращает минимум данных, снижая пропускную способность и нагрузку | Мобильное приложение запрашивает сводку устройства (5 полей) против полного объекта устройства (200+ полей) |
| Снижение безопасности через неизвестность | Чувствительные поля фильтруются в зависимости от роли потребителя | Учётные данные, зоны безопасности скрыты от неавторизованных потребителей |
| Стабильность API | Изменения схемы бэкенда не ломают потребителей, если представления остаются стабильными | Добавление новых полей устройства не влияет на существующих потребителей представления network-engineer |
| Поддержка нескольких языков | Имена полей, перечисления, описания переводятся в зависимости от локали потребителя | Оператор, говорящий по-каталански, видит “Ubicació” вместо “Location” |
Однако необходимо учитывать проблемы и другие соображения:
- Накладные расходы на поддержку представлений: каждое новое представление требует определения, тестирования, документации
- Согласованность между представлениями: одни и те же данные, доступные через несколько представлений, должны оставаться согласованными
- Сложность производительности: вычисление динамических представлений добавляет задержку; требуются стратегии кэширования
- Обнаружение: потребители должны знать, какие представления существуют и когда их использовать
Контекстно-зависимое моделирование - это мост между оптимизацией структуры данных (как мы эффективно храним данные) и оптимизацией потребления (как потребители получают доступ к данным естественным образом). Оно признаёт, что Источник истины служит многим хозяевам, каждый из которых имеет собственную перспективу на то, что означает “истина” в их работе.
4.2.3.4. Интерфейсы с поддержкой ИИ#
Применение ИИ на уровне Потребления снижает когнитивную нагрузку при работе с большими, сложными моделями данных. Три паттерна становятся всё более распространёнными в современных реализациях SoT:
Контекстные подсказки: когда вы вводите имя устройства, система предлагает соответствующие устройства, которые вы редактировали ранее в этом местоположении. При создании сервиса она предлагает разумные технические параметры на основе типа сервиса и исторических паттернов. Это снижает ошибки ввода без добавления трения валидации.
Предупреждения об аномалиях при записи: перед массовым обновлением интерфейс отмечает, если операция необычна по сравнению с историческими паттернами. Массовое переназначение VLAN, которое обычно затрагивает 10 устройств, но собирается затронуть 400, вызывает шаг подтверждения. Система не блокирует операцию; она задаёт вопрос.
Запросы на естественном языке: интерфейсы на основе LLM позволяют операторам запрашивать SoT на обычном языке: “Какие устройства в building-b не имеют тега мониторинга?” Интерфейс переводит это в структурированный API-запрос и возвращает результаты в читаемой человеком форме. Это ценно для специальных расследований, но не является заменой структурированных интерфейсов автоматизации.
Все три паттерна зависят от одной и той же основы: доступа к историческим данным операций и хорошо смоделированной схемы, над которой ИИ может рассуждать. Раздел 4.2.4.4 описывает, как аналогичные техники применяются к валидации качества данных на пути записи.
4.2.4. Применение#
Плохие данные разрушают автоматизацию. Неверное намерение приводит к сбоям сети, нарушениям безопасности и дезориентации операционных команд. Применение ограничений - ваш страж: оно не пропускает явно неверные данные и чётко объясняет почему.
4.2.4.1. Схема и применение ограничений#
| Тип валидации | Цель | Примеры правил | Пример ошибки |
|---|---|---|---|
| Валидация схемы | Обеспечить типы и форматы данных | VLAN id: целое 1-4094 Имя VLAN: строка, макс. 32 символа Площадки VLAN: массив ссылок на площадки Статус VLAN: перечисление(active, planned, deprecated) | { "id": 5000, "name": "CUSTOMER-VLAN" }Ошибка: VLAN ID 5000 превышает максимум 4094 |
| Ограничения уникальности | Предотвратить дублирующиеся записи | VLAN 100: уникален на площадку IP 192.0.2.1: уникален во всём IPAM Имя хоста “pe-01”: уникально в регионе | Попытка создать второй “pe-01” в том же регионе Ошибка: Имя хоста уже существует |
| Референциальная целостность | Обеспечить сохранность связей | Канал ссылается на: site_a, site_b (должны существовать в Площадках), vendor (должен существовать в Поставщиках) | Удаление site_a, на который ссылается канал Варианты: отклонить удаление, каскадное удаление или осиротение со статусом “площадка неизвестна” |
| Диапазонная валидация | Обеспечить числовые и паттерновые ограничения | BGP AS: 1-4294967295 IPv4: regex ^(\d{1,3}\.){3}\d{1,3}$Скорость интерфейса: {1G, 10G, 25G, 40G, 100G} | Скорость интерфейса “5G” Ошибка: Неверная скорость, должна быть одной из {1G, 10G, 25G, 40G, 100G} |
| Валидация бизнес-правил | Обеспечить соблюдение организационных политик | Если статус VLAN=‘active’ - должна быть ≥1 площадка Если тип устройства=‘firewall’ - должна быть security_zone Если тип сервиса=‘L3VPN’ - route_distinguisher должен быть уникален для клиента | Активный VLAN без площадок Ошибка: Активные VLAN должны быть назначены хотя бы одной площадке |
Существует много способов реализации валидации схемы - от языков программирования общего назначения до более специализированных решений:
- JSON Schema: JSON-документ, описывающий ограничения данных для сравнения с реальными данными.
- CUE: обеспечивает типизированную, валидированную генерацию данных с ограничениями и валидацией.
- YANG: специфичный для сети язык моделирования со встроенным применением ограничений.
Например, используя JSON Schema, можно валидировать данные JSON (или YAML):
- Данные JSON
{
"hostname": "sw-core-01",
"mgmt_ip": "192.0.2.10",
"role": "core",
"interfaces": [
{
"name": "Ethernet1",
"enabled": true,
"vlan": 100
},
{
"name": "Ethernet2",
"enabled": false,
"vlan": 200
}
]
}- JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"required": ["hostname", "mgmt_ip", "role", "interfaces"],
"additionalProperties": false,
"properties": {
"hostname": {
"type": "string",
"pattern": "^[a-z0-9-]+$"
},
"mgmt_ip": {
"type": "string",
"format": "ipv4"
},
"role": {
"type": "string",
"enum": ["core", "distribution", "access"]
},
"interfaces": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": ["name", "enabled", "vlan"],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"pattern": "^Ethernet[0-9]+$"
},
"enabled": {
"type": "boolean"
},
"vlan": {
"type": "integer",
"minimum": 1,
"maximum": 4094
}
}
}
}
}
}4.2.4.2. Жёсткое и мягкое применение#
Отклоняйте плохие данные. Жёсткая остановка. Я видел слишком много систем с “мягкой валидацией”, превращавшихся в мусорные свалки, потому что “только на этот раз” становилось стандартной практикой. Если это достаточно важно, чтобы валидировать, то достаточно важно, чтобы применять.
Но, как обычно, бывают исключения:
Политические рекомендации (не правила): “Вы используете подсеть /22, тогда как мы обычно используем /24” - это предупреждение, а не ошибка. Предупредите пользователя, зафиксируйте в логах, но позвольте продолжить, если он подтверждает.
Дорогостоящие межобъектные проверки: если валидация занимает более нескольких секунд, принимайте изменение и валидируйте асинхронно. Но всё равно применяйте результат: отмечайте нарушение, уведомляйте пользователя и требуйте исправлений.
Обнаружение legacy-сети: при импорте существующих конфигураций вы обнаружите нарушения повсюду. Отмечайте их, но не блокируйте импорт. Весь смысл в том, чтобы обнаружить, что реально существует, даже если это нарушает вашу идеальную модель.
Всё остальное? Отклоняйте. Ваша автоматизация зависит от достоверных данных. Плохие данные означают сбои.
4.2.4.3. Стоимость валидации и компромиссы производительности#
Валидация не бесплатна. Иерархия стоимостей валидации влияет на проектные решения:
graph LR
SPEED["⚡ SPEED"]
V1["< 1ms<br/>Type validation"]
V2["~10ms<br/>Uniqueness"]
V3["5-50ms<br/>Regex"]
V4["50-200ms<br/>Referential<br/>integrity"]
V5["100-500ms<br/>Rule engine"]
V6["1-5 sec<br/>External API"]
V7["Hours+<br/>Consistency"]
THOROUGH["THOROUGHNESS 🎯"]
SPEED --> V1
V1 --> V2
V2 --> V3
V3 --> V4
V4 --> V5
V5 --> V6
V6 --> V7
V7 --> THOROUGH
style SPEED fill:none,stroke:none,font-size:14px,font-weight:bold
style THOROUGH fill:none,stroke:none,font-size:14px,font-weight:bold
style V1 fill:#d4edda,stroke:#28a745,stroke-width:2px
style V2 fill:#d7ecf1,stroke:#17a2b8,stroke-width:2px
style V3 fill:#dfe8f1,stroke:#17a2b8,stroke-width:2px
style V4 fill:#fff3cd,stroke:#ffc107,stroke-width:2px
style V5 fill:#ffe8cd,stroke:#ffc107,stroke-width:2px
style V6 fill:#f8d7da,stroke:#dc3545,stroke-width:2px
style V7 fill:#f5c2c7,stroke:#dc3545,stroke-width:2pxПрактические системы выбирают целевой показатель производительности и валидируют только до этого уровня для синхронных путей записи:
- Быстрый путь (< 10 мс): тип, regex, проверки локального индекса
- Стандартный путь (< 100 мс): уникальность, референциальная целостность
- Медленный путь (< 5 с): движок правил, сложная бизнес-логика
- Асинхронный путь (часы спустя): фоновая валидация, проверки согласованности
4.2.4.4. Повышение качества данных с помощью ИИ#
Машинное обучение улучшает качество данных без снижения пропускной способности. Эти техники ИИ-валидации дополняют пользовательские ИИ-функции из раздела 4.2.3.4, создавая комплексный интеллектуальный уровень данных.
Обнаружение аномалий
Сопоставляйте исторические паттерны с новыми запросами для выявления несоответствий:
- Исторический паттерн: при подготовке нового филиала операторы создают VLAN в диапазоне 1000-1999, назначают его на site_a, настраивают статическую маршрутизацию
- Новый запрос: создать VLAN 2500, назначить на site_c, включить OSPF
- Оповещение: “Этот паттерн создания VLAN необычен. Вы уверены? (98% вероятность, что он должен быть в диапазоне 1000-1999)”
- Техника МО: кластеризация и обнаружение выбросов на исторических векторах изменений
Предложения по автокоррекции
Автоматически предлагать исправления в сторону наиболее вероятного корректного решения:
- Ввод: IP-адрес “192.0.2.1/33” (недопустимая длина префикса > 32)
- Система: “Вы имели в виду /24? (определено из аналогичных подсетей на этой площадке)”
- Техника МО: сопоставление паттернов выделения подсетей в том же местоположении
Векторные вложения для согласованности
Использование вложений для обнаружения значимых отклонений от конфигураций аналогичных устройств:
- Хранить вложения конфигурации каждого устройства
- Получена конфигурация нового устройства
- Сравнить вложение с аналогичными устройствами той же роли
- Если значительно отличается: “Это устройство отличается от аналогов по роли: похожие устройства имеют NTP-серверы X,Y,Z и syslog на сервер Z”
- Техника МО: косинусное сходство на вложениях конфигурации устройств
Соображения по реализации МО
| Аспект | Рекомендация | Обоснование |
|---|---|---|
| Пороги уверенности | Показывать предложения только с уверенностью >90% | Предотвращает усталость от оповещений из-за ложных срабатываний |
| Обучающие данные | Использовать 6-12 месяцев валидированных изменений | Баланс между актуальностью и статистической значимостью |
| Обновления модели | Переобучать еженедельно или при обнаружении дрейфа | Адаптироваться к развивающимся паттернам сети |
| Объяснимость | Всегда показывать, почему ИИ отметил проблему | Формировать доверие оператора к рекомендациям |
| Переопределение человеком | Позволять операторам отмечать ложные срабатывания | Улучшать модель через петли обратной связи |
Обратите внимание на использование оценок “уверенности”. Это важная концепция при использовании ИИ, поскольку она даёт больше контекста о том, насколько можно полагаться на рекомендацию. Всегда сопровождайте предложения ИИ объяснениями лежащего в основе паттерна, который их вызвал.
4.2.4.5. Стоимость применения: последствия для проектирования системы#
Высококачественная валидация влияет на архитектуру:
| Подход | Преимущества | Недостатки | Лучше всего для |
|---|---|---|---|
| Синхронная валидация (валидировать перед принятием записи) | Пользователь получает немедленную обратную связь Гарантирована согласованность данных | Медленные ответы API (задержка валидации) Блокирует высокопропускную автоматизацию | Критические операции целостности данных Интерактивные пользовательские рабочие процессы |
| Асинхронная валидация (сначала принять, затем валидировать) | Быстрые ответы API Высокая пропускная способность | Существует окно несогласованности данных Сложная отчётность об ошибках (“запись прошла успешно, но не прошла валидацию 5 минут спустя”) | Массовые операции Высокообъёмная автоматизация |
| Гибридный подход | Быстрая валидация типа/формата синхронно Дорогостоящая межобъектная валидация асинхронно Конечная точка API для проверки статуса валидации | Более сложная реализация Требует отслеживания статуса | Большинство производственных систем Баланс производительности и корректности |
4.2.5. Версионирование#
Ваше сетевое намерение постоянно меняется. Добавляются устройства, обновляются конфигурации, переносятся сервисы, корректируются политики. Версионирование позволяет понять, что было истинным в какой момент времени, как это стало таким, и как вернуться к чему-то безопасному при необходимости.
4.2.5.1. Контроль версий и неизменяемые журналы аудита#
Все изменения должны записываться неизменяемым образом, создавая полную историю. Это может принимать разные формы, например:
Журналы изменений
Change Event: timestamp: 2025-02-07T14:32:15Z user: engineer@company.com action: UPDATE resource_type: vlan resource_id: vlan-100 changes: description: "Customer VLAN" → "Production Customer VLAN" assigned_sites: [site-a, site-b] → [site-a, site-b, site-c] reason: "Adding new office location" request_id: req-12345Git-коммиты
commit 0c0ad51152f9b3be307802badb15eca8d121c576 (HEAD -> new-site, origin/new-site) Author: Engineer <engineer@company.com> Date: Sat Feb 7 09:43:59 2026 +0100 Adding a new site: BCN01 diff --git a/sites.yaml b/site.yaml index ae18c87..dabf6c5 100644 --- a/sites.yaml +++ b/sites.yaml @@ -219,51 +219,1279 @@ sites: + BCN01:
Этот неизменяемый журнал отвечает на критические вопросы:
- Каким было сетевое намерение на дату X? (путешествие во времени)
- Кто сделал это изменение и почему? (подотчётность)
- Какая конфигурация развёртывания соответствует этому намерению? (прослеживаемость)
- Что изменилось между версиями Y и Z? (сравнение/diff)
Неизменяемость - ключ: никто, даже администраторы, не может редактировать исторические записи. Это предотвращает сокрытие информации и гарантирует сохранение достоверности журналов аудита.
Версионирование также связано с политиками хранения, и здесь нужен баланс между соответствием требованиям и практичностью, например:
- Хранить все изменения 7 лет (регуляторное требование)
- Удалять промежуточные версии через 2 года (например, если VLAN 100 изменился 10 раз, хранить только начальное и конечное состояние)
- Архивировать на холодное хранение через 1 год (для сокращения затрат)
В связи с событиями изменения данных паттерны источника событий (event sourcing, хранение всех изменений как событий для полного воссоздания данных) мощны, но менее распространены в управлении сетевой инфраструктурой. Это связано с тем, что сетевое намерение высоко состояниеёмко. Текущие данные важнее последовательности изменений, приведших к ним. Кроме того, сетевые изменения часто затрагивают внешнее состояние (конфигурации устройств, выделения IP во внешних системах), которое не может быть полностью воссоздано только из событий. Тем не менее источник событий может быть ценен для конкретных случаев использования, таких как соответствие требованиям аудита или криминалистический анализ.
4.2.5.2. Паттерны контроля версий: ветвление, слияние и откат#
Современные системы Источника истины активно заимствуют паттерны контроля версий программного обеспечения. Эти возможности обеспечивают безопасную параллельную работу, экспериментальные изменения и быстрое восстановление после ошибок.
Ветвление для параллельных потоков работы
Любая организация, в которой более одного инженера или ИИ-агента работают параллельно, нуждается в способе работы без блокировки других. Когда один участник (человек или ИИ) подготавливает новые данные, он не может блокировать весь Источник истины.
Заимствуя опыт разработки программного обеспечения, механизмы ветвления обеспечивают параллельные потоки работы. Каждая команда может работать в параллельных треках данных и в конечном итоге объединять их с “основным” треком, когда готова. Это слияние - возможность разрешить любые несоответствия, которые могли возникнуть.
Пример рабочего процесса:
main branch (production intent)
│
├─── feature/add-dallas-office (Engineer A)
│ • Creates site DAL-01
│ • Allocates VLANs 2100-2110
│ • Defines 5 new devices
│
└─── feature/upgrade-ntp-servers (Engineer B)
• Changes NTP config for all devices
• Updates 3,000 device recordsКогда обе ветви объединяются в main:
- Нет конфликта: изменены разные объекты - автоматическое слияние
- Обнаружен конфликт: оба изменили NTP устройства device-core-01 - требуется ручное разрешение
- Валидация: объединённый результат должен пройти все правила применения перед фиксацией
Реализация этого механизма ветвления в традиционных базах данных - важная самостоятельная проблема. Например, NetBox и Nautobot, опирающиеся на реляционные базы данных, выбрали разные подходы: NetBox использует копии базы данных для ветвления, тогда как Nautobot использует Dolt (SQL-базу данных со встроенными Git-подобными возможностями Versioning). Infrahub, спроектированный с нуля с учётом Git-подобного ветвления, реализовал это с использованием графовой базы данных со встроенными возможностями ветвления.
Rollback и восстановление
Ошибки случаются. Rollback данных должен быть быстрым и надёжным. Обратите внимание, что это Rollback самих данных намерения, а не напрямую конфигурации сети.
Откат данных требует, чтобы компонент Исполнения применил изменения конфигурации (можно откатить конфигурации на сетевой инфраструктуре, если это возможно, но в конечном итоге и сеть, и намерение должны быть синхронизированы для поддержания стабильного состояния).
Для поддержки Rollback данных существует два основных подхода:
| Подход | Как работает | Накладные расходы на хранение | Скорость восстановления | Сложность |
|---|---|---|---|---|
| Снимки | Периодические полные копии всего набора данных | Высокие (полная копия на снимок) | Быстрое (прямое восстановление) | Низкая сложность реализации |
| Источник событий | Записывать все изменения как события, воспроизводить для восстановления состояния | Низкие (хранятся только дельты) | Медленнее (нужно воспроизвести события) | Высокая сложность реализации |
| Гибридный | Снимки каждые N часов + журнал событий между снимками | Средние | Быстро до снимка, затем воспроизведение событий | Средняя сложность |
Rollback может быть инициирован двумя способами:
- Вручную: оператор распознаёт проблему, инициирует Rollback
- Автоматически:
- Наблюдаемость обнаруживает увеличение частоты ошибок после развёртывания
- Пост-развёртывательная валидация завершается неудачей (“500 устройств недоступны после изменения”)
- Превышен порог влияния на бизнес (“нарушений SLA клиента > 10”)
Сочетание ветвления (параллельная работа без конфликтов) и Rollback (быстрое восстановление после ошибок) обеспечивает временну́ю гибкость, которую требует крупномасштабная сетевая автоматизация.
4.2.5.3. Атомарные транзакции и гарантии согласованности#
Транзакционные гарантии обеспечивают согласованность данных, когда несколько связанных изменений должны либо все успешно завершиться, либо все откатиться:
- Атомарность: либо всё успешно, либо всё откатывается
- Согласованность: ограничения данных соблюдаются до и после
- Изоляция: параллельные транзакции не мешают друг другу
- Долговечность: после фиксации данные сохраняются даже при сбое системы
Реализация этого требует тщательного проектирования:
- Транзакции базы данных (если все данные в единой БД)
- Распределённые транзакции (если данные охватывают несколько систем)
- Паттерн Saga (если нативная поддержка распределённых транзакций отсутствует)
В Главе 11 мы подробнее рассмотрим, как эти требования влияют на надёжные системы.
4.2.5.4. Рабочие процессы утверждения изменений#
После предложения изменений данных они могут потребовать рабочих процессов согласования с участием человека перед вступлением в силу. Данные, как правило, проходят несколько этапов перед тем, как считаться окончательными, аналогично конвейерам непрерывной интеграции.
graph LR
A["📝 Operator Proposes Change<br/>Add 50 new branch devices"] --> C["📦 STAGING<br/>No network effect yet<br/>Preview, test, dry-run"]
C --> D["✓ Automated Checks Validation<br/>Schema & constraints?"]
C --> E["✓ Simulation<br/>Routing/MPLS impact?"]
C --> F["✓ Compliance<br/>Security policies?"]
D --> G{All Checks<br/>Pass?}
E --> G
F --> G
G -->|Pass| H["👥 Human Review<br/>Change Control"]
G -->|Fail| I["❌ Rejected<br/>Notify proposer"]
H --> J{Approved?}
J -->|Yes| K["✅ APPROVED<br/>Ready for deployment"]
J -->|No| IПример рабочего процесса изменения данных может выглядеть так:
Оператор предлагает изменение: “Добавить 50 новых устройств филиала”
Изменение поступает на ЭТАП ПОДГОТОВКИ: (без влияния на сеть, можно просматривать, тестировать, выполнять пробный запуск)
Запускаются автоматизированные проверки (непрерывная интеграция):
- Валидация: соответствует ли схеме и ограничениям?
- Симуляция: нарушает ли маршрутизацию, MPLS и т.д.?
- Соответствие: нарушает ли политики безопасности?
- Отчёт: все проверки пройдены
Проверка человеком:
- Комитет по управлению изменениями получает уведомление
- Просматривает diff, обоснование, масштаб воздействия
- Утверждает или запрашивает изменения
Решение об утверждении, изменение переходит в состояние УТВЕРЖДЕНО.
Запуск развёртывания: после утверждения это запускает компонент рабочего процесса для окончательного применения связанных изменений к сети (типичный триггер для автоматизированных исполнительных рабочих процессов)
Однако не все изменения требуют согласования с участием человека, и именно здесь большинство организаций делает ошибку. Советы по управлению изменениями - это место, где автоматизация умирает. Я не говорю пропускать согласование, я говорю о том, чтобы автоматизировать его (то есть согласование изменений в масштабе).
Если ваш CAB собирается еженедельно, чтобы утвердить добавление VLAN, вы уже проиграли. Создайте ограждения, которые автоматически утверждают 95% изменений, оставив проверку человеком для действительно рискованных вещей. Например, при подготовке AWS VPC операторы не ждут, пока люди одобрят сетевое изменение: они следуют проверенным шаблонам в рамках определённых границ.
Правило такое: изменения, соответствующие чётким ограждениям, проходят автоматически; только сама логика ограждений требует проверки и утверждения человеком. Определите минимальное покрытие ограждениями и максимальную допустимую погрешность. Затем отойдите в сторону и дайте системе работать.
В противном случае ваша “автоматизация” - просто более красивый способ ждать совещаний.