简介:面向SDN初学者与技术爱好者,这份基于Java的开源控制器Floodlight安装部署资料,重点解决“如何在Linux环境中快速搭建控制器”这一实际问题。内容从概述、安装前准备切入,特别提醒非专业人士建议在虚拟机上操作,并以Ubuntu为例展开,适合希望系统掌握Floodlight部署流程、后续进行网络实验或二次开发的人群。包体为64.72MB的zip压缩包,以安装说明、环境配置文档、部署指南等文字材料为主,便于按步骤查阅和对照实践。目前已有554人学习下载,实用性得到初步验证。通过这份资料,读者可以少走弯路,了解SDN控制器安装的常见前提条件、虚拟机环境选择方法,并参照文档完成从准备到启动的完整部署,为深入理解SDN架构打下可操作的基础。
1. Floodlight:不只是“又一个控制器”,而是一套能改源码的SDN实验台
Floodlight 是运行在普通服务器上的 Java 版 OpenFlow 控制器。它把交换机的转发表抽象成可编程的下发接口,让一台 Linux 主机变成整个网络的“决策大脑”——拓扑由它发现,路径由它计算,流量由它通过流表规则放行或丢弃。对于做网络实验、写课程设计、验证某个转发策略的从业者来说,它的价值不在功能华丽,而在结构简单:总共几十个模块,启动十分钟就能看到真实交换机上报的 packet-in,改一个 Java 文件重启即可观察行为变化。对比动辄体积庞大的商业控制器,Floodlight 更适合场景是“快速验证想法”。同时,它对外提供一套相对完整的 REST API,学清楚模块与接口之间的对应关系后,很多复杂的二层策略、链路调度、流量观测需求,都能在几行命令内完成原型验证。
我见过不少刚接触 SDN 的开发者问:既然有各种可视化平台,为什么还要用这样一个老牌控制器?原因是可视化工具把底层细节封装成黑匣子,你看到的只是配置界面和结果曲线,而 Floodlight 的好处是所有转发动机都能追溯到具体模块代码,适合需要论文结果或自定义转发的人。本文围绕一套可复现的流程展开:从拉取代码、启动控制器,到通过 REST API 查看拓扑和下发流表,再到用链路切换完成一次路径调度实验,最后给出我踩过的坑。
2. Floodlight 的核心架构与模块加载机制
2.1 模块化设计:为什么它比“单体控制器”更适合改源码
Floodlight 的每个功能点都对应一个模块,例如拓扑管理、设备追踪、链路发现、防火墙、转发逻辑,它们之间通过事件和接口互相调用。这种设计和单片式程序的最大区别是:你可以只替换其中一段逻辑,完全不影响其他功能。最常见的做法是把 forwarding 模块替换成自定义模块,用于研究某种二层转发策略;或者替换 topology 模块里的路径计算函数,实现特定约束的路由算法。
它的启动入口是一个模块加载器,启动时读取配置文件里列出的模块清单,按依赖关系依次实例化。模块间调用方式分为两类:同步直接调用接口,异步监听事件。例如链路发现模块发出 LLDP 后,收到回复会触发一个拓扑事件,监听者马上知道链路状态变化。理解这个机制对后续排查问题很关键:某个 REST API 没反应,不一定是接口写错,可能是上游模块没有把状态更新发给下游。
我用过几个控制器之后,发现 Floodlight 的代码风格是最适合做实验的——模块之间耦合度不高,注释丰富,出错时堆栈信息能够定位到具体模块和行号。相比之下,一些商业控制器把核心逻辑封装在闭源代码里,遇到底层问题只能靠猜测。
2.2 读取配置文件:模块加载顺序与参数生效条件
Floodlight 启动时默认读取src/main/resources/floodlightdefault.properties,这个文件决定了哪些模块被加载、哪些服务被暴露。开发者经常忽略的一点是:文件里每个模块都有默认配置,只有修改后重启才生效。如果你改动某个模块参数却没看到预期效果,大概率是配置文件根本没被加载或被其他配置覆盖。
常见配置项包括:
floodlight.modules:按顺序列出需要加载的模块类,顺序决定启动优先级org.projectfloodlight.core.restserver:REST API 服务参数,如监听端口(默认 8080)org.projectfloodlight.core.internal.FloodlightProvider:控制器和交换机之间的通信参数,如 OpenFlow 监听端口(默认 6633)net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher:静态流表下发模块,常配合 REST API 使用
下面是一段最小配置示例(节选):
floodlight.modules = \ net.floodlightcontroller.core.internal.FloodlightProvider, \ net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher, \ net.floodlightcontroller.restserver.RestApiServer, \ net.floodlightcontroller.topology.TopologyManager, \ net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl, \ net.floodlightcontroller.linkdiscovery.internal.LinkDiscoveryManager, \ net.floodlightcontroller.forwarding.Forwarding org.projectfloodlight.core.restserver.restport=8080 org.projectfloodlight.core.FloodlightProvider.openflowport=6633这里加载顺序有讲究:FloodlightProvider 必须先加载,因为它负责建立 OpenFlow 连接;RestApiServer 也要靠前,否则后续转发模块所提供的一些端口映射服务可能注册不上。TopologyManager 和 LinkDiscoveryManager 需要配合使用:前者负责维护全网拓扑视图,后者负责发送 LLDP 报文和接收回复。转发模块依赖拓扑模块,如果顺序颠倒,启动日志会报依赖缺失错误。
参数不是随便写的,REST 端口如果和本机其他应用冲突,会直接启动失败;OpenFlow 端口 6633 是业界的默认约定,但如果你在实验环境里跑多个控制器实例,必须显式改成不同端口,否则后启动的实例无法绑定端口。
2.3 REST API 体系:从哪个接口能看到什么信息
Floodlight 面向开发者最重要的接口是 REST API,默认监听 8080 端口。想查看当前连接的交换机列表,请求/wm/core/controller/switches/json;想看拓扑链路,请求/wm/topology/links/json;想下发静态流表,使用/wm/staticflowentrypusher/json。它和很多平台的区别在于:Floodlight 交换机的编号不是用户指定的,而是控制器根据交换机上报的 dpid(Datapath ID)自动生成的,dpid 通常是交换机的 MAC 地址或网桥 ID。
这里有个小技巧:你在查看拓扑前,最好先看看设备管理器接口里的主机表。因为 Floodlight 的拓扑视图只表达交换机之间的链路,主机层面需要单独查询。很多初学者在这两个接口之间切换时容易搞混——设备表包含连接主机的 MAC、IP、接入端口,而拓扑表只包含交换机间链路。
2.4 从“控制器起点”到“网络视图”:一套完整的最小信息流
Floodlight 与交换机的信息流大致是:控制器启动后,交换机主动连接控制器并上报自身能力和连接端口;控制器随后向所有交换机发送 LLDP 探测报文;交换机收到后上报给控制器,控制器借此发现链路,生成拓扑。此后每收到一个未知目的地的数据报文,交换机都会通过 packet-in 消息上报给控制器,控制器查找或计算路径然后下发给交换机 flow-mod 消息。
这套机制决定了 Floodlight 的控制延时比纯静态配置高——每一个新流量首包都会经过控制器,但后续报文按流表转发,不会再经过控制器。所以实验中的首包延迟普遍在几十毫秒,后续延迟会降到交换机本地转发级别。理解这个区别非常重要:做性能测试时,不能拿首包当作最终转发性能指标。
3. 从零跑通 Floodlight 的最小实验环境与链路查看
3.1 本地环境准备与启动控制器
Floodlight 是 Java 项目,最低要求是 JDK 8,较早版本对 JDK 11 以上存在兼容问题。用下来的经验是:如果你用 JDK 11 跑老版本代码,启动会报非法反射访问错误,解决办法要么换 JDK 8,要么改编译参数。为了专注实验本身,我建议直接安装 JDK 8。
环境准备和启动命令:
# 安装 JDK 8(以 Debian/Ubuntu 为例) sudo apt-get update sudo apt-get install openjdk-8-jdk # 获取项目源码后进入根目录 git clone <项目源码地址> cd floodlight # 编译(首次编译会下载依赖,需要几分钟) ./gradlew build -x test # 启动控制器 ./floodlight.sh启动成功后,日志末尾会出现Controller startup complete之类的提示,说明 OpenFlow 服务已经就绪。很多人第一次启动时看到大量 INFO 日志以为出错了,其实大部分是模块注册信息,只要没有ERROR和异常堆栈,就是正常启动。
参数说明:./gradlew build -x test里的-x test作用是跳过测试阶段,因为完整跑一遍测试会持续很久,对本地实验没有必要。如果你改动了 Java 源码,需要重新编译后再启动,热替换在这个项目里不可靠,必须重启控制器让新逻辑生效。
3.2 用 Mininet 模拟一个真实拓扑并观察控制器视角
Floodlight 单独运行只是一个空的控制器,需要配合流量源使用。最常见的是 Mininet,它能在一台 Linux 机器上创建带 OpenFlow 能力的虚拟交换机、虚拟主机和链路。下面的命令创建包含三台交换机、每台交换机下挂两台主机的环形拓扑:
sudo mn --controller=remote,ip=127.0.0.1,port=6633 --topo linear,3 --switch=ovsk,protocols=OpenFlow13连接后,控制器日志会立刻出现交换机加入的事件,包括 dpid 和端口信息。此时用 curl 查看拓扑:
curl http://127.0.0.1:8080/wm/topology/links/json返回结果是 JSON 格式,包含每一条链路的源交换机 dpid、源端口、目标交换机 dpid、目标端口和链路状态。看到有链路数据说明 LLDP 发现机制正常工作;如果这里为空,问题大多出在交换机没有正确配置控制器地址,或者 Mininet 里 ovs 协议版本不匹配。
补充一个关键点:Mininet 默认给 OVS 交换机配置的协议版本可能和 Floodlight 不匹配。Floodlight 老版本默认只支持 OpenFlow 1.0,但 Mininet 新版本往往默认开启 OpenFlow13。如果不加指定,你可能会看到控制器日志里不断出现错误握手信息,解决方式是启动 Mininet 时明确指定protocols=OpenFlow13,并且使用较新版本的 Floodlight——它在启动时也能同时协商多种协议版本,但保险起见仍建议显式指定。
3.3 从 REST API 获取交换机与主机信息:字段含义与实际用途
有拓扑之后,再检查交换机列表和主机表:
# 查看所有已连接的交换机 curl http://127.0.0.1:8080/wm/core/controller/switches/json # 查看控制器发现的主机设备 curl http://127.0.0.1:8080/wm/device/返回的交换机信息里有一些字段值得注意:
dpid:交换机唯一标识,后续所有流表下发都要靠它定位目标交换机inetAddress:控制器和交换机之间的管理地址,通常不参与数据转发connectedSince:连接建立时间,排错时用来判断交换机是否反复掉线capabilities:交换机支持的能力标志,例如是否支持流表统计
主机表里包含主机的 MAC、IP、接入交换机 dpid、接入端口号,这些信息用来写转发规则。比如你想让某个主机的流量只能从特定端口出去,就必须从主机表里查出接入交换机和端口号。
3.4 验证转发功能:连通性测试与流表观察
拓扑和主机都正常后,先不做任何自定义规则,直接在 Mininet 里执行pingall,利用 Floodlight 自带的 forwarding 模块测试各主机连通性。这个过程实际上是 controller 收到 packet-in、计算路径、逐交换机下发流表的过程。连通信后,我们可以在交换机上查看流表内容:
# 在 Mininet 里进入某台交换机查看流表 sudo ovs-ofctl dump-flows s1正常会看到若干条由控制器下发的流表项,匹配字段包括 MAC 地址和入端口,动作字段则是出端口。若所有主机能连通,说明控制器的自动转发逻辑工作正常;不能连通,则需要检查交换机是否真的连上了控制器、拓扑模块是否生成了完整路径。
这个简单实验的价值不在于证明“能通”,而是建立了一个可对照的基准。后续你写自定义模块或下发静态规则时,需要反复对比:默认逻辑能通,改动后不通,那么问题大概率在改动部分;默认逻辑就不通,则需要检查环境和配置。
4. 一次完整的路径调度实验:静态流表的下发、验证与召回
4.1 实验场景与目标:让流量按你指定的路径走
默认的 Forwarding 模块按最短路径转发,但很多真实场景需要主动控制流量路径——比如链路 A 负载高时把流量拨到链路 B。Floodlight 最常见实现方式就是使用静态流表入口模块。以下实验场景是:三台交换机连成线形(s1-s2-s3),主机 h1 在 s1 下,主机 h2 在 s3 下。默认路径走 s1-s2-s3。现在下发一条静态路由,让 h1 的某些流量避开 s2 转而走 s1-s3 的直连链路。
需要强调的前提:实验拓扑必须存在 s1 与 s3 之间的直连链路,否则这不是“绕路调度”,而是错误路由。我们用--topo linear,3默认构建的拓扑不满足条件,需要改为自定义拓扑。这里给出一个简化的做法:启动一个环形拓扑,同样用 Mininet 的--topo linear,3再加上一条额外链路,或者直接编写 Python 脚本来定义。我这里用了简单的 ring 拓扑,也就是交换机两两之间有边。
sudo mn --controller=remote,ip=127.0.0.1,port=6633 --topo=ring,3 --switch=ovsk,protocols=OpenFlow13这个拓扑包含 s1-s2、s2-s3、s1-s3 三条链路。默认最短路径 s1-s2-s3,我们的目标是让 h1 到 h2 的流量改为走 s1-s3 直连路径。
4.2 用 REST API 下发静态流表:规则结构逐字段说明
需要先分别查清楚两台交换机的端口信息。在 Mininet 里直接查看但要注意,Mininet 内看到的端口名和控制器侧看到的端口号是同一个编号。通常物理端口 connetion 对应的 OpenFlow 端口号就是 1、2、3 这些整数。注意,Loopback 端口 65534 要避免误用。
我们的策略分两段下发:
第一段:在 s1 上,把从 h1 接入端口进来的、目的 MAC 为 h2 的报文,从连接 s3 的端口转发出去。
curl -X POST -H 'Content-Type: application/json' \ http://127.0.0.1:8080/wm/staticflowentrypusher/json \ -d '{ "switch": "00:00:00:00:00:00:00:01", "name": "s1-to-s3", "cookie": "1", "priority": "40000", "eth_type": "0x0800", "eth_dst": "00:00:00:00:00:03", "in_port": "1", "active": "true", "actions": "output=3" }'第二段:在 s3 上,把从连接 s1 的端口进来的报文,从连接 h2 的端口转发出去。相当于流量的后半段路径。
curl -X POST -H 'Content-Type: application/json' \ http://127.0.0.1:8080/wm/staticflowentrypusher/json \ -d '{ "switch": "00:00:00:00:00:00:00:03", "name": "s3-to-h2", "cookie": "1", "priority": "40000", "eth_type": "0x0800", "eth_dst": "00:00:00:00:00:03", "in_port": "3", "active": "true", "actions": "output=2" }'字段说明:
switch:目标交换机 dpid,必须和交换机实际上报的 dpid 完全一致,冒号分隔,不能省略前导零name:流表项名称,Floodlight 用它做唯一标识,删除时也是用这个名字priority:流表优先级,控制器默认转发的规则优先级通常场是 100 以下,这里设置为 40000 就是为了覆盖默认转发规则eth_dst:目的 MAC,这个字段实际匹配的是 h2 的 MAC 地址。可以使用00:00:00:00:00:03作为仿真的 MAC 地址,但如果你在 Mininet 里实际生成的 MAC 不同,需要替换为实际值in_port:限制只匹配从某个端口进入的报文,避免影响其他方向的流量actions:动作列表,output=3表示从 3 号端口转发
这两条规则只是做了“只匹配目的 MAC 为 h2”的策略。如果实验环境里还有其他主机,且你想要更精细地限定源主机,需要加上eth_src字段,否则所有去往 h2 的流量都会走这条路径。实际使用时,我会把eth_src和eth_dst一起写上,避免规则影响范围扩大。
4.3 验证路径是否真的切换:从交换机流表和实际连通性两个角度
下发成功后,首先用 REST API 查看是否生效:
curl http://127.0.0.1:8080/wm/staticflowentrypusher/list/all/json返回 JSON 里能看到刚才下发的两条规则。但“规则存在”不等于“规则生效”,更可靠的做法是到交换机侧查看实际的流表:
# 在 Mininet 里执行 ovs-ofctl dump-flows s1这里会看到匹配in_port=1, dl_dst=00:00:00:00:00:03的流表项动作是output:3。然后再检查 OVS 的流表统计,确认这个规则确实被报文命中。具体方法:
ovs-ofctl dump-flows s1 | grep s1-to-s3注意n_packets和n_bytes字段,如果都是 0,说明规则没有被匹配——可能是参数填错或流量路径根本没到达该交换机。
另一个验证方式是在 Mininet 里用ping测试,然后抓包看是否经过 s2:
# 在 xterm 里打开 s2 的抓包窗口,观察是否有 h1 到 h2 的 ICMP 流量 sudo tcpdump -i s2-eth1 -vvv 'icmp'如果 s2 上完全看不到相关流量,说明路径已经切换成功。这一步是最直观的“实锤”。
4.4 删除与修改:为什么删规则时要按名字而不是按内容
实验做完需要清理,用删除接口按名字删即可:
curl -X DELETE \ http://127.0.0.1:8080/wm/staticflowentrypusher/json \ -d '{"name":"s1-to-s3"}'这里有一个容易踩的坑:Floodlight 的静态流表模块在控制器重启后,不会自动恢复之前下发的规则,也不会持久化保存。如果实验结束后没删除,只要控制器不重启,规则就一直在。如果你调了一个错误的规则但没有删掉,之后每次测试都会被它干扰,而且有时日志里根本不会提示静态流表的存在。
修改规则的推荐做法是先删除旧规则再下发新规则。直接再 POST 一个同名的规则,实际行为取决于模块实现,可能是覆盖也可能是忽略,不同版本的 Floodlight 有差异。为了不给自己留隐患,保持“先删后增”的习惯最安全。
4.5 实验代价评估:用静态流表做调度,值不值
做完这一套下来,你会理解一个事实:Floodlight 的静态流表完全可以充当轻量级流量调度工具,但不适合做动态自适应策略。原因是每条规则都要手动设计、手动下发、手动回收,没有状态感知能力。如果你要做拥塞感知的自动重路由,不能单纯靠静态规则,还需要写模块监听端口统计,实时调整流表。
所以在实际方案里,静态流表适合“固定业务、固定路径”的场景,比如把某个 VLAN 的流量固定导到某条链路上;动态调度则需要设计自定义模块。值不值得用 Floodlight 取决于你的实验目的——验证策略逻辑和算法效果,它足够用;追求生产级高可用和高性能,它的定位就不合适了。
5. Floodlight 使用中的常见坑与排查思路
5.1 启动后交换机迟迟不出现
现象:Mininet 启动时指定了 remote 控制器,但控制器 REST 接口查不到任何交换机,日志里也没有连接事件。
原因:绝大多数情况是交换机根本没有连上控制器。常见原因包括:控制器 IP 写错、端口写错、Mininet 和控制器不在同一个网络命名空间,或者 OVS 默认协议版本与控制器不匹配。
解决:先从 Mininet 端确认交换机控制器配置,执行ovs-vsctl get-controller s1查看配置是否指向正确 IP 和端口。然后做本机端口测试,确认端口没有被防火墙拦截。最后查看 OVS 日志,重点看交换机是否报版本协商失败的错误。遇到过最隐蔽的情况是:Mininet 启动命令里写了--controller=remote,ip=127.0.0.1,但控制器跑在同一台机器的 Docker 容器里,网络不互通。解决办法是使用宿主机对容器映射后的 IP,或让容器和 Mininet 共享网络。
5.2 REST API 返回了 JSON,但规则实际没有生效
现象:POST 流表接口返回 200 且包含成功信息,但随后查看 OVS 流表,根本没有对应规则。
原因:最常见的是 dpid 格式不匹配。Floodlight 的 REST API 要求 dpid 使用00:00:00:00:00:00:00:01这种带冒号的完整格式,许多写脚本的人喜欢用0000000000000001,接口照样会返回 200,但规则会静默失败。
解决:先 GET/wm/core/controller/switches/json拿到实际 dpid 字符串,直接从返回结果里复制,不要手写格式。第二个常见原因是active字段没设为true,或优先级太低被默认转发规则覆盖。排查时可以临时把优先级改成 50000 再测试,还不行就删除后重新下发一种极简匹配(只匹配 in_port,不匹配 MAC)。
5.3 默认转发模块干扰静态规则
现象:静态规则已经下发,某些报文也没有命中,流量仍然沿默认路径转发。
原因:Floodlight 自带 Forwarding 模块在收到广播或多播帧时,会主动计算路径并下发临时流表。如果你只做了单通路径(比如只下发 s1 方向),回程流量还是走默认模块,那么 ping 测试就会失败。
解决:要么把回程方向也纳入静态规则,要么在实验环境里禁用默认转发模块,只保留静态流表模块。修改配置里的模块列表,移除 Forwarding 模块即可。这个方法会带来另一个问题:任何未匹配到的流量都会被丢弃,因此在做实验前要把需要转发的所有路径规则都写清楚。
5.4 链路发现正常,但 ping 总丢包
现象:拓扑和主机都发现了,但 pingall 结果里出现部分丢包,且丢包位置稳定。
原因:很多情况下是环网导致的广播风暴。Floodlight 的默认转发策略本身不处理环路,当拓扑中有冗余链路时,广播帧会因流表不完整而在交换机之间反复转发;静态规则只覆盖了部分端口,广播帧就走其他端口形成风暴。
解决:实验拓扑尽量避免环,或者在环拓扑里把所有冗余链路对应端口的泛洪行为禁掉。另一种方式是使用 Floodlight 的防火墙模块,限制特定端口之间的泛洪。这个问题比较隐蔽,因为拓扑接口看起来一切正常,只有流量在丢包时才暴露。
5.5 OpenFlow 版本协商失败
现象:控制器日志反复报与交换机的握手失败,错误信息包含version或hello字样。
原因:Floodlight 老版本默认只支持 OpenFlow 1.0,而新版本 Mininet 里的 OVS 默认开启 OpenFlow13,双方协商不到共同版本。有些版本的 OVS 甚至会尝试降级协商,但取决于 OVS 自身策略。
解决:启动 Mininet 时显式指定protocols=OpenFlow13,并确认 Floodlight 分支支持 1.3。如果你必须用旧 Floodlight,可以给 Mininet 传入--switch=ovsk,protocols=OpenFlow10。注意,如果同时跑多个控制器实例,不同控制器监听的端口必须分开,否则也会出现看似版本协商问题、实则是端口占用冲突的报错。
6. 验证路径切换是否真的成功:日志、抓包与流表三方对照法
路径切换实验完成后,需要一套可靠的验证方法,靠 ping 通不代表路径就是预期路径。我的习惯是用“日志-抓包-流表”三方对照来确认:
- 日志侧:查看控制器日志,确认静态流表下发事件与交换机连接状态没有异常报错
- 流表侧:在每台交换机上执行
ovs-ofctl dump-flows,确认规则被放在对应交换机且匹配字段正确 - 抓包侧:在预期不会经过的交换机端口上抓包,确认没有流量经过,再在预期经过的链路上抓包,确认流量确实在那里
在 Mininet 环境里,抓包可以在控制器所在主机的网卡上完成,因为有多个虚拟交换机时流量可能都经过同一个物理接口,你需要按端口或 VLAN 来区分。最简单的做法是在目标端口上开 tcpdump 或 tshark 监听:
# 在 Mininet 里进入 s2,查看它的 s2-eth2 是否出现h1到h2的ICMP sudo tcpdump -i s2-eth2 icmp -nn这里要特别强调:在 OVS 虚拟交换机里抓包,应该抓网桥的内部端口,而不是物理网卡。Mininet 的每个虚拟交换机实际上是一个 OVS 网桥,主机连接口和交换机间互联口都表现为虚拟接口,直接在对应虚拟接口上抓包即可,不要试图去物理网卡抓,那样只能看到封装后的流量,无法判断具体走了哪条链路。
还有一个更高效的验证技巧:在 ping 的时候同时观察两边流表计数变化。ovs-ofctl dump-flows输出里的n_packets会随流量增长而增加。如果规则的计数一直在涨,说明匹配成功;如果规则计数不变但 ping 正常,说明流量走了另一条规则——这时需要查看该交换机上有没有优先级更高的默认流表项在起作用。
经过这么多次实验后,我养成一个习惯:每修改一次路径策略,都会用一张小表格记录“交换机、规则名、优先级、匹配字段、动作、预期路径、验证结果”。一开始觉得多余,后来发现排查问题时这张表比日志还管用——因为控制器日志不会记录每个流表项的状态变化,而表格随时能告诉你当前环境的“实际状态”和“预期状态”的差距。
这套流程走下来,你会发现 Floodlight 其实不复杂,复杂的总是环境细节。但如果把每个模块的角色、REST API 的字段含义、交换机侧的验证手段都搞清楚,它的可掌控程度远超那些看似简单的可视化工具。希望帮到你。
本文还有配套的精品资源,点击获取