Network-as-Code:把 HCIE / CCIE 实验脚本转为企业级 CI 工程化流程
写在前面:
在网络工程师的圈子里,HCIE 或 CCIE 证书曾被视为职业生涯的巅峰。然而,很多拿到"通关文牒"的工程师,在面对真实的生产环境时,却常有一种"有力使不出"的挫败感。
这种挫败感来源于一个残酷的现实:网络实验是一个"静态的瞬间",而企业网络是一个"动态的生命周期"。
我们曾引以为傲的复杂脚本,在多变的业务需求、严苛的 SLA 要求以及复杂的存量环境面前,往往显得脆弱不堪。这种断层,本质上是**"脚本思维"与"工程思维"**的断层。
本文将深度拆解:如何将那些"能跑通"的实验脚本,转化为"能交付"的企业级 CI(持续集成)工程体系。这不是在教你如何写出更好的代码,而是在讨论如何构建一套能够自我解释、自我验证且持续演进的网络状态系统。
1、为什么 HCIE / CCIE 实验脚本,天然不适合直接进入生产系统
在真正进入 Network-as-Code 之前,必须先直面一个现实问题:实验脚本,几乎在所有关键工程维度上,都是"不合格的生产输入"。
1.1 实验脚本的三个隐含前提(企业环境并不成立)
几乎所有认证实验脚本,都默认了以下前提:
第一,环境是"初始态"
- 接口没有被其他业务占用
- 设备上不存在历史策略
- 路由表、策略表是空的或可预测的
而企业网络的现实是:
- 状态是长期累积的
- 存在"你并不知道为什么存在"的配置
- 任何一条命令,都可能触碰未知依赖
第二,失败是可以接受的
在实验中:
- 配错了,删掉重来
- OSPF 不通,清进程
- BGP 异常,直接 reset
而在生产环境中:
- 一次 reset,可能就是 SLA 事故
- 一次误删 ACL,可能是业务中断
第三,结果只需"此刻正确"
实验脚本只关心:
"我现在敲完,通不通?"
企业系统关心的是:
"半年后,这套配置还能不能被人理解?"
1.2 缺乏'幂等性'意识
实验脚本通常是'增量式'的。执行第一次成功,执行第二次往往会报错(如:配置已存在)。而企业级 CI 要求脚本具备幂等性:无论执行多少次,系统的最终状态始终与代码定义的状态一致。这是实现'状态对齐'的技术前提。
1.3 一个典型实验脚本,在工程视角下的问题示例
以一个常见的三层交换 + OSPF 实验片段为例(高度简化):
interface Vlanif10
ip address 10.10.10.1 255.255.255.0 // 硬编码:IP与VLAN耦合,未模型化
ospf enable 1 area 0 // 隐式依赖:默认OSPF进程1已存在
#
interface GigabitEthernet0/0/1
ip address 192.168.1.1 255.255.255.252
ospf enable 1 area 0
#
ospf 1
router-id 1.1.1.1
area 0
从协议角度看,没有问题。
但从工程角度看,这段配置存在多个致命缺陷:
- 没有声明意图(为什么是 VLAN 10)
- 没有依赖分析(VLAN 是否已存在)
- 没有冲突检测(OSPF Process 是否已在用)
- 没有回滚路径
- 没有变更影响评估
这不是"写得不够好",而是表达层级完全不对。
2、Network-as-Code 的核心不是"代码",而是"状态建模"
很多人一提 Network-as-Code,就会直接联想到:
- Git
- YAML
- Ansible
- Terraform
这些都是工具,但不是核心。
核心问题只有一个:
网络工程中,什么才是"可被管理的最小状态单元"?
2.1 从"命令集合"转向"状态对象"
在实验中,我们操作的是:
命令 → 命令 → 命令
在工程系统中,我们必须操作的是:
对象 → 状态 → 约束
例如:
- VLAN 不是几行命令
- VLAN 是一个对象,包含:
- ID
- 名称
- 作用域
- 绑定关系
- 生命周期
这一步,是 Network-as-Code 与脚本自动化的根本分水岭。
2.2 网络工程中的四类核心状态对象
在企业级 Network-as-Code 系统中,几乎所有复杂度,都可以被归约到四类对象:
- Intent(意图)
业务或网络希望达到的目标状态 - Model(模型)
对网络资源的结构化抽象 - Template(渲染)
厂商 / OS / 版本相关的实现层 - Validation(校验)
状态变更前后的正确性与风险评估
这四类对象,决定了你是在"写脚本",还是在"构建系统"。
3、把 HCIE / CCIE 实验,拆解为 Intent 层
Intent 层,是大多数网络工程师最陌生、但也是最关键的一层。
3.1 实验中"隐含但未表达"的 Intent
例如,一个实验要求你:
在接入交换机上划分 VLAN 10、20,并通过三层交换互通。
在实验里,Intent 是隐含的;
在企业里,Intent 必须是第一等公民。
一个合理的 Intent 表达,应该接近:
intent:
network_segments:
- name: office_user
vlan_id: 10
subnet: 10.10.10.0/24
purpose: internal_access
- name: office_server
vlan_id: 20
subnet: 10.10.20.0/24
purpose: service_zone
connectivity:
- from: office_user
to: office_server
policy: allow
这里没有任何厂商命令,但已经表达了:
- 网络被划分为哪些逻辑域
- 每个域的用途
- 域之间的通信关系
3.2 AI 在 Intent 层的第一个真实价值点:语义补全与校正
Intent 层并不要求工程师"写得完美"。
在实践中,我们通常让 AI 介入两个关键动作:
- 补全隐含约束
- 发现语义冲突
例如,当工程师只写了:
network_segments:
- name: office_user
vlan_id: 10
AI 可以基于历史配置库与企业规范,自动补全:
- 子网规划建议
- 命名规范校验
- 与现有 VLAN 冲突的风险提示
这不是"自动生成配置",而是辅助完善意图表达。
4、Model 层:把"协议知识"转化为"结构知识"
如果说 Intent 层偏向业务与规划,那么 Model 层,就是 HCIE / CCIE 知识真正发力的地方。
4.1 实验知识,为什么一定要"结构化"才能工程化
在实验中,你掌握的是:
- OSPF 的 LSA 类型
- BGP 的 Path Selection
- ACL 的匹配顺序
但在工程系统中,这些知识必须被固化为模型规则,而不是存在于人的大脑里。
例如,一个 OSPF Area 模型:
ospf:
process_id: 1
router_id: auto
areas:
- id: 0
networks:
- 10.10.10.0/24
- 10.10.20.0/24
passive_interfaces:
- Vlanif10
这段模型:
- 明确了作用范围
- 显式表达被动接口
- 为后续校验提供了结构基础
此外,在 Model 层,不仅要定义'要做什么',还要定义'合规边界'。例如:禁止在核心层设备上出现超过 1000 条的 OSPF 路由,或者禁止在接入交换机开启特定的高危协议。这让 CCIE 的'避坑经验'变成了自动化的规则检查。
4.2 AI 在 Model 层的价值:规则推理与异常识别
在 Model 层,AI 不再是"生成器",而更像一个:
协议理解与规则推理引擎
典型能力包括:
- 判断模型是否违反协议最佳实践
- 推断隐含依赖(例如 VLAN 与 VRF 的绑定关系)
- 发现"结构上合法,但工程上危险"的组合
例如:
- OSPF Area 设计是否可能引发 LSDB 爆炸
- BGP 策略是否存在不可达路径
这些判断,单靠静态规则很难穷尽,而 AI 非常适合做"经验外推"。
5、从 Model 到 Template:多厂商渲染不是复制,而是语义映射
这一节,通常是"脚本思维"最容易翻车的地方。
5.1 为什么不能"一个模型,对应一个模板"
在实验环境里,你可能习惯于:
- Huawei 一套写法
- Cisco 一套写法
但在企业环境中,同一个模型,可能要面对:
- 不同厂商
- 不同 OS
- 不同版本
- 不同功能裁剪
因此,Template 层的核心不是"模板",而是:
语义映射关系
5.2 示例:同一 OSPF 模型的双厂商渲染(片段)
Cisco IOS-XE:
router ospf {{ ospf.process_id }}
router-id {{ router_id }}
{% for area in ospf.areas %}
{% for net in area.networks %}
network {{ net | ip_network }} area {{ area.id }}
{% endfor %}
{% endfor %}
Huawei VRP:
ospf {{ ospf.process_id }} router-id {{ router_id }}
{% for area in ospf.areas %}
area {{ area.id }}
{% for net in area.networks %}
network {{ net | to_wildcard_mask }}
{% endfor %}
{% endfor %}
在 Network-as-Code 体系中,这两段模板:
- 不应该被工程师手工维护一致性
- 而应该由 模型驱动 + AI 校验 来保证语义等价
6、网络 CI 不是 DevOps 的翻版,而是"状态系统"的工程化约束链
当网络工程师第一次接触 CI/CD 时,最常见的误区是:
把应用 CI 的思路,原样搬到网络上。
但网络和应用,在本质上完全不同。
应用是 过程系统 ,网络是 状态系统。
6.1 网络变更的核心风险,不在"执行",而在"状态跃迁"
在应用 CI 中,一次发布失败:
- 回滚代码
- 重启实例
- 业务恢复
而在网络中,一次失败的变更,往往意味着:
- 拓扑状态被破坏
- 路由收敛进入异常区间
- 流量路径不可预测
所以,网络 CI 的核心目标不是"自动化执行",而是:
约束每一次状态变化,只能发生在"可解释、可评估、可逆"的范围内。
6.2 一个可用于生产的 Network CI 流水线结构
下面是一条在真实企业网络中可以长期运行的 CI 流水线逻辑顺序(不是概念图,而是工程顺序):
Commit →
Intent 校验 →
模型结构校验 →
依赖与影响分析 →
配置渲染(Dry Run) →
AI 辅助审计(AI-Augmented Audit) →
人工审批(条件) →
分阶段发布 →
在线验证 →
自动回滚(条件触发)
这条链路里,没有一步是多余的。
7、从 Git Commit 开始:网络变更必须"先变成可审计事件"
Network-as-Code 的第一条硬约束是:任何网络变更,必须先变成代码变更
7.1 仓库结构示例
network-repo/
├── intent/
│ ├── segments.yaml
│ └── connectivity.yaml
├── model/
│ ├── vlan.yaml
│ ├── ospf.yaml
│ └── bgp.yaml
├── templates/
│ ├── cisco/
│ └── huawei/
├── policies/
│ ├── naming.yaml
│ └── security.yaml
├── pipeline/
│ └── ci.yaml
└── history/
└── snapshots/
这里的关键点是:
- Intent 与 Model 强制分离
- 模板是"被消费对象",不是核心资产
- history 目录用于状态快照与回溯
7.2 AI 在 Commit 阶段的第一个介入点:变更意图解释
当工程师提交一个变更时,例如:
- vlan_id: 20
- vlan_id: 30
AI 在这里要做的不是判断"对不对",而是生成人类可读的变更解释:
"将 office_server 网段从 VLAN 20 迁移到 VLAN 30,涉及三层网关、OSPF 宣告与 ACL 关联策略。"
这一段解释,后续会被复用在:
- 审批界面
- 变更文档
- 回溯审计
8、依赖与影响分析:这是网络 CI 的"生命线"
这是 HCIE / CCIE 知识真正产生壁垒的地方。
8.1 网络依赖不是线性的,而是图结构
以 VLAN 变更为例,它的依赖至少包括:
- VLAN ↔ 接口
- VLAN ↔ SVI
- SVI ↔ OSPF
- OSPF ↔ BGP(重分发)
- VLAN ↔ ACL / 安全策略
这些关系,必须被显式建模。
8.2 AI 在依赖分析中的真实作用
传统做法是:
- 写死规则
- 人工补充
而 AI 的优势在于:
- 从历史变更中学习"真实依赖"
- 发现非显性路径(例如间接重分发)
示例输出(AI 生成):
Impact Analysis:
- Direct: SVI Vlanif30 IP change
- Indirect: OSPF LSA update in Area 0
- Potential: BGP route-map referencing prefix-list X
- Risk: Medium (core area involved)
这类分析,是脚本永远写不完的。
9、Dry Run 与配置 Diff:工程系统不接受"盲推"
在网络 CI 中,没有 Dry Run 的自动化,等同于手工操作。
9.1 配置渲染必须是"可重复"的
渲染不是为了"生成配置",而是为了:
- 对比当前状态
- 计算变更范围
示例(简化):
render_config --device sw-core-01 --mode dry-run
输出必须是:
- 完整配置
- 有序
- 可 Diff
9.2 AI 对 Diff 的第二个关键价值:语义解释
普通 Diff:
- network 10.10.20.0 0.0.0.255 area 0
- network 10.10.30.0 0.0.0.255 area 0
AI Diff 解释:
"OSPF Area 0 中移除 10.10.20.0/24,引入 10.10.30.0/24,对核心 LSDB 有影响,预计 1 次 SPF 计算。"
这一步,极大降低了审批与复核成本。
10、风险评分:AI 在网络 CI 中最不可替代的位置
网络工程中,最难自动化的不是"怎么改",而是:
值不值得现在改
10.1 风险不是一个布尔值,而是一个区间
风险评分至少应综合:
- 变更对象重要性
- 涉及协议层级
- 历史失败概率
- 时间窗口(高峰 / 低峰)
10.2 一个可落地的风险评分模型(示意)
risk_factors:
protocol_weight:
ospf: 3
bgp: 5
area_weight:
core: 5
access: 1
time_weight:
peak: 3
offpeak: 1
AI 的作用在于:
- 动态调整权重
- 基于历史结果修正模型
最终输出一个连续值,而不是"高/中/低"的拍脑袋判断。
11、自动回滚不是"反向执行",而是"状态回溯"
这是实验脚本与工程系统的又一条分水岭。
11.1 为什么网络回滚不能简单反向执行命令
原因只有一个:
网络状态是非对称的
例如:
- 邻居关系
- 路由收敛顺序
- 会话状态
11.2 正确的回滚方式:状态快照 + 意图恢复
在 CI 系统中,每一次成功发布,都必须生成:
snapshot:
intent_hash: abc123
model_hash: def456
timestamp: 2026-01-01T10:00:00
回滚时,不是执行"undo 命令",而是:
恢复到某一个已知可运行的状态版本
AI 在这里的角色是:
- 判断是否"值得回滚"
- 选择最安全的回滚点
12、一个完整案例:把 CCIE 实验级 OSPF 设计,迁移到企业 CI
这一节,我用一个真实可复用的案例收尾。
12.1 实验背景(简化)
- 三层交换核心
- 多 VLAN
- OSPF Area 0
- 与防火墙策略联动
12.2 企业级转化结果
最终在企业中落地为:
- 1 套 Intent 文件
- 3 个模型定义
- 2 套厂商模板
- 1 条 CI 流水线
- AI 驱动的风险评估与回滚决策
工程师不再"敲配置",而是:
提交变更 → 理解影响 → 决策是否上线
13、Network-as-Code 与云网络的真正交汇点:不是 API,而是"状态对齐"
很多团队在把 Network-as-Code 推向云环境时,会产生一个错觉:
"云网络本来就是 API 驱动的,天然适合 CI。"
这是一个表象成立、工程结论错误的判断。
13.1 云 API 解决的是"可调用性",不是"可控性"
云厂商已经帮你解决了三件事:
- 资源可以被创建
- 状态可以被查询
- 操作可以被自动化
但它没有解决:
- 多资源之间的状态一致性
- 网络变更对业务路径的影响
- 混合云 / 混合网络的演进问题
换句话说:云 API 在提升了'执行效率'的同时,也无形中按下了'故障扩散'的加速键。
13.2 一个典型的云网络失控场景(真实工程问题)
假设你在 CI 中做了一个看似合理的变更:
- 扩展一个子网 CIDR
- 调整一条安全组规则
- 新增一条路由指向 NAT Gateway
从 API 角度看:
- 三个操作都成功
- 没有报错
- Terraform / SDK 状态一致
但从网络状态角度看,可能已经出现:
- 路由优先级变化导致南北向流量绕路
- 防火墙会话被重建
- 跨 AZ 流量计费异常
这类问题,完全无法通过 API 成功与否判断。
13.3 Network-as-Code 在云环境中的真正角色
在云里,Network-as-Code 要做的不是"替代 Terraform",而是:
作为云网络之上的"状态裁判层"
它关注的是:
- 期望状态是否合理
- 实际状态是否偏移
- 状态变化是否符合工程约束
AI 在这里的角色,是把分散在云 API、监控指标、流量数据里的信号,统一解释成"网络状态语言"。
14、Network-as-Code 与 AIOps 的分界线:一个管"变",一个管"稳"
很多人会问一个问题:
Network-as-Code 和 AIOps 到底是什么关系?
这是一个必须讲清楚的问题。
14.1 一个简单但严格的划分原则
在成熟体系中,两者的边界非常清晰:
- Network-as-Code
- 负责:设计、变更、演进
- 输入:Intent / Model
- 输出:期望状态
- AIOps
- 负责:运行、监控、恢复
- 输入:真实运行状态
- 输出:异常信号与反馈
它们通过状态闭环连接,而不是功能叠加。
14.2 状态闭环是如何形成的
在企业级系统中,完整闭环应该是:
Intent →
Model →
CI 发布 →
运行态 →
Telemetry →
异常识别 →
反馈到 Intent / Model
AI 在这里的关键作用不是"替你运维",而是:
- 判断异常是否与最近变更有关
- 量化某类变更的长期风险
- 反向修正模型假设
14.3 一个真实可用的反馈示例
假设系统在过去 3 个月内发现:
- 所有涉及 Core Area OSPF 的变更
- 在高峰期触发异常的概率显著更高
AI 可以自动给出反馈建议:
"建议将 Core Area 路由变更默认窗口限制在非高峰时段,或提高审批阈值。"
这条建议不会直接改配置,而是:
- 修正 CI 风险模型
- 调整组织的工程策略
这才是 AIOps 与 Network-as-Code 的正确协作方式。
15、为什么说:Network-as-Code 最终会"改造组织",而不是只改造网络
这是很多技术文章刻意回避,但在真实企业中绕不开的一点。
15.1 当网络变成代码,权责边界会被迫重写
一旦网络变更进入 CI 流水线,就意味着:
- 终结了'口头变更'与'手工盲操'的灰色地带。
- 每一次变更都有责任主体
- 所有风险都有可追溯来源
这会直接影响:
- 网络团队的工作方式
- 变更审批流程
- 事故归因模式
15.2 Network-as-Code 对工程师能力模型的真实要求
它并不是"降低门槛",而是重新分配能力重心:
- 协议理解仍然重要,但不再是全部
- 系统思维、抽象能力、风险意识变成核心
- 能否把"经验"转化为"模型",决定上限
HCIE / CCIE 的价值,在这里不是"会不会敲命令",而是:
是否理解网络系统在复杂约束下的行为模式。
15.3 为什么这条路几乎不可逆
一旦一个组织真正跑通了 Network-as-Code:
- 手工操作会被视为风险源
- 无模型变更会被视为技术债
- 无法解释的状态会被优先清理
这不是文化问题,而是工程效率的自然选择。
16、回到最初的问题:实验脚本的"终点"在哪里?
现在,我们可以回到文章一开始提出的那个断层问题。
16.1 HCIE / CCIE 实验能力并没有"过时"
它们解决的是:
- 协议理解
- 极端场景推理
- 网络行为边界
但它们的终点不是生产环境,而是:
成为 Network-as-Code 体系中的"模型与约束来源"
16.2 真正成熟的工程状态
在成熟体系中,你会看到这样的画面:
- 网络工程师很少直接登录设备
- 大多数时间在审视 Intent、模型和 Diff
- 讨论的不是"命令对不对",而是"这个状态值不值得上线"
这不是"失去技术感",而是技术进入了更高抽象层级。
写在最后(不计入编号)
Network-as-Code 并不是一个工具栈,也不是一套模板规范。
它是一种工程世界观的迁移:
- 从"我现在能不能把它配通"
- 迁移到"这个系统五年后还能不能被安全演进"
HCIE / CCIE 给了你理解网络的底层能力;
Network-as-Code,决定这些能力是否能在真实世界里长期生效。
结语:
Network-as-Code 的终点,并不是要把每个网络工程师都变成软件开发,而是要借用软件工程的思想,给脆弱的网络架构穿上"铠甲"。
正如我们在文中看到的,AI 并不是要取代那些懂得 LSA 类型或 BGP 选路原则的专家,而是要将这些专家的"大脑直觉"转化为"系统规则"。 当你的 HCIE/CCIE 知识不再只存在于敲入的命令中,而是沉淀为 Model 层的一条约束、CI 流水线中的一个评分权重时,你才真正完成了从"网络操作员"到"网络架构师"的华丽转身。
未来的网络不再是一个被动等待敲击的黑盒,而是一个透明、可测、自动对齐意图的数字基础设施。
路虽远,行则将至;事虽难,做则必成。 愿每一位在 CLI 命令行中奋斗过的工程师,都能在这波"状态建模"的浪潮中,找到属于自己的进化之路。
(文:陈涉川)
2026年01月01日