Nov 30, 2025 · 6601 words · 31 min read
Примечание о переводе: Эта глава переведена с помощью ИИ на основе оригинала на английском языке. Мы стремимся к точности, однако некоторые нюансы могут отличаться от оригинала. Оригинал доступен на английском языке.

2. Принципы проектирования#

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

Внедрения так и не произошло. Операторы продолжали использовать CLI. На вопросы о причинах ответы были одинаковыми: “Я не знаю, что она сделает, прежде чем она это сделает.” “Если что-то пойдёт не так, я не могу понять, что произошло.” “Я не понимаю, как читать вывод.” Команда автоматизации создала нечто технически впечатляющее, но операционно непрозрачное. Не было режима пробного запуска, понятного для человека предварительного просмотра изменений, журнала аудита в терминах, понятных операторам. Система была чёрным ящиком, просящим доверия, которое она не заработала. Шесть месяцев инженерных усилий остались невостребованными.

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

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

2.1 Формирование доверия#

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

Почему доверие так важно? Потому что без него сетевые инженеры не примут вашу автоматизацию. Им необходимо верить, что автоматизация обеспечивает как минимум тот же уровень уверенности, что и ручные процессы, которые она заменяет (плюс другие преимущества).

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

Актуальность заслуживающей доверия автоматизации вдохновлена презентацией Damien Garros Building Trustworthy Network Automation на Autocon3.

Для простоты выделим четыре базовые характеристики, которые нам необходимы:

  • Predictable: Согласованные, детерминированные результаты. Инженеры должны знать, что произойдёт, прежде чем нажать кнопку запуска, и получать одинаковое поведение каждый раз.
  • Reliable: Корректная обработка ошибок. Восстановление после сбоев. Обеспечение безопасного завершения операций (или отката) даже в неожиданных условиях и при масштабировании.
  • Usable: Интерфейсы, позволяющие инженерам проверять, анализировать и управлять поведением без излишней сложности. С защитными ограничителями.
  • Understandable: Не может быть чёрным ящиком. Должна раскрывать намерение, шаги, результаты и решения способом, формирующим уверенность у людей.
graph BT
  %% ===== Middle Layer =====
  subgraph L2[**Qualities**]
    direction LR
    B1[Predictable]:::layer2
    B2[Reliable]:::layer2
    B3[Usable]:::layer2
    B4[Understandable]:::layer2
  end

  %% ===== Top Layer =====
  subgraph L1[" "]
    direction TB
    A[Trust]:::layer1
  end

  %% ===== Connections: Behavior → Outcome =====
  B1 --> A
  B2 --> A
  B3 --> A
  B4 --> A

  %% ===== Styling =====
  classDef layer1 fill:#ffcccc,stroke:#b8860b,stroke-width:2px,color:#000;
  classDef layer2 fill:#ffe6cc,stroke:#4682b4,stroke-width:1.5px,color:#000;

Предсказуемость или детерминированное поведение становятся всё более актуальными по мере того, как технологии ИИ/МО входят в область сетевой автоматизации, поскольку они вносят некоторую случайность.

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

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

Итак, с учётом этих характеристик, исследуем принципы, их поддерживающие.

2.2 Принципы проектирования#

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

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

  • Идемпотентность: Одна и та же операция несколько раз = одно и то же конечное состояние. Снижает побочные эффекты, устраняет неоднозначность, делает автоматизацию более понятной и безопасной для повторения.
  • Transactional: Изменения завершаются полностью или безопасно завершаются неудачей. Никаких частичных, несогласованных или наполовину применённых состояний. Необходимо для предсказуемости и обеспечивает откаты в масштабе сети.
  • Intent-Driven: Определяет желаемое состояние системы при различных условиях. Улучшает предсказуемость, снижает когнитивную нагрузку, делает систему более удобной в использовании.
  • Дружественность к Dry Run: Показывает, что будет сделано, до того, как это будет сделано. Делает автоматизацию более удобной и вызывающей доверие, позволяя людям проверять действия, визуализировать результаты и обнаруживать проблемы до их воздействия на сеть.
  • Versioning: Поддержка версионирования как данных, так и логики. Перемещение назад или вперёд во времени, восстановление предыдущих состояний, поддержание нескольких состояний параллельно. Усиливает предсказуемость и укрепляет надёжность.
  • Тестируемость: Надлежащая тестовая среда необходима перед выполнением изменений в производстве. Улучшает надёжность и помогает инженерам понять поведение системы.

Эти принципы не являются исключительными для сетей, они применимы к автоматизации в любой ИТ-области. Но они становятся особенно критическими в сетях, где изменения несут значительный операционный риск.

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

graph BT
  %% ===== Bottom Layer =====
  subgraph L3[**Principles**]
    direction LR
    C1[Idempotent]:::layer3
    C2[Versioned]:::layer3
    C3[Transactional]:::layer3
    C4[Testable]:::layer3
    C5[Dry Run]:::layer3
    C6[Intent-Driven]:::layer3
  end

  %% ===== Middle Layer =====
  subgraph L2[**Qualities**]
    direction LR
    B1[Predictable]:::layer2
    B2[Reliable]:::layer2
    B3[Usable]:::layer2
    B4[Understandable]:::layer2
  end

  %% ===== Top Layer =====
  subgraph L1[" "]
    direction TB
    A[Trust]:::layer1
  end

  %% ===== Connections: Foundation → Behavior =====
  C1 --> B1
  C1 --> B4

  C2 --> B3
  C2 --> B2

  C3 --> B1
  C3 --> B2

  C4 --> B2
  C4 --> B4

  C5 --> B3
  C5 --> B4

  C6 --> B1
  C6 --> B3

  %% ===== Connections: Behavior → Outcome =====
  B1 --> A
  B2 --> A
  B3 --> A
  B4 --> A

  %% ===== Styling =====
  classDef layer1 fill:#ffcccc,stroke:#b8860b,stroke-width:2px,color:#000;
  classDef layer2 fill:#ffe6cc,stroke:#4682b4,stroke-width:1.5px,color:#000;
  classDef layer3 fill:#ccffcc,stroke:#228b22,stroke-width:1.5px,color:#000;

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

2.2.1. Управление намерением#

Почему начинать с намерения? Прежде чем обсуждать, как выполнять автоматизацию, нам нужно понять, что мы пытаемся достичь. Проектирование на основе намерений — это фундамент, на котором строится всё остальное.

Распространённый вариант использования для начала автоматизации: скрипты или плейбуки, выполняющие простые действия. Поднять или опустить интерфейс, указав FQDN и имя интерфейса. Но это создаёт проблему. Следующий человек, работающий с этим интерфейсом, не будет знать, каково его Desired State. Должен ли он быть поднят или опущен?

Эта проблема затрагивает как ручные, так и автоматизированные операции. Но с автоматизацией проблема усугубляется. Вы не можете уверенно вывести сетевое намерение из его текущего состояния, особенно когда было применено много ситуативных изменений. Фактическая конфигурация сети является результатом вашей логики Intent-Driven, а не её надёжной записью.

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

Кто-то может возразить, что его намерение — это просто Actual State сети: “посмотри на конфигурацию, вот моё намерение.” Хотя это технически является намерением, вы не можете доказать, что оно соответствует вашему первоначальному или реальному намерению и не было изменено обстоятельствами, если только у вас нет отдельного источника для сравнения. Конфигурация сети — это результат вашего намерения, а не само намерение.

Таким образом, качество ваших данных Intent-Driven напрямую определяет качество вашей автоматизации. Эта концепция тесно связана с Source of Truth (SoT) (SoT), который мы подробно рассмотрим в Главе 4.

Инфраструктура как код (IaC): Автоматизация на основе намерений является фундаментом Infrastructure as Code (IaC): отношение к определениям сетевой инфраструктуры как к программному коду. С IaC вы получаете управление версиями, процессы code review, тестирование и возможность относиться к изменениям инфраструктуры так же, как к изменениям программного обеспечения. Это соединяет сетевую автоматизацию с лучшими практиками разработки ПО. IaC хранит шаблоны, инвентари и намерение в виде файлов под управлением версиями. Изменения проверяются, тестируются и отслеживаются, а не применяются как разовые правки в CLI.

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

2.2.2. Идемпотентность#

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

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

Например, при автоматизированной настройке ACL, если мы определяем правило, мы ожидаем:

  • Если правило не существует, оно добавляется на определённую позицию.
  • Если правило уже существует, дубликаты не добавляются.
  • Если позже добавляется другое правило, предыдущее остаётся нетронутым и не перемещается.

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

  • Каково текущее состояние ACL?
  • Является ли правило уже его частью?
  • Если нет, какое различие нужно применить?

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

Идемпотентность применима к различным измерениям сетевой автоматизации. Например, при запросе IP-адреса через DHCP или из системы IPAM, понимающей соответствие между идентификатором запроса и результатом:

Рисунок 1: Пример идемпотентности (из доклада Damien Garros на Autocon3)

Как вы прочитаете позже, для достижения идемпотентности предпочтительнее использовать Declarative модели вместо Imperative. Определяйте конечное состояние, а не шаги. Это не означает, что использование императивного режима невозможно, но это сложнее.

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

2.2.3. Транзакционность#

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

Transactional — распространённая концепция в базах данных, где несколько изменений применяются атомарно для поддержания согласованности. В сетях (распределённых системах) транзакционность ещё сложнее, но это не новая проблема. В 2006 году NETCONF (RFC 6241) ввёл общесетевой коммит, применяющий изменения глобально на нескольких устройствах или полностью откатывающий их при сбое валидации. Эта Atomic Operation предотвращает частичные состояния, когда одни устройства обновились, а другие — нет: кошмарный сценарий для устранения неполадок. Однако не все платформы поддерживают NETCONF, и сложность интеграции существенно варьируется. Поэтому, хотя проблема теоретически решена, практическая реализация зависит от вашей инфраструктуры.

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

Итак, в целом, как мы можем применять транзакционность к сетям? Это сочетание техник:

  • NETCONF: Возможности управления сетью, поддерживающие распределённую координацию управления. Но поддержка очень ограничена.
  • Транзакции на основе базы данных: Хранение изменений конфигурации в базе данных со свойствами ACID, затем их применение скоординированными пакетами с возможностью Rollback
  • Очереди уведомлений об изменениях: Захват всех предполагаемых изменений, их групповая валидация, затем выполнение со скоординированным механизмом Rollback при сбое любого устройства
  • Паттерны двухфазного коммита: Сначала подготовка изменений на всех устройствах (фаза 1), затем их одновременная фиксация (фаза 2) с Rollback при сбое фазы 2 на любом устройстве
  • Транзакционные журналы: Запись каждой попытки изменения с достаточными деталями для отмены частичных операций вручную или автоматически

Обратите внимание, что все механизмы в распределённой среде требуют возможности отката для обеспечения бесшовного отката. Вам нужен коммит или снимок, который можно активировать (внутренне или внешне по отношению к платформе) для перехода в предыдущее состояние. Это не всегда доступно. Там, где истинные атомарные коммиты недоступны, реализуйте проверенный этап “подготовки” и используйте скоординированный оркестрированный коммит или поэтапное развёртывание для снижения риска (используйте это только при отсутствии встроенной атомарности).

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

2.2.4. Версионирование#

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

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

В разработке программного обеспечения Version Control System (VCS), такие как Git, являются стандартной практикой (я не работал ни в одной среде без какой-либо формы VCS). Эти системы обеспечивают:

  • Лёгкое сотрудничество: Несколько разработчиков вносят код и могут двигаться вперёд по разным ветвям
  • Путешествие во времени: Возврат к предыдущим точкам в истории, чтобы понять, что и когда изменилось
  • Атомарная группировка: Несколько изменений файлов могут быть объединены в единую единицу

Применение Versioning к сетевой автоматизации даёт значительные преимущества:

  • Возможность аудита и отслеживания: Легко отслеживать, кто, что и когда изменил, делая систему прозрачной
  • Сотрудничество между командами: Облегчает проверку изменений и обеспечивает командную разработку автоматизации
  • Atomic Operation: Связанные изменения в нескольких файлах могут применяться вместе, предотвращая частичные или неполные состояния
  • Интеграция с CI/CD: Автоматизированные пайплайны могут запускать тестирование и валидацию при обнаружении изменений кода

Шаблоны конфигураций являются ярким примером данных, выигрывающих от версионирования. Одно изменение шаблона влияет на все производные конфигурации по всей сети, поэтому управление версиями становится необходимым. В целом все данные должны храниться с поддержкой версий. Распространено хранение версионированных файлов YAML или JavaScript Object Notation (JSON), моделирующих данные любого рода, или данных с более сложными связями.

GitOps: Развивающийся паттерн, выводящий версионирование на новый уровень: репозиторий Git становится единым источником истины, а контроллер непрерывно сравнивает Desired State в Git с Actual State в сети, автоматически исправляя дрейф. Набирает популярность в сетевой автоматизации, особенно в облачно-нативных средах и средах с интеграцией Kubernetes.

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

2.2.5. Тестируемость#

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

Тестирование особенно сложно в сетях. Часто вы не владеете всей сетью (подумайте об интернет-пирингах BGP, где вы не владеете другой стороной), или масштаб запрещителен (представьте тестирование фабрики датацентра с тысячами коммутаторов). Воспроизведение реальных тестовых сценариев может быть практически невозможным или запрительно дорогостоящим.

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

Пирамида тестирования предоставляет полезный фреймворк:

graph BT
  %% Unit tests (base)
  U1["Unit Tests<br/>(Data Quality, Logic)"]:::unit

  %% Integration tests
  I1["Integration Tests<br/>(Simulated Environment)"]:::integration

  %% End-to-end tests (top)
  E1["End-to-End Tests<br/>(Lab, Validation)"]:::enduser

  %% Links
  U1 --> I1
  I1 --> E1

  %% Styling
  classDef unit fill:#a6e3a1,stroke:#3b7a57,stroke-width:2px,color:#000;
  classDef integration fill:#89b4fa,stroke:#1e3a8a,stroke-width:2px,color:#000;
  classDef enduser fill:#f9e2af,stroke:#b8860b,stroke-width:2px,color:#000;
  • Unit Test проверяют качество данных, базовую логику и специфическое поведение изолированно с использованием заглушек или фиктивных систем. Выполняются быстро и рано выявляют фундаментальные ошибки.
  • Integration Test вводят сторонние системы в смоделированной (и упрощённой) среде. Различные компоненты автоматизации взаимодействуют друг с другом и имитируемыми вариантами сети, позволяя проверять точки интеграции (например, имитация Application Programming Interface (API) или Secure Shell (SSH) Command Line Interface (CLI) интерфейса сетевого устройства).
  • End-to-End Test проверяют поведение в близких к реальным сценариях с использованием виртуализированных сетевых сред или лабораторий, имитирующих часть вашей производственной сети (мы глубже рассмотрим эту тему в Главе 9).

ИИ-ассистенты для написания кода становятся всё более полезными для генерации тестов. Если вы можете сформулировать, что тестировать, эти инструменты могут помочь быстро создать комплексные наборы тестов (и выявить логические недостатки, которые вы могли не заметить с первого взгляда).

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

Расширенные стратегии тестирования:

  • Хаос-инжиниринг: Намеренное внедрение сбоев (отключение устройств, задержки сети) для проверки того, что ваша автоматизация и мониторинг обрабатывают их корректно (Netflix популяризировал этот подход с их Chaos Monkey).
  • Тестирование на основе свойств: Определите свойства, которые всегда должны оставаться истинными (например, “BGP всегда должен сходиться в течение 30 секунд”), и пусть тестовые фреймворки генерируют сценарии для их проверки

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

2.2.6. Дружественность к пробному запуску#

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

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

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

Существуют инструменты, предоставляющие возможность Dry Run, но вы всегда можете создать свой, если это необходимо:

  • Ansible: Флаги --check и --diff показывают, что было бы изменено
  • Terraform: Команда terraform plan отображает разницу между текущим и Desired State
  • Пользовательские сетевые API: Некоторые могут предоставлять режим “пробного запуска” или предварительного просмотра

Вот пример того, как выглядит эта видимость:

Вывод Ansible Diff

- description: Uplink to CoreSwitch1
+ description: Uplink to CoreSwitch2
  mtu: 9216

Вывод Terraform Plan

~ description = "Uplink to CoreSwitch1" -> "Uplink to CoreSwitch2"
  mtu          = 9216

Предварительный ответ пользовательского сетевого API

{
  "operation": "PATCH",
  "path": "/interfaces/Gi0-1",
  "changes": [
    {
      "field": "description",
      "current_value": "Uplink to CoreSwitch1",
      "proposed_value": "Uplink to CoreSwitch2",
    }
  ],
  "mtu": 9216
}

Пробные запуски превращают автоматизацию из подхода “надеемся на лучшее” в осознанный, поддающийся проверке процесс.

Расширенные концепции пробного запуска:

  • Анализ воздействия: Помимо показа изменений, анализировать и сообщать о бизнес-воздействии (например, “Это временно затронет 10% трафика”)
  • Поэтапные развёртывания: Реализовать пробный запуск в масштабе, постепенно развёртывая изменения на подмножестве устройств сначала, проверяя воздействие перед полным развёртыванием
  • Симуляция сети: Комбинировать с инструментами тестирования сети для выполнения пробных запусков на реплике вашей производственной сети

2.3. Паттерны архитектурных решений#

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

2.3.1. Декларативный vs. Императивный#

Выбор между декларативным и императивным подходами является фундаментальным. Каждый имеет сильные стороны и компромиссы в зависимости от варианта использования. Управление конфигурацией инфраструктуры может принимать два подхода:

  • Declarative автоматизация определяет желаемое конечное состояние; система определяет, как его достичь. Пример: “Я хочу, чтобы интерфейс Gi0/1 имел MTU 9000.” Движок автоматизации определяет текущее состояние и применяет только необходимые изменения. Фокусируется на ЧТО — желаемых результатах.
  • Imperative автоматизация задаёт точные шаги для выполнения. Пример: “Показать конфигурацию интерфейса, разобрать её, вычислить разницу, отправить эти точные CLI-команды в этом порядке.” Фокусируется на КАК — конкретных действиях.

Декларативные подходы естественно поддерживают Идемпотентность, возможности Dry Run и Transactional поведение, но требуют инфраструктуры и систем, поддерживающих это.

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

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

Большинство современных фреймворков автоматизации (Terraform, Ansible, Kubernetes или инструменты на основе Yet Another Next Generation (YANG)) стремятся к Declarative моделям, допуская Imperative запасные варианты при необходимости (например, модули raw в Ansible, прямой Command Line Interface (CLI), Netmiko).

Некоторые инструменты, такие как Ansible, могут функционировать обоими способами в зависимости от типа модуля. Сетевые модули (такие как cisco.ios.ios_interfaces) являются декларативными, тогда как ansible.netcommon.cli_command выполняет императивные команды. В приведённом ниже примере вы увидите оба подхода:

- name: Imperative vs. Declarative Approaches in Ansible
  hosts: switches
  gather_facts: no
  vars:
    interface_name: GigabitEthernet0/1
    new_description: Uplink to CoreSwitch2
  tasks:
    - name: Imperative - Execute exact commands
      ansible.netcommon.cli_command:
        command: |
          configure terminal
          interface {{ interface_name }}
          description {{ new_description }}
          no shutdown
          end
      # Repeating this task may add duplicates and fails idempotency

    - name: Declarative - Define desired state
      cisco.ios.ios_interfaces:
        config:
          - name: "{{ interface_name }}"
            description: "{{ new_description }}"
            enabled: true
        state: merged
      # Repeating this task is safe, it converges to the desired state

Имейте в виду, что при декларативном подходе вы перекладываете логику на внешнюю систему, и в некоторых сценариях это может быть недоступным вариантом. Обратите внимание в предыдущем примере, как вы используете модуль Ansible cisco.ios.ios_interfaces, реализующий логику, необходимую для обеспечения декларативного поведения.

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

2.3.2. Изменяемая vs. Неизменяемая инфраструктура#

Концепция: Вы разрешаете внесение изменений в инфраструктуру (сеть) на месте, или заменяете инфраструктуру полностью при необходимости изменений?

  • Изменяемая инфраструктура: Традиционный подход, при котором вы заходите на устройства через Secure Shell (SSH) и напрямую модифицируете конфигурации (или модифицируете их через NETCONF, gNMI или любой Application Programming Interface (API)). Изменения применяются на месте.
    • Плюс: Менее разрушительно, меньше накладных расходов.
    • Минус: Сложнее отслеживать состояние, повышает риск Configuration Drift.
  • Неизменяемая инфраструктура: Вы никогда не модифицируете работающую инфраструктуру. Вместо этого создаёте новую инфраструктуру с желаемыми изменениями и переключаете трафик/соединения. Широко используется в облаке (контейнеры, ВМ), но менее распространено в сетях.
    • Плюс: Предсказуемое состояние, легче проверить, устраняет дрейф.
    • Минус: Требует оркестрации, более сложное восстановление, большие накладные расходы на ресурсы.

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

2.3.3. Greenfield vs. Brownfield#

Не технический термин, но полезный для понимания двух различных сценариев при разработке решений по сетевой автоматизации:

  • Среды Brownfield существуют с унаследованными системами, ручными процессами, несогласованными конфигурациями и знаниями, доступными только немногим. Сложнее, потому что вы автоматизируете сложность, которая никогда не предназначалась для автоматизации: несогласованные проекты, отсутствующие данные, унаследованные технологии, человеческие привычки и ограничения живого трафика. Но это наиболее распространённая среда.
  • Среды Greenfield создаются с нуля с принципами “автоматизация прежде всего”. Вы можете чисто реализовать все принципы: управление версиями с первого дня, декларативное намерение, чистые модели данных, комплексное тестирование. Идеально, но редко.

Углубимся немного в то, почему среды brownfield настолько сложны…

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

Однако в таких случаях ещё есть надежда. Следующие три подхода облегчают начало работы в этих сценариях:

  1. Частичный подход greenfield: Автоматизируйте новую инфраструктуру, постепенно рефакторируя унаследованные системы. Это показывает прогресс без начала с максимальной сложности.
  2. Инкрементальный выбор цели: Сосредоточьтесь на частях сети, которые легче автоматизировать и дают быстрые победы:
    • Добавление дрейфа конфигурации и исправление для нескольких функций управления (AAA, NTP, SNMP)
    • Автоматизация настройки интерфейсов для одного типа устройств
    • Стандартизация одной подсистемы перед расширением
  3. Накопление импульса: Каждая маленькая победа демонстрирует ценность автоматизации и формирует доверие для финансирования и расширения

2.3.4. Разнообразие устройств и абстракция сервисов#

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

Два основных подхода:

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

Лучшая практика: Многоуровневый подход Большинство зрелых операций используют оба: вендорно-специфические драйверы снизу (один уровень на тип устройства), затем общий уровень абстракции выше. Это даёт вам преимущества обеих стратегий.

Пример из реального мира: Создание альтернативы DMVPN Сетевые вендоры предлагают DMVPN (Dynamic Multipoint VPN) для масштабируемости VPN в топологии hub-spoke. Альтернатива — настройка множества простых соединений типа точка-точка вместо этого. Однако без автоматизации это громоздко (и именно причина существования протокола). Управление тысячами туннелей с автоматизацией выполнимо (и не чрезвычайно сложно), и обеспечивает аналогичную масштабируемость через оркестрацию, а не сложность протокола, поскольку практически все платформы поддерживают базовые VPN-туннели. Вы заменили зависимость от протокола абстракцией автоматизации: часто это лучший компромисс.

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

2.3.5. Заблуждение об инструментах вместо проектирования#

Хотя инструменты необходимы, они не заменяют хорошее проектирование. Распространённая ошибка: покупка инструмента с ожиданием, что он решит проблемы автоматизации. Инструменты важны, но они усиливают существующую архитектуру и проектирование. Хорошо спроектированная стратегия автоматизации с посредственным инструментом превосходит плохо спроектированную стратегию с лучшим доступным инструментом.

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

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

В Главе 3 мы исследуем эталонную архитектуру, выделяющую основные строительные блоки, которые необходимо учитывать при оценке инструментов.

2.3.6. Покупать vs. Строить#

Общий стратегический вопрос: следует ли купить готовое решение, создать пользовательскую автоматизацию или использовать гибридный подход?

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

При оценке решения:

  • Покупать: Используйте, когда продукт близко соответствует вашим потребностям, поддерживает вашу архитектуру, и анализ затрат-выгод благоприятен
  • Строить: Используйте, когда ваши требования уникальны, у вас есть экспертиза, или готовые решения не соответствуют вашим принципам

Это фундаментально решение о проектировании, а не о закупках. Речь идёт о том, сколько настройки и контроля вам действительно нужно.

На практике большинство организаций используют гибридный подход: покупают стратегические компоненты (платформы оркестрации, CI/CD-системы, хранилища данных), но создают доменно-специфическую автоматизацию (шаблоны, рабочие процессы, логику валидации). Вы должны владеть доменно-специфическим уровнем: универсальные рецепты редко дают нужные результаты.

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

2.3.7. Управление автоматизацией#

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

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

Управление в этом контексте означает определение четырёх вещей:

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

  • Процесс согласования логики: изменения в логике автоматизации (новые плейбуки, изменённые шаблоны, обновлённые модели данных в SoT) должны проходить процесс проверки, эквивалентный code review в программном обеспечении. Дисциплина здесь отражает разработку ПО: изменения кода, работающего в производстве, требуют проверки до его попадания туда. Код автоматизации ничем не отличается.

  • Авторизация выполнения: кто может запускать какое задание, в какой области действия, при каких условиях. Это напрямую соответствует ролевому управлению доступом на уровне Выполнения (Глава 5) и уровне Представления (Глава 8). Модель управления должна быть выражена в средствах управления доступом инструментов, а не только в документе с политиками.

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

Управление — не бюрократия ради бюрократии. Это механизм, с помощью которого организации постепенно расширяют доверие к автоматизации. Начало с операций с низким риском, обратимых и хорошо понятных, и расширение области действия по мере того, как автоматизация зарабатывает репутацию, эффективнее, чем либо полная блокировка автоматизации, либо её развёртывание без ограничителей.

2.3.8. Почему эти принципы важны: обучение на ошибках#

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

Разбор случая: сбой Meta

В октябре 2021 года Meta (бывший Facebook) столкнулась с глобальным сетевым сбоем, который вывел их системы из строя на несколько часов. Что его вызвало? Автоматизация усилила неверную конфигурацию. Во время плановой смены трафика автоматизированные системы вносили глобальные изменения на основе неполной валидации политик. Конфигурация распространялась по их сети, вызвав единую точку отказа с глобальными последствиями.

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

  • Отсутствие идемпотентности: Изменения применялись без проверки текущего состояния
  • Отсутствие транзакционности: Одни устройства получили изменение, другие — нет (частичный сбой)
  • Недостаточное тестирование: Сценарий не был выявлен в предпроизводственной среде
  • Отсутствие возможности пробного запуска: Изменения применялись без предварительного просмотра или валидации
  • Плохое версионирование: Невозможно быстро идентифицировать и откатить проблемное изменение
  • Недостаточная наблюдаемость: Недостаточно быстрое обнаружение сбоя
  • Отсутствие деградированного режима: Изменения каскадом распространились глобально без ограничения радиуса поражения
  • Неясные обязанности: Нет чёткой иерархии принятия решений для автоматизации

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

Урок: Не автоматизируйте хаос, надеясь исправить его позже. Вместо этого:

  1. Начинайте с процессов, которые вы понимаете и можете проверить
  2. Автоматизируйте постепенно, обучаясь на каждом шаге
  3. Рассматривайте каждый сбой автоматизации как возможность для обучения
  4. Встраивайте защитные меры: ограничения скорости, механизмы отката, наблюдаемость, ограничение радиуса поражения
  5. Разделяйте задачи, чтобы сбои в одной области не распространялись глобально

Обратите внимание, как это соотносится с подходом “Люди, Процесс и Технологии”, представленным в Главе 1.

Принципы, которые мы исследовали (Intent-Driven, Идемпотентность, Transactional, Versioning, тестируемость и возможность Dry Run) напрямую устраняют эти режимы сбоя. Они не являются опциональными функциями; они — необходимые защитные меры, которые должны быть встроены с самого начала.

2.4. Принципы разработки ПО#

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

Не все двенадцать имеют равный вес в этой области. Четыре устраняют режимы сбоя, специфичные для автоматизации критически важной инфраструктуры: Принцип наименьшего удивления (автоматизация, ведущая себя неожиданно, разрушает операционное доверие, установленное в разделе 2.1, до того как оно успевает укорениться), Защитное и надёжное программирование (сети отказывают частичным, недетерминированным образом, который автоматизация должна предвидеть по замыслу, а не обрабатывать как исключения), Быстрый и видимый сбой (раннее обнаружение сбоев ограничивает радиус поражения до его масштабирования на устройства), и Разделение задач (структурный принцип, который фреймворк NAF в Главе 3 непосредственно воплощает — разделение намерения, логики выполнения и представления здесь не является общей хорошей практикой, это конкретная структура, которая сохраняет независимую эволюцию блоков). Оставшиеся восемь принципов — стандартная гигиена разработки ПО: правильные, важные и заслуживающие знания, но не причина, по которой сетевая автоматизация конкретно терпит неудачу или имеет успех.

Мы организуем их в две категории, вдохновившись Robert C. Martin’s “Clean Code” и “Clean Architecture”:

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

Сосредотачиваясь на их применении к сетевой автоматизации, хорошие примеры этих принципов можно найти в этой серии блогов Network to Code авторства Ken Celenza.

2.4.1. Принципы чистого кода#

В этом разделе акцент на том, как создаются программные компоненты.

Пишите код для читателей

Код, который вы пишете, будет прочитан много раз в будущем: вами (при отладке) или другими. И у них, скорее всего, не будет вашего оригинального контекста. Выражайте своё намерение чётко в коде через значимые имена, комментарии и структуру (пожалуйста, не злоупотребляйте комментариями; используйте их осторожно). Код автоматизации — это не просто инструкции для машин; это форма документации для людей.

DRY — Не повторяйся

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

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

Когда вы нарушаете DRY, исправление в одном месте требует исправлений в пяти других, и вы неизбежно пропустите одно.

Принцип единственной ответственности (SRP)

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

  • Рендерер шаблонов конфигурации не должен также обрабатывать обнаружение устройств
  • Рабочий процесс валидации не должен также выполнять изменения

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

Быстрый и видимый сбой

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

  • Проверяйте данные сразу при вводе (не ждите развёртывания)
  • Делайте вывод Dry Run явным и очевидным
  • Журналируйте сбои с полным контекстом, а не расплывчатыми кодами ошибок
  • Немедленно оповещайте операторов при возникновении проблем

Раннее выявление проблем снижает радиус поражения и время реагирования.

Безопасность

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

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

Мы глубоко рассмотрим вопросы безопасности и соответствия требованиям в Главе 12.

Принцип наименьшего удивления

Автоматизация должна вести себя так, как ожидают пользователи. Удивительное или контринтуитивное поведение подрывает доверие.

Например, если задача автоматизации называется “deploy_interface”, операторы ожидают, что она создаст интерфейс, а не удалит его. Неожиданное поведение разочаровывает пользователей и вызывает ошибки.

Защитное и надёжное программирование

Встраивайте повторные попытки, паттерны Circuit Breaker, Compensation Logic и резервные механизмы. Распределённые системы отказывают. Проектируйте с учётом этого, а не против. Если устройство временно недоступно, повторяйте попытку с экспоненциальной задержкой, а не немедленно завершайте с ошибкой. Если изменение не удалось на полпути, имейте план отката.

Эти паттерны конкретно проявляются в Главе 7 (Оркестрация), где паттерн компенсации Saga обрабатывает частичные сбои рабочего процесса, а логика повторных попыток/задержки встроена в функциональность устойчивости.
“Будьте консервативны в том, что отправляете, будьте либеральны в том, что принимаете.” Закон Постела (RFC 761)

В сетевой автоматизации:

  • Консервативная отправка: Убедитесь, что данные, отправляемые в API или устройства, соответствуют строгим схемам и контрактам
  • Либеральное принятие: Будьте готовы обрабатывать вариации (например, атрибуты как целые числа или строки с преобразованием) для максимальной совместимости с различными версиями систем

Этот принцип соединяет чистый код с архитектурой. Он влияет как на то, как вы пишете логику интеграции, так и на то, как вы структурируете системные интерфейсы.

2.4.2. Принципы чистой архитектуры#

Далее мы исследуем принципы, управляющие тем, как компоненты решения по сетевой автоматизации соединяются вместе.

KISS — Делай проще, глупец

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

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

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

Разделение задач

Чётко разделяйте данные (конфигурацию), логику (рабочие процессы) и представление (API/UI). Это предотвращает тесную связанность и обеспечивает независимую эволюцию каждого уровня.

В сетевой автоматизации:

  • Уровень данных: Сетевое намерение, хранимое как структурированные данные
  • Уровень логики: Движки автоматизации и правила валидации
  • Уровень представления: API, CLI, панели управления для операторов

Это разделение позволяет изменять способ взаимодействия операторов с автоматизацией, не затрагивая базовую логику. Это разделение напрямую соответствует строительным блокам NAF: уровень данных — это Источник истины (Глава 4), уровень логики охватывает Выполнение (Глава 5), Наблюдаемость (Глава 6) и Оркестрацию (Глава 7), а уровень Представления — это Глава 8. Глава 3 представляет полный фреймворк NAF.

Наблюдаемость

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

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

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

Расширяемость

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

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

Минимальная связанность, максимальная связность

Определяйте чёткие контракты для взаимодействия систем: схемы, правила валидации и политики обратной совместимости. Эти контракты обеспечивают независимую эволюцию компонентов.

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

Всегда подходите к каждой системе с дизайном API-First: проектируйте API сначала (а не реализации). Это обеспечивает независимую разработку систем и их замену без нарушения других компонентов.


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

2.5. Резюме#

В этой главе было установлено, что доверие — это фундамент успешной сетевой автоматизации. Доверие возникает из четырёх основных качеств: Predictable, Reliable, Usable и Understandable.

Эти качества поддерживаются шестью основополагающими принципами проектирования:

  1. Управление намерением: Определите, чего вы хотите достичь, прежде чем — как этого достичь
  2. Идемпотентность: Повторные выполнения дают согласованные результаты
  3. Транзакционность: Изменения завершаются полностью или безопасно завершаются неудачей, никогда частично
  4. Версионирование: Отслеживайте все изменения с полной историей и журналами аудита
  5. Тестируемость: Проверяйте поведение перед развёртыванием в производство
  6. Дружественность к пробному запуску: Предварительный просмотр изменений перед выполнением

Помимо этих основных принципов, мы исследовали паттерны архитектурных решений (декларативный vs. императивный, greenfield vs. brownfield, абстракция устройств) и принципы разработки ПО (чистый код и чистая архитектура), операционализирующие эти паттерны в реальных системах.

Эти принципы не абстрактная теория: у них есть конкретные реализации в инструментах и фреймворках, которые вы будете использовать. На протяжении всей остальной части книги мы увидим, как архитектурное мышление (Глава 3) применяет эти принципы к более крупным системам, и как строительные блоки (Главы 4–9) операционализируют их.

Ключевые выводы:

  • Начинайте с принципов, а не с инструментов
  • Проектируйте для Predictable результатов, а не сложности
  • Измеряйте и улучшайте непрерывно

Когда вы делаете это последовательно, доверие следует естественно, а с доверием приходит способность масштабировать автоматизацию по всей вашей организации.

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

💬 Found something to improve? Send feedback for this chapter