3. 架构思维#
本章介绍本书的核心基础。它解释了为什么需要采用这种思维方式,介绍了网络自动化论坛(NAF)提出的参考框架,并展示如何在项目中加以运用。
第二部分将深入探讨这些主题。本章仅做高层概述,以便在深入细节之前建立整体认知。这一点至关重要,因为一旦我们描述各个构建模块,整体图景将帮助你将各部分串联起来。
但我坚信在了解"是什么"之前先理解"为什么",因此让我们首先理解运用架构的原因。
3.1. 参考架构的重要性#
“只有受过教育的人才是自由的。” —— 爱比克泰德
网络自动化解决方案由多个部分组合而成,每个部分各司其职。在网络领域,我们习惯于简单或单体化的解决方案,它们试图以一体化的方式解决所有问题。这在一定程度上可能成立,但没有任何方案能独立应对所有多样化的挑战和用例。因此,如果你的用例不属于最常见的那类,就可能需要定制或扩展。
若缺乏清晰的参考架构,团队往往会面临一系列可预见的问题:
- 重复工作:多个团队独立构建相似工具(数据源、重复脚本、冗余监控系统),浪费资源并造成接口不一致。
- 集成缺口:工具之间无法干净地协作,迫使团队承担昂贵的定制集成工作。
- 职责不清:不清楚哪个工具应负责可观测性、编排或状态管理,导致混乱和相互推诿。
- 难以扩展:增加新能力或工具时需要重新思考整个系统。
- 知识孤岛:不同团队使用不同的心智模型,导致新人上手困难,方案难以维护。
参考架构通过提供单一清晰的心智模型来解决这些问题,明确自动化系统应如何组织。它定义了:
- 每个组件应做什么 -> 其职责
- 组件如何交互 -> 其接口和数据流
- 可以做出选择的地方 -> 使用哪些工具
- 需要保持一致的地方 -> 组件如何相互通信
参考架构对网络工程师来说并不陌生。我们都是伴随着 OSI 模型成长起来的。OSI 模型提供了一种逐层诊断和理解网络问题的方法,因为每一层都有不同的职责和关注点。网络专业人员直觉地理解,这种关注点分离使复杂系统变得可管理。
在网络自动化中,我们需要类似的东西来指导如何开发和互联协同工作的解决方案。它帮助团队做出一致的决策,在项目间复用组件,并在不每次重新发明轮子的情况下演进自动化能力。
3.2. 网络自动化架构#
因此,我们需要一个架构。但请注意本节标题中的"一个":架构不止一种。架构只是一个参考框架,是一种组织思维、引导一致决策的方式。我参与了三项相关工作:
- Network to Code 参考架构,由 NTC 架构团队(我在其中工作了四年)主导的集体努力,旨在支持跨多种用例的高效、可理解的网络自动化。
- O’Reilly《网络可编程性与自动化》第二版,与 Matt Oswalt、Scott S. Lowe 和 Jason Edelman 合著,将全书内容串联成整体。
- NAF 框架,由 NAF 发起的社区项目,与 Wim Henderickx、Dinesh Dutt、Claudia de Luna、Ryan Shaw 和 Damien Garros 共同主导,目标是帮助新手和有经验的从业者以结构化、可重复的方式构建自动化解决方案。
在这些迭代过程中,我专注于保持一致性并从每次演进中汲取经验。三种方法各有价值。但我建议使用 NAF Framework 作为当前最佳实践:它由社区驱动、厂商中立、适用范围广。它凝聚了多年的集体智慧,并由一个积极活跃、不断壮大的社区持续维护。
三者相辅相成,而非互相竞争。简短的对比有助于明确各自最适用的场景:
| 架构 | 主要关注点 | 治理方式 | 最适用场景 |
|---|---|---|---|
| NTC 参考架构 | 有主见的工具选型与集成模式 | NTC 内部,持续演进 | 使用 NTC 工具栈、需要具体实施指南的团队 |
| O’Reilly 第14章 | 连接可编程性主题的概念框架 | 已发布,静态 | 希望了解自动化概念如何关联的读者 |
| NAF 框架 | 每模块含 MUST/SHOULD/MAY 的互操作性标准 | 社区维护,厂商中立 | 任何希望在多工具、多厂商环境中建立共同参考的团队 |
NAF 框架定义了模块之间的契约,并将实现选择留给使用者。NTC 架构用具体工具推荐来填充这些选择。如果你的团队使用 NTC 工具栈,两者可以同时适用而不产生冲突。
NAF Framework 提出了以下架构:
block-beta
columns 7
space:1
block:layer1:5
Presentation["展示层"]
end
space:1
space:7
block:Observability:2
columns 2
%% ObsLabel["可观测性"]:2
ObservedState[("已观测状态")]:1
ObservedLogic["观测逻辑"]:1
end
space
block:Orchestration:1
columns 1
OrchLabel["编排层"]:1
end
space
block:Intent:2
columns 2
%% IntLabel["意图"]:2
IntendedState[("预期状态")]:1
IntendedLogic["意图逻辑"]:1
end
space:7
space
Collector["采集器"]:2
space
Executor["执行器"]:2
space
space:7
space:1
block:layer4:5
NetworkInfra["网络基础设施"]
end
Presentation <--> Observability
Presentation <--> Orchestration
Presentation <--> Intent
Observability <--> Orchestration
Orchestration <--> Intent
Collector --> Observability
Collector <--> Orchestration
NetworkInfra --> Collector
Orchestration --> Executor
Intent --> Executor
Executor --> NetworkInfra
classDef darkStyle fill:#5a4149,stroke:#4a9eff,stroke-width:2px,color:#e8e8e8,font-size:20px,font-weight:bold
class Presentation,NetworkInfra,ObsLabel,IntLabel,Collector,Executor,ObservedState,ObservedLogic,IntendedState,IntendedLogic,OrchLabel darkStyle
该架构包含以下模块,定义来自框架文档:
- Intent (Architectural Block):定义处理逻辑和持久化层,用于存储网络的 Desired State,涵盖配置和运营期望。
- Executor:涵盖作用于网络以驱动变更(更新配置)的实际任务,以预期状态为指引。
- Collector:与 Executor 相对,该组件专注于检索(读取)网络的 Actual State。
- Observability:持久化网络的 Actual State,并定义处理逻辑。
- Orchestrator:定义自动化任务如何协调并响应事件执行。
- Presentation (Layer):提供用户与系统交互的接口,包括仪表板、图形用户界面(ITSM)和 Command Line Interface (CLI) 工具。
该架构并非任意设计,而是将软件工程原则应用于网络运营的自然结果。
NAF 框架旨在帮助网络自动化架构师通过参考各模块的功能来组织解决方案,并以 RFC 风格定义 MUST、SHOULD 和 MAY。然后,你可以决定如何实现它们来解决自己的用例。
拥有多个组件并不意味着每个组件都必须选用一种工具。在很多情况下,你可以使用一个实现不同功能的工具,但这需要理解(并承认)其中的权衡。
接下来,我们将逐一介绍不同的模块。
3.2.1. 意图(真实数据源)#
意图包含了所有必要信息,定义了将网络从零状态带到完全运行所需的一切,涵盖所有不同的生命周期阶段,从预配置到引导启动,到完全运行,再到最终停用所有类型的网络服务。
架构将其命名为意图(Intent),但我将其与另一个流行术语对应:真实数据源(Source of Truth,SoT)。SoT 这个词有时会被误解,我想先澄清 SoT 或意图是什么(在本书中我将交替使用这两个术语)。
可以想象,这可能涵盖非常多样的数据,包括设备、IP 地址规划、数据中心基础设施(机架、线缆)、路由协议、虚拟化服务、密钥、运营限制、配置模板以及服务或策略抽象。一个关键方面是这些数据必须结构化以便机器理解。然后,它必须支持创建、读取、更新和删除操作,并通过规范化、文档完善的 Application Programming Interface (API)(如 Representational State Transfer (REST) 或 GraphQL)进行访问。
类比于手动网络管理,这主要对应网络架构师(定义设计和网络方案)或网络规划师(为新网络部署定义物料清单)的角色。
理想情况下,即使数据分散在多个数据源中,该组件也应提供对预期状态的一致统一视图。这些数据源(我称之为记录系统,Systems of Record,SoR)是数据的实际所有者。因此,首先需要澄清的是:拥有唯一数据源极为罕见,但整合后的数据必须保持一致。数据管理是一个复杂话题,需要数据治理功能,包括时间戳、数据来源、数据所有权和有效期等元数据,以便理解和管理这些数据。
此外,与实现可信网络自动化的功能相关,该模块应提供事务性和版本化的数据访问,以实现可预测、可靠的网络自动化流程。
如果你想了解哪些实际工具可以归入此类,以下是一些示例:CSV/YAML/JavaScript Object Notation (JSON) 文件、Git、NetBox、Nautobot、Infrahub、Infoblox,或任何通用数据库。
详见第 4 章,深入了解如何构建和管理真实数据源。
3.2.2. 执行器#
执行器负责将来自意图的预期状态写入实际网络状态,通过 SSH、NETCONF、gNMI/gNOI 和 REST API 等不同接口与网络交互。
继续类比手动网络管理,执行器相当于准备最终网络配置并通过 CLI 连接到网络设备输入配置命令的网络工程师。
然而,这并非简单地将数据从一处(意图)复制粘贴到另一处(网络)。需要考虑许多操作,从网络变更到重启或升级系统。此外,尽管大多数时候参考数据来自意图模块,但在某些情况下,来自可观测性的已观测数据可能会影响该组件,因此两者必须结合使用。
例如,执行器可能在尝试变更之前验证设备可达性,根据当前网络状态调整故障切换逻辑,或者当可观测性显示关键依赖服务宕机时跳过执行。这种来自可观测性的反馈确保自动化决策基于实时网络状况,而不仅仅依赖意图。
与意图类似,该组件应提供预演(dry-run)、事务性变更和幂等性(通过声明式或命令式方法)等功能,帮助构建网络工程师可以信赖的自动化系统。这通常是网络工程师(最初)最关心的组件,因为它是实际"改变"网络的那个。
最适合此类别的工具包括 Ansible、Terraform/OpenTofu,或任何利用 Netmiko、Scrapli 或 Napalm 等库的脚本,甚至是 Kubernetes CRD(自定义资源)。
前往第 5 章探索执行框架、幂等性模式和实施策略。
3.2.3. 采集器#
与执行器类似,采集器负责通过不同接口和协议从网络检索实际运营数据(与执行器相同的接口,另加 SNMP、Syslog 或其他基于流的遥测)。
所有这些数据的目的地是可观测性模块,数据在那里被用于驱动自动化决策。
这里有一个重要议题,通常未被考虑,即需要规范化数据以便比较。因此,为所有厂商获取一致的指标名称(system_version 独立于平台定义操作系统版本)以及用于高级数据处理的一致元数据至关重要。
适合此类别的工具示例包括 Telegraf、Vector、gNMIc、PMACCT、goFlow、Akvorado,或任何利用库从网络获取数据的脚本。
由于亲缘性,我将采集器与下一个构建模块可观测性一起在第 6 章中介绍。采集器和可观测性在架构上是独立的,但在运营上是密不可分的:关于如何采集数据的每个设计决策都由可观测性层需要处理什么来驱动。将它们放在一起介绍保留了这种依赖关系。
3.2.4. 可观测性#
与采集器密切相关(很多情况下一并出现),可观测性接收采集的数据,支持其持久化,并提供程序化访问以支持高级分析、报告和故障排查工作流,理想情况下使用功能强大的查询语言(如 PromQL)。
该模块的数据必须暴露网络 Desired State 和 Actual State 之间的相关差异,生成可触发缓解系统的事件(或告警)。
继续类比手动网络管理,这对应网络运营中心的角色,检查网络实际状态并相应作出反应。
此外,已观测数据可以用来自预期状态的上下文信息进行丰富,包括其他第三方来源(如生命周期终止信息、CVE、维护通知等),从而增强分析能力并实现更准确的数据关联。
在传统网络监控中,可观测性(和采集)的所有功能都集成在一个大型系统中(如 Nagios、LibreNMS、Spectrum 等工具)。
目前,更多样化的集成系统正在获得普及,Prometheus 和 InfluxDB 是流行的 Time Series Database (TSDB),Elasticsearch 及相关系统负责管理告警(Alertmanager)和可视化(Grafana、Kibana)。这催生了一些流行的技术栈:ELK、TIG 和 TPG。
在第 6 章中了解更多关于监控架构、告警策略和可观测性最佳实践的内容。
3.2.5. 编排器#
到目前为止,你已经看到许多不同的组件,需要对它们进行协调:整合不同构建模块的流程,创建复杂的端到端自动化工作流。因此,编排器必须支持多种交互方式,从手动触发到完全事件驱动的工作流,支持同步和异步两种模式。
编排器实现的工作流应提供定义多个步骤的方式,还必须支持回滚和预演功能,依赖其他组件(例如,使用来自意图模块的版本化快照)。
在手动操作中,这通常以必须遵循的流程核对表的形式松散定义。
该组件为用户提供整个网络自动化运行情况的全面可视化,通过清晰的日志记录和可追溯性展示不同流程如何协同运作。
此类别的示例工具包括 AAP 或 AWX(Ansible 自动化平台)、Windmill 或 Prefect。
AI 和智能体在架构中的位置: AI 辅助决策主要位于编排器和可观测性模块的交叉点。AI 智能体遵循感知-推理-行动循环:通过可观测性模块观察网络状态,应用推理决定所需操作,并通过编排器触发执行器。这与编排器的传统角色(遵循预定义工作流)不同,但使用相同的基础设施。第 7 章(编排,7.2.7 节)将智能体方法作为协调模式进行介绍;第 15-17 章将其作为自治网络的基础进行探讨。现在,可以将智能体自动化理解为一种以动态、模型驱动的决策替代静态工作流定义的协调方法。
深入第 7 章了解工作流设计、事件驱动自动化和编排平台。
3.2.6. 展示层#
有时我们会忘记向网络自动化用户暴露合适接口的重要性。这通常是一个模糊的领域,因为我们已经介绍的所有工具都有某种接口:CLI、API 或基于 Web 的界面。在某些情况下,你可能认为这已经足够。在其他情况下,你可能需要创建自己的用户界面,以充分发挥各工具的优势并简化用户体验。这取决于具体情况。
传统上,对外部用户来说,这仅限于电话或电子邮件,对网络团队来说则是 CLI。
无论如何,该层必须支持灵活的身份验证和授权(它是系统的入口点),然后适应实际需求。有时这可能是一个特定于网络的平台,有时可能与公司范围的系统集成(如 ServiceNow、Slack 等)。
根据角色的不同,它可以涵盖写入或读取操作,但始终要考虑不同类型用户的需求以获得最佳效果。
在第 8 章中探索用户体验、接口设计和集成模式。
3.2.7. 网络#
最后但同样重要的是,我们必须了解网络支持自动化的能力,而网络不再只是相互连接的设备和线缆。在 2020 年代,虚拟化和基于云的网络解决方案使端到端可达性(网络)成为一个混合多样的环境。
网络本身既是整个自动化架构的约束,也是其使能者。与你可以控制的前六个模块不同,网络基础设施(你的设备、平台、服务和连接)可能存在影响可行性的限制。
网络能力分为以下几个类别:
- 接口与协议:你的网络支持哪些管理接口?SSH CLI?NETCONF?gNMI?REST API?SNMP?有些平台支持很多,有些支持很少。这些选择直接约束了采集器和执行器能做什么。
- 数据模型:即使设备支持 gNMI,它暴露的 YANG 模型也可能不完整。例如,你的设备可能声称支持 gNMI,但未暴露你需要管理的特定配置。在规划阶段了解这些差距至关重要。
- 运营成熟度:较新的平台可能有现代 API 但行为未文档化。较老的平台可能稳定但完全缺乏 API。你需要评估实际的成熟度,而不仅仅是宣传的功能。
为有效支持自动化,你的网络基础设施理想情况下应提供:
- 开发和测试环境:与软件开发一样,自动化需要安全的测试场所。这可能意味着:实验室网络(通常昂贵且受限)、虚拟网络环境(Containerlab、GNS3),或厂商提供的模拟器(Cisco DevNet、Arista EOS-lite)。
- 一致的接口:如果 90% 的设备支持 NETCONF 但 10% 只支持 SSH,你要么需要标准化,要么构建多个执行器。每一处不一致都会增加复杂性。
- 充足的遥测:如果无法从设备获取所需数据,可观测性将变得毫无意义。确保你的设备能以你需要的粒度和信息流式传输遥测数据(流式遥测、SNMP、syslog)。
网络是架构中最难改变的部分。你无法轻易更换路由器。因此,要尽早了解其约束,并在这些约束内设计自动化。这就是为什么网络模块在架构规划阶段值得仔细关注。
在第 9 章了解网络能力、设备 API 和测试环境。
接下来,为了总结本节,让我们通过一个非常简单的用例来了解架构如何与之对应。
3.2.8. 一个实际示例#
在我们深入每个模块之前,让我们通过一个具体场景来展示架构如何协同运作。
问题:应用团队提交了一个新应用网段的请求:在一个运行约 800 台接入和汇聚交换机(来自 Cisco、Arista 和 HPE)的异构园区网络中,需要新建一个 VLAN、IP 子网、路由策略和访问控制区域。运营团队需要在不对数百台设备进行手动 CLI 操作的情况下端到端完成这项工作。
架构如何解决它:
- 意图(真实数据源):网络工程师在 Nautobot 中录入新服务定义:VLAN ID、子网、路由策略、各厂商配置模板,以及适用的交换机组。这作为 Desired State 存储,是 800 台设备的唯一真实来源。
- Orchestrator:AWX 收到来自 Nautobot 的变更 webhook,触发执行工作流,按正确顺序协调各步骤并处理每台设备的故障。
- Executor:一个 Ansible Playbook 从 Nautobot Application Programming Interface (API) 读取数据,为每个厂商(Cisco、Arista 和 HPE 各需要不同语法)渲染设备专属配置,并通过 NETCONF 推送变更。每次运行都是幂等的:在已配置的交换机上再次运行不产生变更。
- Collector:部署完成后,gNMIc 采集器连接到每台交换机,检索实际的 VLAN 成员、接口状态和路由条目。
- Observability:采集的数据流入 Prometheus Time Series Database (TSDB)。一个查询将 Desired State(来自意图)与 Actual State(来自 Collector)进行对比。缺少 VLAN 的交换机以指标形式暴露并触发告警。
- Orchestrator:当告警触发(“access-switch-b3-07 上不存在 VLAN 210”),AWX 工作流自动在该交换机上重新运行 Executor,重新采集数据并验证修复结果。
- Presentation (Layer):仪表板按楼栋和厂商显示全部 800 台交换机,突出显示哪些合规(✅)哪些已发生漂移(❌)。应用团队无需 CLI 访问即可跟踪部署进度。IT 运营团队无需编写代码即可触发手动修复。
- 网络:这个流程的成功取决于设备实际支持什么。Cisco 和 Arista 上 NETCONF 运行良好。几台 HPE 交换机只支持 SSH CLI,因此需要一条单独的执行器路径来处理,不够优雅但有必要。没有任何架构能消除厂商约束;它只是让这些约束变得明确。
核心洞见:没有单一工具完成了这一切。Nautobot(意图)、Ansible(执行器)、gNMIc(采集器)、Prometheus(可观测性)、AWX(编排器)和 Grafana 仪表板(展示层)共同协作。架构提供了如何整合它们的心智模型。
这就是架构思维所能实现的:系统化、可组合的自动化。
在第二部分(第 4-9 章)中,我们将回到这个相同的园区网络,深入探讨每个构建模块:SoT 存储 VLAN 服务定义(第 4 章),执行器部署它(第 5 章),可观测性监控它(第 6 章),编排器协调完整生命周期(第 7 章),展示层向不同受众暴露它(第 8 章),网络章节以基于仿真的预生产验证环节收尾(第 9 章)。示例中引用真实数据源工具时,Nautobot 和 NetBox 可互换使用;无论选择哪个,架构模式都是相同的。
3.3. 如何使用架构#
现在你已经了解了 NAF 网络自动化架构的不同构建模块,你可能会想:“我实际上如何在项目中开始使用它?”
3.3.1. 逐步采纳方法#
参考架构并非一种规定。它是思考和组织自动化解决方案的框架。以下是应用它的实用、逐步方法:
flowchart LR
A[了解当前状态]:::phase1 --> B[规划自动化路径]:::phase2
B --> C[做出更好的工具与设计决策]:::phase3
C --> D[为集成而设计]:::phase4
D --> E[与利益相关方沟通]:::phase5
E --> F[增量演进]:::phase6
classDef phase1 fill:#e0f7fa,stroke:#333,stroke-width:2px;
classDef phase2 fill:#b2ebf2,stroke:#333,stroke-width:2px;
classDef phase3 fill:#80deea,stroke:#333,stroke-width:2px;
classDef phase4 fill:#4dd0e1,stroke:#333,stroke-width:2px;
classDef phase5 fill:#26c6da,stroke:#333,stroke-width:2px;
classDef phase6 fill:#00bcd4,stroke:#333,stroke-width:2px;
阶段 1:了解当前状态
首先将现有工具和流程映射到架构模块。这个评估练习帮助你识别差距、重叠和潜在改进领域:
- 你的数据是否分散在多个系统中?
- 你是否在有效采集网络状态,还是完全盲目运营?
- 你目前如何执行变更?手动操作?临时脚本?有组织的框架?
如果你发现执行能力出色但可观测性薄弱,你就找到了下一个高价值待解决的问题。
阶段 2:规划自动化路径
利用架构指导自动化路线图。你不需要一次性实现所有模块。从解决最关键痛点的组件开始:
- 如果你在与配置漂移作斗争,重点关注意图/真实数据源和执行。
- 如果你无法快速发现问题,优先考虑采集器和可观测性。
- 如果你的自动化零散且不可靠,投资于编排。
- 如果用户对如何请求变更感到困惑,改善展示层。
按业务影响优先排序,而非追求架构完整性。
阶段 3:做出更好的工具与设计决策
在评估新工具或构建定制解决方案时,问自己:
- 这服务于哪个架构模块?
- 它与我的其他组件集成良好吗?
- 我需要模块之间哪些数据流?
这可以防止工具蔓延,并确保你的自动化生态系统保持内聚。它也明确了是应该自建还是采购。如果一个工具清晰地适合某个模块且接口定义明确,通常采购优于自建。
阶段 4:为集成而设计
理解组件之间的边界有助于设计更好的接口。核心原则:组件不应需要了解彼此的内部细节。
- 执行器不需要知道意图如何存储数据:它只需要一个定义良好的 API 来查询预期状态。
- 编排器不应关心你使用的是 Ansible 还是 Terraform:它只需触发执行并监控结果。
- 可观测性系统不需要了解采集器的内部细节:它只需要清晰的指标和事件。
这种解耦使你能够独立演进每个组件。
阶段 5:与利益相关方沟通
架构为与不同受众讨论自动化提供了共同语言:
- 对管理层:“我们正在加强可观测性以降低 MTTR。”
- 对团队:“让我们标准化采集器向可观测性发送数据的方式。”
- 对其他部门:“我们的展示层将与你们的 ITSM 系统集成。”
清晰的架构语言减少混乱并有助于获得支持。
阶段 6:增量演进
架构允许你随着需求变化替换组件:
- 今天你可能使用 Git 作为真实数据源,但明天可以在不完全重新设计自动化工作流的情况下采用 NetBox 或 Infrahub,只要你保持清晰的接口。
- 你可能从一个简单脚本作为编排器开始,之后用 AAP 或 Windmill 替换它。
- 你可以在不干扰采集器检索数据方式的情况下,将可观测性中的 TSDB 从一个迁移到另一个。
这种演进式方法最大限度地降低了风险,并允许你在实践中学习。
不要陷入过度工程的陷阱。目标不是架构纯粹性,而是解决实际问题的实用自动化。有时最好的解决方案是一个跨越多个架构模块的简单脚本。架构是指南,不是束缚。
核心要点:将架构作为心智模型来组织思维、识别差距并做出深思熟虑的设计决策,而不是规定每个实现细节的刚性模板。
3.3.2. 常见陷阱#
说实话:你会犯错误。但向他人学习可以为你省去很多痛苦。以下是常见陷阱:
试图一次性实现所有内容
很容易这样想:“如果这个架构很好,我应该完美构建所有七个模块。“这会导致庞大的多年期项目在完成之前就已过时。
更好的方法:从解决最紧迫问题的一两个模块开始,增量构建。早期成功积累动力和支持。
相信"一个工具统治一切”
某些厂商声称他们的平台能做一切。虽然可能确实如此,但这通常意味着:
- 你被锁定在他们的做事方式中
- 之后无法替换组件
- 你为不需要的功能付费
更好的方法:为每个模块选择最优工具,但确保它们有清晰的 API 和集成点。接受你可能需要集成 3-5 个工具,但你将拥有灵活性。
忽视网络约束
你设计了一个漂亮的使用 gNMI 的执行器,但 30% 的设备只支持 SSH CLI。或者你想要流式遥测,但旧平台只支持 SNMP。
更好的方法:首先了解网络基础设施的能力。这些约束塑造了你的架构。你不能无视物理规律,也不能无视设备实际能做什么。
假设接口会很简单
你说:“执行器只需调用意图的 API 获取预期状态。“但意图使用带有自定义扩展的 NetBox,而执行器期望的是平坦的 YAML。突然间你在编写转换层。
更好的方法:提前投入建立清晰、文档完善的接口。尽可能使用标准(REST API、gRPC、清晰的 schema 定义)。好的接口现在花费较少,而转换层之后花费更多。
在已有好工具的情况下构建自定义工具
你的团队决定构建一个自定义采集器,因为"没有工具完全满足我们的需求”。六个月后,你有了 3000 行代码在维护专有遥测管道。
更好的方法:首先评估现有工具(Telegraf、Vector、gNMIc)。它们处理 80% 的用例,且经过实战检验。如有需要,对其定制或构建适配器,但不要从零开始构建。
将可观测性视为事后补充
许多团队专注于意图和执行器,然后太晚才意识到无法看到网络中实际发生的情况。可观测性最后才被加上。
更好的方法:从第一天起就规划可观测性。你将采集哪些指标?如何检测漂移?哪些告警重要?在构建执行器之前回答这些问题。
忘记用户
工程师构建了一个强大的编排器,但用户与它交互的唯一方式是通过 CLI 命令。非技术用户感到困惑;采用率很低。
更好的方法:尽早考虑你的用户。他们需要什么接口?API?Web UI?ServiceNow 集成?有时展示层决定了采用的成败。
这些陷阱不是理论性的,它们是真实自动化项目中的模式。现在从中学习将使你的架构更强大。
3.3.3. 从哪里开始#
架构定义了七个模块。没有人会一次性实现所有七个。在实践中,两种起始模式占了真实部署的大多数。
模式 A:配置驱动启动(最常见)
已经手动管理配置、希望使这一过程一致化和自动化的团队。从意图和执行器开始:建立真实数据源并构建从中部署的 Playbook。一旦执行稳定并需要对实际部署情况的反馈,再添加可观测性。
flowchart LR
A[意图 / SoT] --> B[执行器] --> C[可观测性] --> D[编排器] --> E[展示层]
style A fill:#4a9eff,color:#fff
style B fill:#4a9eff,color:#fff
style C fill:#7db8f7,color:#fff
style D fill:#b8d4f5,color:#333
style E fill:#ddeeff,color:#333
模式 B:可见性驱动启动
主要痛点是不知道网络当前状态的团队。从采集器和可观测性开始:先建立数据管道,了解实际部署了什么,然后在获得可靠图景后再添加意图和执行器进行部署。
flowchart LR
A[采集器] --> B[可观测性] --> C[意图 / SoT] --> D[执行器] --> E[编排器]
style A fill:#4a9eff,color:#fff
style B fill:#4a9eff,color:#fff
style C fill:#7db8f7,color:#fff
style D fill:#b8d4f5,color:#333
style E fill:#ddeeff,color:#333
在两种模式中,编排器和展示层都在核心数据流稳定之后才出现。在有可靠的意图或执行之前就启动编排器是过早的:还没有有意义的东西可以协调。一旦内部团队开始使用自动化并需要合适的接口而非直接 API 或 CLI 访问时,展示层就变得重要。
这些是起点,而非蓝图。你的约束(现有工具、团队技能、最紧迫的痛点)应该决定顺序。关键是要有意识地选择起点,而不是试图并行构建所有内容,结果什么都没完成。
3.3.4. 跨团队的模块所有权#
七个模块产生的是组织问题,同样也是架构问题:谁拥有什么,以及多个团队如何共享同一平台而不互相干扰?
中大型组织中最常见的模型分为两组。平台团队拥有自动化基础设施本身:SoT 的 schema 和 API、编排器运行时、可观测性管道、展示层以及共享采集器基础设施。这些是组织其余部分依赖的组件。平台团队的工作是保持它们可靠、版本化且可用。网络运营团队(或多个领域团队,每个技术领域一个)拥有自动化内容:在平台之上运行的 Playbook、工作流定义、预期数据和业务逻辑。他们消费平台;他们不维护平台。
这种分工对模块边界如何转化为团队边界有影响。SoT 是共享平台资源,但不同团队对其有不同的写入权限:IP 地址规划团队可能拥有 IPAM 数据;园区团队可能拥有交换机清单;安全团队可能拥有防火墙策略数据。SoT 的 Term "rbac" not found 模型必须映射到这些所有权边界。向错误域的写入操作是一个等待发生的运营事故。
编排器类似:平台团队拥有运行时和工作流执行框架;运营团队拥有工作流定义。工作流定义应在运营团队所有权下存储在版本控制中,在部署时由编排器拉取,而不是直接在编排器的 UI 中编辑。这使平台团队和运营团队不会相互干扰对方的工作。
展示层进一步划分所有权问题。其他自动化工具使用的内部 API 是平台关切。为应用团队提供的自助服务门户是产品关切,可能属于专门的工具团队或共享服务组。提前定义这些边界可以防止每个团队对同一底层平台构建各自的临时接口这一局面。
运营自动化平台的组织维度,包括团队如何围绕它组建、产品思维如何应用于内部工具,以及平台团队如何管理与内部消费者的契约,将在第 10 章(平台工程)和第 13 章(文化与协作)中深入探讨。这里做出的架构选择,特别是 SoT RBAC 范围和编排器工作流所有权,直接约束了那些章节描述的组织模型。
3.4. 总结#
架构思维对于构建真正有效的网络自动化至关重要。正如 OSI 模型为我们提供了一个理解网络的分层框架,参考架构帮助你组织和设计可维护、可扩展且可靠的自动化系统。
本章介绍了 NAF 框架,它定义了七个关键构建模块。架构并非刚性规定,而是灵活的框架。利用它来评估当前状态、规划自动化路径、做出明智的工具决策、与利益相关方沟通、为集成而设计并增量演进。记住:目标是解决实际问题的实用自动化,而非架构纯粹性。
在本书第二部分中,我们将深入探讨每个构建模块,探索你可以应用于自己自动化项目的实现模式、最佳实践和真实案例。
💬 Found something to improve? Send feedback for this chapter