目录
[步骤 1:启动 OpenDaylight 并安装 Karaf 插件](#步骤 1:启动 OpenDaylight 并安装 Karaf 插件)
[步骤 2:编写 Mininet 自定义拓扑脚本(topo.py)](#步骤 2:编写 Mininet 自定义拓扑脚本(topo.py))
[步骤 3:运行拓扑、验证网络基础连通性](#步骤 3:运行拓扑、验证网络基础连通性)
[步骤 4:负载均衡控制脚本执行(load_balance.py)](#步骤 4:负载均衡控制脚本执行(load_balance.py))
[步骤 5:流量测试验证负载均衡](#步骤 5:流量测试验证负载均衡)
[补充:load_balance.py 核心逻辑参考(简易轮询负载均衡框架)](#补充:load_balance.py 核心逻辑参考(简易轮询负载均衡框架))
一、实验基本信息
- 实验名称:SDN 基本应用实践 ------ 基于 OpenDaylight 控制器实现负载均衡
- 实验环境
- 控制器:OpenDaylight(ODL)
- 仿真工具:Mininet、Open vSwitch(OVS)
- 编程语言:Python
- 通信协议:OpenFlow13
- 实验目的
- 掌握 OpenDaylight 启动、Karaf 控制台插件安装流程;
- 学会使用 Mininet 自定义拓扑,远程连接 ODL 控制器;
- 验证交换机与 ODL 控制器的 OpenFlow 通道连通性;
- 基于 ODL RESTCONF 接口下发流表,实现多主机负载均衡转发;
- 理解 SDN 集中式控制、流表下发、流量调度的核心原理。
二、实验原理
- SDN 架构 SDN 将控制平面与数据平面解耦,OpenDaylight 作为集中式控制器,通过 OpenFlow 协议管控底层 OVS 交换机;上层可通过 RESTCONF API 向控制器下发流表规则,自定义流量转发逻辑。
- 负载均衡思路 本实验拓扑:1 台交换机
s1连接 4 台主机h1(10.0.0.1)、h2(10.0.0.2)、h3(10.0.0.3)、h4(10.0.0.4); 以h1作为客户端,h2/h3/h4作为后端业务服务器;控制器通过周期性 / 分片下发差异化流表,将h1的访问流量轮流调度至三台后端主机,实现简易轮询负载均衡。 - 关键组件
- OVSDB 插件:ODL 对接 Open vSwitch 的南向组件;
- OpenFlow 插件:实现 OpenFlow13 协议交互;
- RESTCONF:北向接口,Python 通过 HTTP 调用下发流表;
- DLUX:ODL 可视化 Web 管理界面。
三、实验步骤
步骤 1:启动 OpenDaylight 并安装 Karaf 插件
- 进入 ODL 根目录,执行启动命令


bash
运行
./karaf
- 在 Karaf 控制台依次安装实验所需插件 (1)安装 OVSDB 全套组件

plaintext
feature:install odl-ovsdb-all
feature:install odl-ovsdb-southbound-api odl-ovsdb-southbound-impl odl-ovsdb-southbound-impl-rest odl-ovsdb-southbound-impl-ui odl-openflowplugin-adsal-compatibility-all
(2)安装 RESTCONF 北向接口
plaintext

feature:install odl-restconf
(3)安装 L2 交换与 OpenFlow 核心功能
plaintext

feature:install odl-l2switch-switch
feature:install odl-openflowplugin-all
(4)安装 Web 可视化 DLUX 与 MD-SAL 数据存储层
plaintext

feature:install odl-dlux-all
feature:install odl-mdsal-all
- 等待所有插件安装完成,无报错即控制器就绪,ODL 默认监听 OpenFlow 端口
6633。
步骤 2:编写 Mininet 自定义拓扑脚本(topo.py)
实现单交换机连接 4 台主机,远程对接本机 ODL 控制器(127.0.0.1:6633),拓扑代码:
python

echo -e 'from mininet.net import Mininet\nfrom mininet.cli import CLI\nfrom mininet.node import RemoteController, OVSKernelSwitch\nimport os\n\nif name == '\''main'\'':\n net = Mininet(controller=RemoteController, switch=OVSKernelSwitch)\n\n odl_controller = net.addController('\''ODL_controller'\'',\n controller=RemoteController,\n ip='\''127.0.0.1'\'',\n port=6633)\n\n s1 = net.addSwitch('\''s1'\'')\n\n h1 = net.addHost('\''h1'\'', mac="00:00:00:00:00:01")\n h2 = net.addHost('\''h2'\'', mac="00:00:00:00:02")\n h3 = net.addHost('\''h3'\'', mac="00:00:00:00:03")\n h4 = net.addHost('\''h4'\'', mac="00:00:00:00:04")\n\n net.addLink(s1, h1)\n net.addLink(s1, h2)\n net.addLink(s1, h3)\n net.addLink(s1, h4)\n\n h1.setIP('\''10.0.0.1'\'', 24)\n h2.setIP('\''10.0.0.2'\'', 24)\n h3.setIP('\''10.0.0.3'\'', 24)\n h4.setIP('\''10.0.0.4'\'', 24)\n\n net.start()\n CLI(net)\n net.stop()' > topo.py
运行
from mininet.net import Mininet
from mininet.cli import CLI
from mininet.node import RemoteController, OVSKernelSwitch
import os
if __name__ == '__main__':
# 初始化网络,指定远程控制器、OVS交换机、OpenFlow13
net = Mininet(controller=RemoteController, switch=OVSKernelSwitch)
# 添加ODL远程控制器
odl_controller = net.addController('ODL_controller',
controller=RemoteController,
ip='127.0.0.1',
port=6633)
# 添加交换机s1
s1 = net.addSwitch('s1')
# 4台主机,指定MAC地址
h1 = net.addHost('h1', mac="00:00:00:00:00:01")
h2 = net.addHost('h2', mac="00:00:00:00:00:02")
h3 = net.addHost('h3', mac="00:00:00:00:00:03")
h4 = net.addHost('h4', mac="00:00:00:00:00:04")
# 建立交换机与主机链路
net.addLink(s1, h1)
net.addLink(s1, h2)
net.addLink(s1, h3)
net.addLink(s1, h4)
# 配置主机IP网段10.0.0.0/24
h1.setIP('10.0.0.1', 24)
h2.setIP('10.0.0.2', 24)
h3.setIP('10.0.0.3', 24)
h4.setIP('10.0.0.4', 24)
# 启动网络
net.start()
# 进入Mininet交互CLI
CLI(net)
# 退出后销毁网络
net.stop()
步骤 3:运行拓扑、验证网络基础连通性
- 执行拓扑脚本
bash

运行
python topo.py
- Mininet 内基础验证命令

mininet
# 查看所有节点
nodes
# 查看链路状态
links
# 查看h1网卡IP/MAC
h1 ifconfig h1-eth0
执行结果:
- 节点:
ODL_controller h1 h2 h3 h4 s1 - 四条链路状态均为
OK OK; - h1-eth0 IP 为
10.0.0.1,MAC 与脚本配置一致。
- 验证 OVS 交换机与 ODL 控制器连接状态
mininet

sh ovs-vsctl show
输出关键信息:
plaintext
Bridge s1
Controller "tcp:127.0.0.1:6633"
is_connected: true
证明交换机s1已成功和 ODL 控制器建立 OpenFlow 长连接,通道正常。
步骤 4:负载均衡控制脚本执行(load_balance.py)
- 脚本逻辑:调用 ODL RESTCONF 接口,循环下发流表,将 h1 流量轮询导向 h2、h3、h4 三台后端服务器;
- 运行负载均衡程序:
bash

运行
python load_balance.py
- 程序输出日志:

plaintext
add flow success!
backend server is:host2
add flow success!
backend server is:host2
...
add flow success!
backend server is:host3
...
add flow success!
backend server is:host4
每一条add flow success!代表一条负载均衡转发流表成功写入 ODL 控制器,并同步下发至 OVS 交换机s1。
步骤 5:流量测试验证负载均衡
- 在 Mininet 中,使用
h1持续 ping / 访问后端地址; - 通过
sh ovs-ofctl dump-flows s1查看交换机流表,可见多条差异化转发规则; - 观测数据包走向:h1 的请求流量交替转发至 h2、h3、h4,实现轮询负载分担。
四、实验现象与结果分析
- ODL 插件安装结果 Karaf 控制台所有
feature:install命令无报错,feature:list可查看插件状态为active,控制器北向 RESTCONF、南向 OpenFlow/OVSDB 服务正常启用。 - Mininet 拓扑验证结果
- 4 台主机、1 台交换机、1 台远程控制器全部正常创建;
- 所有链路双向通信状态 OK,主机 IP、MAC 与代码预设一致;
ovs-vsctl show输出is_connected: true,交换机与控制器握手成功,控制通道建立完成。
- 负载均衡脚本执行结果 程序循环输出
add flow success!,说明 RESTCONF 接口调用正常,ODL 接收流表并下发至数据平面 OVS;日志交替打印host2/host3/host4,证明控制器按照轮询策略分配后端服务器。 - 功能验证 下发流表后,客户端 h1 的流量被调度分发至三台后端主机,单台后端不会承载全部访问压力,达成简易负载均衡效果;可通过抓包(tcpdump)或流表统计(ovs-ofctl dump-flows)观测各后端数据包计数均衡增长。
五、关键问题与排错
- 问题 1:ovs-vsctl show 显示 is_connected: false
- 原因:ODL 未正常启动、OpenFlow 插件未安装、端口 6633 被占用;
- 解决:重启 ODL 重装 openflowplugin 插件,关闭占用 6633 端口程序,确认控制器 IP / 端口填写正确。
- 问题 2:load_balance.py 执行报 HTTP 404/401
- 原因:odl-restconf 插件未安装、RESTCONF 地址 / 认证错误;
- 解决:重装
odl-restconf,核对 ODL 默认账号 admin/admin,确认 API 资源路径无误。
- 问题 3:拓扑脚本 h4 IP 配置错误
- 原图代码笔误
h3.setIP('10.0.0.4'),会导致 h3、h4IP 冲突; - 解决:修正为
h4.setIP('10.0.0.4')。
- 原图代码笔误
- 问题 4:流表下发成功但主机不通
- 原因:流表优先级、匹配域、出端口动作配置错误;
- 解决:检查 RESTCONF 的 JSON 载荷,确认匹配源 IP、目的 IP、转发输出端口与拓扑端口一一对应。
六、实验总结
- 本次实验完成 OpenDaylight 控制器部署、全套功能插件安装,掌握 Karaf 控制台基础操作;
- 实现 Mininet 自定义单交换机多主机拓扑,完成 OVS 交换机与 ODL 远程控制器的 OpenFlow 对接;
- 基于 ODL 北向 RESTCONF 接口开发负载均衡控制脚本,能够动态下发流表实现流量轮询调度;
- 直观验证 SDN 集中控制优势:无需修改交换机硬件配置,仅通过控制器软件下发规则即可灵活改变流量转发策略,快速实现负载均衡、访问控制等业务逻辑;
- 拓展思考:本次为简易静态轮询负载均衡,工业场景可扩展为基于服务器 CPU、带宽、连接数的动态权重负载均衡,通过控制器实时采集后端主机状态动态调整流表。
七、实验附图说明
- 附图 1:ODL Karaf 控制台插件安装指令清单;
- 附图 2:Mininet 拓扑 Python 完整源码;
- 附图 3:Mininet nodes/links/ifconfig 拓扑验证输出;
- 附图 4:ovs-vsctl show 控制器连接状态截图;
- 附图 5:负载均衡脚本运行流表下发成功日志。