恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
SDN四平面模型详解:从数控分离到可编程网络实践
首页
资讯中心
/
SDN四平面模型详解:从数控分离到可编程网络实践
SDN四平面模型详解:从数控分离到可编程网络实践
发布时间:2026/10/9 2:58:02
简介这份文档面向网络工程师、SDN初学者及高校网络方向师生系统讲解软件定义网络的核心架构与设计思想帮助读者理解控制与转发分离这一关键理念解决传统网络设备只可配置、难以编程的痛点。资源包内含1个doc文档约444KB内容围绕SDN概述、基本架构、ONF四平面模型及核心概念展开结构完整、条理清晰。文档从SDN产生原因切入依次剖析数据平面、控制平面、应用平面与管理平面的职责划分并说明CDPI、北向接口、东西向接口等协议交互方式同时结合ForCES与4D项目梳理数控分离的历史脉络深入讲解RIB与FIB在控制与转发之间的纽带作用。目前已有449人学习适合作为课程学习、技术调研或方案设计的参考材料便于快速建立对SDN体系框架的整体认知。1. 从一台只会转发不会思考的交换机说起手里这份《SDN网络架构详解.doc》我翻了三遍第一反应是它把 ONF 那套四平面模型讲得比大多数网上拼凑的 PPT 都干净。SDN 这个词现在被用得很泛有人拿它指 OpenFlow有人拿它指白盒交换机还有人把任何带控制器的网络都叫 SDN。这份文档的价值在于它老老实实回到“控制与转发分离”这个根上把数据平面、控制平面、应用平面、管理平面四个面拆开讲再把 CDPI、NBI 两个接口的职责边界划清楚。如果你正在做网络架构选型、准备 SDN 相关课程设计或者被“网络可编程”这个概念绕得头晕这份文档能当底稿用。它不教你敲命令但它把“为什么这么设计”讲透了后面配实验环境的时候你会少走很多弯路。2. 四平面模型拆解ONF 架构里每个面到底管什么2.1 数据平面不是“网元”两个字就完了文档里写“数据平面由若干网元组成每个网元可以包含一个或多个 SDN Datapath”这句话容易被扫过去。实际落地时一个 SDN Datapath 是一个逻辑上的转发实体它没有控制能力只负责按流表干活。一个 Datapath 内部拆成三块控制数据平面接口代理、转发引擎表、处理功能。接口代理负责跟控制器通信转发引擎表就是流表本身处理功能管的是匹配之外的杂活比如计数、丢弃、上送控制器。为什么要把 Datapath 和物理设备解耦因为一台物理交换机可以虚拟出多个 Datapath分给不同的租户或不同的网络切片。你在做实验的时候OVSOpen vSwitch里一条ovs-vsctl add-br创建出来的网桥就是一个 Datapath 实例。它逻辑上代表全部或部分物理资源但你在控制器上看到的就是一个独立的转发节点。提示Datapath 是逻辑概念不要跟物理端口数量挂钩。一个 Datapath 可以只有两个端口也可以有几十个。2.2 控制平面逻辑集中物理可以分散文档里有一句很关键的话“SDN 控制器只是要求逻辑上完整因此它可以由多个控制器实例组成也可以是层级式的控制器集群。”这句话是理解 SDN 可扩展性的钥匙。很多人一听到“集中式控制”就担心单点故障其实 ONF 从来没说控制器必须是一台机器。逻辑上集中指的是全网有一个统一的网络视图物理上你可以跑三个控制器实例做集群也可以按区域分层部署。控制器内部拆成三块北向接口代理、SDN 控制逻辑、CDPI 驱动。北向接口代理负责把上层应用的请求翻译成内部事件控制逻辑是核心维护全网拓扑和状态CDPI 驱动负责跟下面的 Datapath 说“人话”——也就是 OpenFlow 之类的南向协议。我一般会这样理解控制逻辑是大脑北向代理是耳朵和嘴巴听应用要什么告诉应用网络什么样CDPI 驱动是脊髓把大脑指令传给末梢。三者缺一不可但部署时可以分开调优。2.3 应用平面和管理平面一个管“变”一个管“定”应用平面放的是 SDN 应用也就是用户真正关心的业务逻辑。比如一个流量工程应用它通过北向接口告诉控制器“我要给视频流留 40% 带宽”控制器再去算路径、下流表。应用可以调多种北向 API也可以把自己的功能再封装成更高级的北向接口给别人用。管理平面管的是静态工作配置网元、指定哪个 Datapath 归哪个控制器管、定义控制器和应用的控制范围。这些事不适合放在应用、控制、数据三个面里做因为它们是“定规矩”的不是“跑数据”的。文档里把管理平面单独拎出来这个划分很实用——你在做多租户隔离的时候管理平面就是分配“谁管哪块”的地方。2.4 CDPI 和 NBI两个接口的边界别搞混CDPI 是控制平面和数据平面之间的接口功能包括转发行为控制、设备性能查询、统计报告、事件通知。OpenFlow 是 CDPI 的一种实现但不是唯一。CDPI 的核心要求是“开放、与厂商无关”这样控制器才能管不同品牌的交换机。NBI 是应用平面和控制平面之间的接口提供抽象的网络视图让应用能直接控制网络行为。NBI 也要求开放、与厂商无关。REST API 是目前最常见的 NBI 形式但文档里没限定具体协议这是对的——NBI 可以是 REST、可以是 gRPC、也可以是消息队列。注意CDPI 和 NBI 不要搞反。CDPI 朝下管设备NBI 朝上给应用。东西向接口是控制器之间用的不在 ONF 四平面模型里但做集群时必须考虑。3. 数控分离的来龙去脉从 ForCES、4D 到 OpenFlow3.1 ForCES 和 4D 项目分离思想不是 SDN 首创文档在“数控分离历史”里提了 ForCES 和 4D 项目这两个是 SDN 之前的重要尝试。ForCES 把网络单元拆成控制单元CE和转发单元FECE 和 FE 之间用 Fp 接口通信可以经过一跳或多跳网络。一个 NE 可以有一个 CE 和几百个 FEFE 之间用 Fi 接口CE 之间用 Fr 接口。这套架构已经具备了控制与转发分离的雏形但它的目标是设备内部的功能模块化不是全网集中控制。4D 项目倡导四个平面数据平面、发现平面、决策平面、扩散平面。决策平面处理可达性、负载均衡、访问控制、安全和接口配置扩散平面负责把决策面产生的状态扩散到数据面自身不产生状态。4D 的贡献在于把网络控制逻辑从分布式系统问题里独立出来这个思路直接影响了后来的 SDN。我翻这段历史的时候有个体会SDN 不是凭空冒出来的它是 ForCES 的设备内分离和 4D 的集中决策两条线汇合的结果。理解这一点你就不会把 SDN 当成某个厂商的营销概念。3.2 RIB 和 FIB控制平面和数据平面的交接棒文档把数控分离的功能实现讲得很清楚控制平面建立 RIB路由信息库RIB 通过分布式路由协议如 OSPF跟网内其他控制平面实例保持一致。然后控制平面基于 RIB 创建 FIB转发信息库FIB 在控制和数据平面之间镜像保证转发行为与路由决策一致。数据平面根据 FIB 做高速转发。这里的关键是 FIB 作为“分界线”控制平面管到 FIB 为止数据平面从 FIB 开始。这种划分降低了 SDN 的编程灵活性——你不能直接改数据平面的转发逻辑但好处是没有暴露商用设备的高速转发实现细节设备商更容易接受。提示做 SDN 实验时流表就是 FIB 的一种实现。你在控制器上算路径、下流表本质上就是在操作 FIB。3.3 数控分离的三个优点和三个问题文档列了三个优点全局集中控制和分布高速转发、灵活可编程与性能的平衡、开放性和 IT 化。我重点说第三个——数据控制分离后交换设备制造与功能软件开发可以分离模块透明化成本降低。这个逻辑跟服务器领域的软硬件解耦是一样的x86 服务器能起来就是因为操作系统和硬件可以分开买。三个问题也很实在可扩展性集中控制节点成为瓶颈、一致性集中控制器要保证分布式节点状态一致、可用性控制平面网络延迟影响数据平面。这三个问题在今天的 SDN 部署中依然存在只是工程上有了各种缓解方案——控制器集群解决可扩展性一致性协议解决状态同步控制平面冗余解决可用性。3.4 用 OVS 和 Ryu 搭一个最小验证环境文档本身不涉及实验但你要验证数控分离最小环境就是 OVS Ryu 控制器。下面这套步骤我在 Ubuntu 20.04 上跑过多次能复现。# 安装 OVS 和 Ryu sudo apt update sudo apt install -y openvswitch-switch python3-pip pip3 install ryu # 创建两个 OVS 网桥模拟两个 Datapath sudo ovs-vsctl add-br br0 sudo ovs-vsctl add-br br1 # 把 br0 和 br1 连起来 sudo ovs-vsctl add-port br0 patch0 -- set interface patch0 typepatch options:peerpatch1 sudo ovs-vsctl add-port br1 patch1 -- set interface patch1 typepatch options:peerpatch0 # 启动 Ryu 控制器监听 6633 端口 ryu-manager ryu.app.simple_switch_13这段脚本的逻辑OVS 创建两个网桥每个网桥就是一个 Datapath。patch 端口把两个网桥连起来模拟物理链路。Ryu 启动后监听 6633等待 OVS 连接。# 另开一个终端把 br0 和 br1 的控制器指向 Ryu sudo ovs-vsctl set-controller br0 tcp:127.0.0.1:6633 sudo ovs-vsctl set-controller br1 tcp:127.0.0.1:6633 # 查看控制器连接状态 sudo ovs-vsctl showset-controller命令把网桥的控制器地址设为 Ryu 的监听地址。ovs-vsctl show里看到is_connected: true就说明 CDPI 通道通了。这时候你在 Ryu 的日志里能看到 Datapath 加入的事件控制器已经拿到了两个 Datapath 的抽象视图。参数说明tcp:127.0.0.1:6633里的 6633 是 OpenFlow 默认端口Ryu 的 simple_switch_13 用的就是这个。如果你的环境里 6633 被占用可以在 Ryu 启动时加--ofp-tcp-listen-port改端口同时 OVS 的 set-controller 也要改。这个环境跑起来之后你可以用ovs-ofctl dump-flows br0看流表。初始状态下流表是空的因为 Ryu 的 simple_switch 只在收到包的时候才下流表。你可以用ping触发一下再看流表就有了。这就是数控分离的直观体现数据平面收到包上送控制器控制器决策后下流表数据平面按流表转发。4. 抽象与可编程SDN 真正值钱的地方4.1 三种抽象转发、分布状态、配置文档把 ONF 的抽象分成三种转发抽象、分布状态抽象、配置抽象。转发抽象是把数据平面抽象成通用转发模型MAC 表、MPLS 标签表、路由表、ACL 全部统一成流表。分布状态抽象是屏蔽分布式控制的实现细节给上层应用提供全局网络视图。配置抽象是用网络编程语言表达网络行为把抽象配置映射为物理配置。这三种抽象对应三个层次的问题转发抽象解决“设备差异”分布状态抽象解决“视图碎片化”配置抽象解决“配置方式不统一”。Overlay 网络架构是另一种抽象它把基础网络设施抽象掉让租户感觉自己有独立的网络。我一般会这样跟人解释转发抽象让你不用管交换机是哪个牌子分布状态抽象让你不用管网络有多少个节点配置抽象让你不用管配置命令是 CLI 还是 NETCONF。三层抽象叠起来才是“网络可编程”的完整含义。4.2 可编程的七个层次从芯片到业务文档列了一个从下往上的可编程层次芯片可编程P4、POF、FIB 可编程OpenFlow、RIB 可编程BGP、PCEP、设备 OS 可编程、设备配置可编程CLI、NETCONF/YANG、OVSDB、控制器可编程、业务可编程GBP、NEMO。这个层次表很实用因为它告诉你SDN 可编程不是只有 OpenFlow 一条路。如果你只想改路由策略RIB 可编程就够了如果你想定义新的协议头那得走芯片可编程。选型的时候先确定你要在哪一层编程再选对应的技术栈。注意层次越低灵活性越高但硬件依赖越强。P4 很强大但需要支持 P4 的芯片。OpenFlow 相对成熟但受限于流表字段。选型时不要盲目追低层。4.3 主动网络SDN 可编程的思想前身文档在“网络可编程历史”里讲了主动网络这个容易被跳过但值得看一眼。主动网络的核心思想是允许网络节点在用户数据上执行用户所需的计算比如用户可以向路由器发送一个压缩程序要求节点收到相应包时执行压缩。DARPA 主动网络架构分三层主动应用AA、执行环境EE、节点操作系统Node OS。主动网络的封装模型有两种in-band 方式把可执行代码封装在数据分组内交换设备根据分组头执行操作。这种“数据包携带代码”的思路在当时太激进部署成本高但它提出的“网络节点可执行用户逻辑”就是今天 SDN 应用平面的雏形。我读这段的感受是SDN 的可编程不是突然出现的主动网络在二十多年前就试过只是当时没有合适的硬件和协议支撑。现在有了 OpenFlow、P4、可编程芯片主动网络的很多想法才真正落地。4.4 用 Ryu 写一个自定义北向接口验证完数控分离之后下一步是验证北向接口。Ryu 自带 REST API但默认只提供基础功能。下面这段代码给 Ryu 加一个自定义 REST 端点返回当前 Datapath 列表。# custom_api.py from ryu.app import simple_switch_13 from ryu.controller import ofp_event from ryu.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER from ryu.controller.handler import set_ev_cls from ryu.app.wsgi import ControllerBase, WSGIApplication, route from webob import Response import json simple_switch_instance_name simple_switch_api_app class SimpleSwitchAPI(ControllerBase): def __init__(self, req, link, data, **config): super(SimpleSwitchAPI, self).__init__(req, link, data, **config) self.simple_switch_app data[simple_switch_instance_name] route(datapaths, /datapaths, methods[GET]) def list_datapaths(self, req, **kwargs): # 从 simple_switch 实例里拿 datapath 列表 dps list(self.simple_switch_app.datapaths.keys()) body json.dumps({datapaths: dps}) return Response(content_typeapplication/json, textbody)这段代码的逻辑定义一个SimpleSwitchAPI类继承ControllerBase。route装饰器把/datapaths路径绑定到list_datapaths方法。方法里从simple_switch_app实例的datapaths字典里取所有 Datapath ID转成 JSON 返回。参数说明simple_switch_instance_name是注册到 WSGI 应用时的名字必须跟启动脚本里注册的名字一致。methods[GET]限定只响应 GET 请求。返回的datapaths是 Datapath ID 列表每个 ID 是一个整数对应 OVS 网桥的 datapath_id。启动脚本需要把 WSGI 和 simple_switch 一起加载ryu-manager --wsapi-port 8080 custom_api.py ryu.app.simple_switch_13启动后访问http://127.0.0.1:8080/datapaths就能看到当前连接的 Datapath 列表。这就是一个最简 NBI应用通过 REST 接口拿到网络视图不需要知道底层是 OVS 还是硬件交换机。5. 避坑与排查SDN 实验里最容易翻车的五个地方5.1 控制器连不上 Datapath现象ovs-vsctl show里is_connected一直是 falseRyu 日志里没有 Datapath 加入事件。原因最常见的是端口不对。OVS 默认用 6633但有些 Ryu 版本默认监听 6653。另一个原因是防火墙挡了本地回环的 TCP 连接。解决先确认 Ryu 监听端口ss -tlnp | grep ryu看实际端口。然后ovs-vsctl set-controller br0 tcp:127.0.0.1:6653改成一致。如果还不行sudo iptables -L看有没有规则挡了 6633/6653。5.2 流表不下发ping 不通现象控制器连上了但ovs-ofctl dump-flows br0里只有 table-miss 流表ping 不通。原因Ryu 的 simple_switch 只在收到 packet-in 后才下流表。如果 table-miss 流表的动作不是上送控制器包就被丢了。解决检查 table-miss 流表ovs-ofctl dump-flows br0 table0看 priority0 的那条。正常应该是actionsCONTROLLER:65535。如果没有手动加一条ovs-ofctl add-flow br0 priority0,actionsCONTROLLER:65535。5.3 Ryu 启动报错 “Address already in use”现象ryu-manager启动失败提示 6633 或 6653 端口被占用。原因上一次 Ryu 进程没退干净或者系统里有其他 OpenFlow 控制器在跑。解决ps aux | grep ryu找到残留进程kill -9掉。或者换端口启动ryu-manager --ofp-tcp-listen-port 6634 ryu.app.simple_switch_13同时 OVS 的 set-controller 也要改成 6634。5.4 OVS 网桥创建后端口不通现象ovs-vsctl add-br和add-port都成功了但两个网桥之间 ping 不通。原因patch 端口的两端名字写反了或者 patch 端口没 up。解决ovs-vsctl show看 patch 端口的options:peer是否指向对方。然后ip link set patch0 up和ip link set patch1 up把端口拉起来。OVS 的 patch 端口默认是 down 的必须手动 up。5.5 北向 REST API 返回 404现象Ryu 启动时加载了自定义 API 脚本但访问/datapaths返回 404。原因WSGI 应用注册时名字不对或者route的路径跟访问路径不匹配。解决检查启动命令里--wsapi-port后面的脚本顺序自定义脚本要在ryu.app.simple_switch_13之前加载。然后确认route(datapaths, /datapaths, ...)的第一个参数是路由名第二个是路径访问时用第二个参数。如果还不行在list_datapaths里加一行print(API called)看日志里有没有输出判断是路由没匹配还是方法没执行。6. 从文档到落地把四平面模型映射到真实实验拓扑这份文档最大的价值不是让你背下四个平面的定义而是给你一个分析框架。你拿到任何一个 SDN 方案都可以用这个框架去拆它的数据平面是什么控制平面是单实例还是集群应用平面提供哪些北向接口管理平面怎么划分控制范围CDPI 和 NBI 分别用什么协议我自己的习惯是每接触一个新的 SDN 项目先画一张四平面图把每个平面里的组件和接口标出来。然后问三个问题控制平面能不能水平扩展数据平面的流表容量够不够北向接口的抽象层次适不适合我的应用这三个问题答完方案能不能用基本就有数了。如果你要动手做实验我建议从 OVS Ryu 的最小环境开始先验证数控分离再加自定义北向接口最后尝试多控制器集群。每一步都对照文档里的概念看看实际实现跟理论描述的差距在哪里。比如文档说“控制器可以层级式部署”你在 Ryu 里试一下多实例就会发现状态同步是个麻烦事——这就是理论和工程的差距。提示做多控制器实验时先跑通单控制器再加第二个。两个控制器同时管一个 Datapath 会冲突需要先想好主备还是分区域。最后说一个具体技巧文档里提到的“配置抽象”在实验里最容易被忽略。你可以在 Ryu 里定义一个 YAML 文件描述网络拓扑和策略然后写个脚本把 YAML 解析成流表下发。这样你就有了一个最简的“网络编程语言”——虽然简陋但能让你体会到配置抽象到底在抽象什么。从那以后我每次搭 SDN 实验环境都强制自己先画四平面图再动手不然很容易在 OVS 命令里迷路。希望帮到你。本文还有配套的精品资源点击获取