Feb 15, 2026 · 8682 words · 41 min read
Примечание о переводе: Эта глава переведена с помощью ИИ на основе оригинала на английском языке. Мы стремимся к точности, однако некоторые нюансы могут отличаться от оригинала. Оригинал доступен на английском языке.

4. Источник истины#

Новый сервис должен был запуститься к концу недели. Изменение было простым: новый VLAN, новая подсеть, обновлённые правила брандмауэра и новое BGP-сообщество на пограничных маршрутизаторах. Сетевой инженер точно знал, что делать. Последовали четыре дня координации между пятью системами: инструментом IPAM для резервирования подсети, CMDB для регистрации сервиса, платформой управления брандмауэром для применения новой политики, системой конфигурации маршрутизаторов для BGP-сообщества и платформой мониторинга для добавления новых порогов. У каждой системы был свой интерфейс, своя модель данных, свой рабочий процесс согласования. Но поскольку общей ссылки не существовало, инженеру пришлось ввести контекст вручную: копировать значения из одной системы в другую, надеясь, что ничего не изменится между этапами.

Спустя полгода сервис был выведен из эксплуатации. VLAN убрали. Подсеть освободили. Но правило брандмауэра осталось. Никто не помнил, что оно было связано с этим сервисом. BGP-сообщество сохранялось на двух пограничных маршрутизаторах. Порог мониторинга продолжал генерировать низкоприоритетные оповещения, которые NOC научился игнорировать. Со временем сеть накапливала слои осиротевшей конфигурации: остатки изменений, которые никогда не отслеживались полностью, никогда не отменялись полностью и никогда не были связаны с общей записью намерения.

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

Каждая система автоматизации начинается с одного вопроса: Что я на самом деле собираюсь делать? Когда вы развёртываете правило брандмауэра, добавляете IP-адрес или настраиваете VLAN, вы делаете это на основе какого-то представления намерения. Это представление и есть ваш источник истины: единственная, надёжная версия того, что должно быть развёрнуто.

Я использую “Источник истины” и “Намерение” как взаимозаменяемые. Это в точности одна и та же концепция.

Без надёжного источника истины сетевые операции превращаются в беспорядок из скрытых знаний. Большинство инженеров расходятся во мнениях о том, что развёрнуто. Таблицы противоречат тому, что реально работает. Две разные системы автоматизации вносят конфликтующие изменения в одно и то же устройство. Когда что-то ломается, вы занимаетесь археологией: “Почему это было настроено именно так? Кто это одобрил? Когда это изменилось?”

В этой главе рассматривается, как построить такой источник истины, который работает вне зависимости от того, имеете ли вы десятки устройств или сотни тысяч, обслуживает всех, кому нужны данные (людей, автоматизацию, другие системы), сохраняет данные точными и заслуживающими доверия, и справляется со сложностью получения данных из нескольких источников. Мы рассмотрим шесть строительных блоков: Моделирование, Потребление, Применение, Версионирование, Агрегация и Проектно-ориентированный подход, которые вместе создают прочную основу для сетевой автоматизации. Я также коснусь практических вопросов включения существующих сетей в эту систему и покажу, какие решения доступны на практике.

4.1. Основы#

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

4.1.1. Цели#

Ваш источник истины должен выполнять шесть вещей:

  1. Захватывать всё необходимое. Хранить полную картину вашей сети: конфигурации, активы, топологию, сервисы, IP-адреса, каналы, спецификации устройств, секреты, окна обслуживания, требования соответствия и сведения о владельцах. Включать не только то, что работает сегодня или что запланировано, но и то, что выводится из эксплуатации. Когда все эти данные хранятся в одном месте, а не разбросаны по таблицам и не хранятся в головах людей, системы автоматизации получают контекст, необходимый для принятия разумных решений.

  2. Позволять операторам думать в бизнес-терминах, а не в синтаксисе устройств. Сотрудники должны работать на бизнес-уровне (“добавить новый филиал” или “настроить MPLS-сервис”), а не на уровне Command Line Interface (CLI). За кулисами система сама формирует реальные конфигурации для конкретных устройств. Это сохраняет фокус не на низкоуровневых деталях, а на том, чего в итоге стараются достичь.

  3. Позволять людям и машинам легко получать доступ к данным. Система нуждается в Application Programming Interface (API) (Representational State Transfer (REST), GraphQL), чтобы автоматизация могла получать и изменять данные. Ей также нужен веб-интерфейс и Command Line Interface (CLI), чтобы люди могли просматривать и редактировать. Всем нужен надёжный контроль доступа, чтобы видеть только то, что им положено. Сотни рабочих процессов автоматизации могут работать одновременно, десятки сотрудников - редактировать данные, а внешние системы - синхронизироваться, и при том всём этом система остаётся согласованной и быстрой.

  4. Поддерживать данные чистыми и заслуживающими доверия. Проверять всё: правильность типов данных, осмысленность связей, допустимые диапазоны VLAN, отсутствие дублирующихся IP-адресов. Отслеживать, кто и когда внёс изменения. Позволять людям одобрять крупные изменения до их вступления в силу, а при возникновении проблем — откатываться к предыдущей версии. Автоматизации необходимо доверять точности данных, потому что некорректные данные приводят к плохому состоянию сети и сбоям.

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

  6. Получать данные из других систем. У вас, вероятно, уже есть управление активами для оборудования, IP-системы для адресов, поставщики каналов для подключения, CMDB для сервисов. Не дублируйте это. Вместо этого синхронизируйте их. Установите чёткие правила того, какая система владеет какими данными и поддерживайте синхронизацию в обоих направлениях. Это даёт унифицированное представление всего без изобретения велосипеда.

4.1.2. Столпы#

Эти шесть столпов — не независимые функции, они формируют многоуровневую архитектуру. Моделирование определяет, что может быть выражено. Проектно-ориентированный подход переводит это выражение в технические артефакты. Потребление делает эти артефакты доступными для каждой системы, которой они необходимы. Применение сохраняет надёжность данных при входе. Версионирование сохраняет запись намерения с течением времени, обеспечивая откат версий и аудит. Агрегация предотвращает превращение SoT в ещё один изолированный силос, получая авторитетные данные из систем, которые ими уже владеют.

Уберите любой из них и остальные деградируют. Без Применения Потребление обслуживает некорректные данные. Без Версионирования нет способа рассуждать о том, что изменилось при возникновении проблемы. Без Агрегации операторы поддерживают дублирующиеся данные в разных системах, и SoT теряет доверие. Раздел 4.2 подробно рассматривает каждый из них.

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

4.1.3. Область ответственности#

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

Что входит в область ответственности:

Источник истины управляет всеми данными намерения - полным определением того, как должна выглядеть ваша сеть. Это включает производственные конфигурации, промежуточные среды, ветки разработки и тестовые сценарии. Всё, что описывает “что вы хотите”, живёт именно здесь.

Что не входит в область ответственности:

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

  1. Данные наблюдаемости: Источник истины не хранит метрики, логи или состояние времени выполнения. Однако он определяет ожидания, с которыми вы будете сравнивать реальность. Например, пороговые значения для оповещений или базовые показатели производительности. Реальные данные наблюдаемости хранятся совершенно в другом месте (рассматривается в Главе 6).

  2. Взаимодействие с сетью: Источник истины не обращается к устройствам и не применяет конфигурации. Он предоставляет необходимые артефакты (конфигурации устройств, правила валидации, манифесты развёртывания), но не выполняет их. Это работа Исполнителя (Глава 5).

  3. Логика оркестрации: Источник истины не определяет последовательность шагов или рабочих процессов для развёртывания изменений. Он определяет намеченное конечное состояние. То, как туда добраться (какие устройства первыми, какие шаги валидации, процедуры отката версий), принадлежит Оркестратору (Глава 7).


Думайте об источнике истины как о путеводной звезде вашей стратегии сетевой автоматизации. Это единственный, авторитетный ответ на вопрос “как должна выглядеть сеть?” Всё остальное в вашей системе автоматизации (выполнение, мониторинг, оркестрация) ссылается на эту истину для выполнения своей работы. Когда реальность отклоняется от намерения, источник истины чётко говорит вам, чем эта реальность должна стать.

4.2. Функциональности#

Теперь поговорим о шести функциональностях, реализующих всё это на практике.

Каждая соответствует цели и столпу:

  1. Моделирование: Определяет, какие данные хранятся и как они взаимосвязаны. Модели устройств, интерфейсы, VLAN, каналы, сервисы. Позволяет развиваться по мере изменения потребностей.

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

  3. Потребление: Как люди и системы реально получают и используют данные. Application Programming Interface (API), веб-интерфейс, Command Line Interface (CLI). Каждый получает контроль доступа, соответствующий его роли.

  4. Применение: Гарантирует, что некорректные данные не проникнут. Валидация, проверки уникальности, ссылочная целостность. Чёткие сообщения об ошибках.

  5. Версионирование: Сохраняет полную историю. Кто, что и когда изменил, и самое главное зачем. Откат в версии при необходимости.

  6. Агрегация: Получает данные из других систем (CMDB, IPAM и т.д.) и поддерживает их синхронизацию.

graph LR

    %% --- Subgraphs ---
    subgraph Цели
        direction TB
        A1[Собрать все необходимые данные]
        A2[Позволить операторам мыслить бизнес-терминами, а не синтаксисом устройств]
        A3[Обеспечить лёгкий доступ к данным для людей и машин]
        A4[Поддерживать данные чистыми и надёжными]
        A5[Позволить людям работать параллельно, не мешая друг другу]
        A6[Подтягивать данные из других систем]
    end

    subgraph Столпы
        direction TB
        B1[Гибкий фреймворк моделирования данных]
        B2[Проектирование и шаблоны]
        B3[API и интерфейсы]
        B4[Валидация данных]
        B5[История изменений]
        B6[Агрегация данных]
    end

    subgraph Функциональные возможности
        direction TB
        C1[Моделирование]
        C2[Проектно-ориентированный подход]
        C3[Потребление]
        C4[Принудительное применение]
        C5[Версионирование]
        C6[Агрегация]
    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[Внешний контур]
        A[Потребление]
    end

    %% Tier 2
    subgraph T2[Уровень данных]
        B[Проектно-ориентированный подход]
        D[Моделирование]
    end

    %% Tier 3
    subgraph T3[Движок]
        C[Агрегация]
        E[Принудительное применение]
        F[Версионирование]
    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{Основное требование?}
    Q1 -->|Обход сложных взаимосвязей на глубину| Q2{Запросы с постоянной топологией?}
    Q1 -->|Схема часто меняется| DB_D[Документное хранилище]
    Q1 -->|Структурированные запросы, ссылочная целостность| DB_R[Реляционная база данных]
    Q2 -->|Да| DB_G[Графовая база данных]
    Q2 -->|Время от времени| 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[Инвентаризация и учёт активов]
    DC[Инфраструктура ЦОД]
    IPAM[Управление IP-адресами]
    VIRT[Виртуализация и облачные технологии]
    CONN[Подключение]
    ROUTE[Маршрутизация]
    SVC[Сервисы]
    SEC[Безопасность и соответствие требованиям]
    MGMT[Управление]

    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[Бизнес—намерение]
    B[Применение шаблона]
    C[Выделение ресурсов]
    D[Разрешение логики]
    E[Рендеринг деталей]
    F[Объекты для исполнителя]

    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
gRPCRPC на основе 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, транзакции и вебхуки. Операционным командам нужны ориентированные на задачи представления и журналы аудита. Бизнесу нужны отчёты без технических деталей. Внешние системы должны синхронизировать данные в обоих направлениях.

Обратите внимание, что пользовательский интерфейс блока потребления относится к уровню Представления. Подробнее об этом читайте в Главе 8.

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

Сетевому инженеру нужны интерфейсы и детали маршрутизации. Финансовому отделу - стоимость и информация о гарантии. Службе безопасности - зона соответствия требованиям. Вместо того чтобы возвращать все 500 полей всем, давайте каждому потребителю только то, что ему необходимо. Это можно сделать с помощью параметров API-запроса (?view=network_engineer) или GraphQL, тем самым позволяя запрашивать конкретные поля.

Проблема: одна модель данных не может подойти всем потребителям

Рассмотрим один объект устройства в SoT, содержащий сотни атрибутов:

  • Аппаратные детали (модель, серийный номер, версия прошивки)
  • Конфигурация сети (IP-адреса, VLAN, протоколы маршрутизации)
  • Операционные метаданные (местоположение, центр затрат, истечение гарантии)
  • Связи с сервисами (какие клиенты используют это устройство)
  • Контекст безопасности (зона соответствия требованиям, политики доступа)

Разным потребителям нужны принципиально разные представления этих данных:

Пример: устройство “router-core-01” в разных контекстах

ПотребительКонтекстПредставление данныхКлючевые атрибуты
Сетевой инженерУстранение проблем с подключениемСетевое представлениеИнтерфейсы, IP-адреса, BGP-пиры, маршруты, VLAN, статус аплинка
Финансовый отделРаспределение затратБизнес-представлениеЦентр затрат, график амортизации, статус гарантии, дата покупки, поставщик
Служба безопасностиАудит соответствия требованиямПредставление безопасностиЗона соответствия, политики доступа, последнее сканирование безопасности, уровень патчей, открытые уязвимости
Рабочий процесс автоматизацииРазвёртывание конфигурацииИсполнительное представлениеIP-адрес управления, ссылка на учётные данные, платформа устройства, имя шаблона конфигурации
Каталог сервисовАнализ влияния на клиентовСервисное представлениеОбслуживаемые клиенты, размещённые сервисы, уровень SLA, группа резервирования

Паттерны реализации

  1. Трансформации на основе представлений: 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: ...}
  2. Выбор полей в 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
      }
    }
  3. Проекционные слои: бэкенд вычисляет производные представления, оптимизированные для конкретных паттернов доступа

    • Граф сетевой топологии: устройства как узлы, соединения как рёбра (для визуализации топологии)
    • Дерево зависимостей сервисов: иерархическое представление сервисов - устройств - компонентов (для анализа влияния)
    • Матрица соответствия: устройства, сгруппированные по зонам со статусом соблюдения политик (для аудита)
  4. Предметно-специфические языки (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. Жёсткое и мягкое применение#

Всегда отклоняйте некорректные данные. Это должна быть жёсткая остановка. Я видел слишком много систем с “мягкой валидацией”, которые со временем превращались в мусорные свалки, потому что “только на этот раз” становилось стандартной практикой. Если это в действительности настолько важно, чтобы валидировать, то достаточно важно, чтобы применять.

Но, как обычно, бывают и исключения:

  1. Политические рекомендации (не правила): “Вы используете подсеть /22, тогда как мы обычно используем /24” - это предупреждение, а не ошибка. Предупредите пользователя, зафиксируйте это в логах, но позвольте ему продолжить, если он подтвердит операцию.

  2. Дорогостоящие межобъектные проверки: если валидация занимает более нескольких секунд, то принимайте изменение и валидируйте асинхронно. Но всё равно применяйте результат: отмечайте нарушение, уведомляйте пользователя и требуйте исправлений.

  3. Обнаружение legacy-сети: при импорте существующих конфигураций вы обнаружите нарушения повсюду. Отмечайте их, но не блокируйте импорт. Весь смысл в том, чтобы обнаружить, что реально существует, даже если это нарушает вашу идеальную модель.

Всё остальное - просто отклоняйте. Ваша автоматизация зависит от достоверных данных. Некорректные данные всегда приводят к сбоям.

4.2.4.3. Стоимость валидации и компромиссы производительности#

Валидация не бесплатна. Иерархия стоимостей валидации всегда влияет на проектные решения:

graph LR
    SPEED["⚡ СКОРОСТЬ"]
    V1["< 1ms<br/>Валидация типов данных"]
    V2["~10ms<br/>Проверка на уникальность"]
    V3["5-50ms<br/>Регулярные выражения"]
    V4["50-200ms<br/>Referential<br/>Ссылочная целостность"]
    V5["100-500ms<br/>Движок бизнес-правил"]
    V6["1-5 sec<br/>Запросы к внешним API"]
    V7["Hours+<br/>Проверка консистентности"]
    THOROUGH["ТЩАТЕЛЬНОСТЬ 🎯"]
    
    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 мс): тип, регулярные выражения, проверки локального индекса
  • Стандартный путь (< 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-12345
  • Git-коммиты

    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["📝 Инженер инициирует изменение<br/>Добавить 50 новых устройств филиалов"] --> C["📦 СРЕДА ТЕСТИРОВАНИЯ<br/>Без влияния на сетьt<br/>Предпросмотр, тесты, пробный запуск"]
    C --> D["✓ Автоматическая валидация<br/>Схема&ограничения?"]
    C --> E["✓ Симуляция<br/>Влияние на маршрутизацию/MPLS?"]
    C --> F["✓ Проверка соответствия<br/>Политики безопасности?"]
    D --> G{Все проверки<br/>Успешны?}
    E --> G
    F --> G
    G -->|Pass| H["👥 Ревью человеком<br/>Управление изменениями"]
    G -->|Fail| I["❌ Отклонено<br/>Уведомить инициатора"]
    H --> J{Одобрено?}
    J -->|Yes| K["✅ ОДОБРЕНО<br/>Готово к деплою"]
    J -->|No| I

Пример рабочего процесса изменения данных может выглядеть так:

  1. Оператор предлагает изменение: “Добавить 50 новых устройств филиала”

  2. Изменение поступает на ЭТАП ПОДГОТОВКИ: (без влияния на сеть, можно просматривать, тестировать, выполнять пробный запуск)

  3. Запускаются автоматизированные проверки (непрерывная интеграция):

    • Валидация: соответствует ли схеме и ограничениям?
    • Симуляция: нарушает ли маршрутизацию, MPLS и т.д.?
    • Соответствие: нарушает ли политики безопасности?
    • Отчёт: все проверки пройдены
  4. Проверка человеком:

    • Комитет по управлению изменениями получает уведомление
    • Просматривает diff, обоснование, масштаб воздействия
    • Утверждает или запрашивает изменения
  5. Решение об утверждении, изменение переходит в состояние УТВЕРЖДЕНО.

  6. Запуск развёртывания: после утверждения это запускает компонент рабочего процесса для окончательного применения связанных изменений к сети (типичный триггер для автоматизированных исполнительных рабочих процессов)

Однако не все изменения требуют согласования с участием человека, и именно здесь большинство организаций совершает ошибку. Советы по управлению изменениями - это именно то место, где автоматизация умирает. Я не говорю пропускать согласование, я говорю о том, чтобы автоматизировать его (то есть согласование изменений на самом масштабном уровне).

Если ваш CAB собирается еженедельно, чтобы утвердить добавление VLAN, вы уже проиграли. Создайте такие ограждения, которые автоматически утверждают 95% изменений, оставив проверку человеком для действительно рискованных вещей. Например, при подготовке AWS VPC операторы не ждут, пока люди одобрят сетевое изменение: они следуют проверенным шаблонам в рамках заданных границ.

Правило такое: изменения, соответствующие чётким ограждениям, проходят автоматически; только сама логика ограждений требует проверки и утверждения человеком. Определите минимальное покрытие ограждениями и максимальную допустимую погрешность. Затем отойдите в сторону и дайте системе работать.

В противном же случае ваша “автоматизация” - это просто более красивый способ ждать совещаний.