You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置Mininet使其单次仅连集群SDN控制器并实现故障切换

实现Mininet单控制器连接+故障自动切换

核心问题分析

你之前的配置会让Mininet同时连接多个控制器,是因为通过--controller=remote,ip=xxx重复添加了多个控制器实例,导致OVS交换机同时注册到所有控制器上。要实现单次连一个、故障自动切换的需求,有三种可行方案:


方案1:基于OVS原生机制的自动切换(推荐)

利用OVS自带的控制器故障切换功能,无需修改Mininet脚本,直接配置OVS即可实现按顺序尝试连接控制器,仅当前控制器故障时才切换到下一个。

操作步骤

  1. 启动不带预设控制器的Mininet:
    mn --topo=tree,2 --controller=none
    
  2. 在Mininet CLI中,为每个交换机配置控制器列表和故障模式:
    # 给交换机s1添加控制器列表(按优先级排序,优先连接第一个)
    !ovs-vsctl set-controller s1 tcp:192.168.1.10:6633 tcp:192.168.1.11:6633 tcp:192.168.1.12:6633
    # 设置故障模式为secure,确保控制器故障时交换机保留流表并尝试连接下一个控制器
    !ovs-vsctl set-fail-mode s1 secure
    
  3. 验证:手动关闭当前连接的控制器,OVS会自动尝试连接列表中的下一个控制器,无需人工干预。

方案2:Mininet命令行手动切换(适合测试场景)

如果只是临时测试切换逻辑,可以先启动Mininet连接单个控制器,故障时手动在CLI中切换。

操作步骤

  1. 启动Mininet并指定单个控制器:
    mn --controller=remote,ip=192.168.1.10,port=6633 --topo=tree,2
    
  2. 当当前控制器故障时,在Mininet CLI中执行以下命令切换:
    # 删除当前控制器实例
    py net.delController(c0)
    # 添加新的控制器实例
    py c1 = net.addController('c1', controller=RemoteController, ip='192.168.1.11', port=6633)
    # 将所有交换机绑定到新控制器
    py for s in net.switches: s.setController(c1)
    

方案3:自定义Mininet脚本实现自动切换(适合自动化场景)

通过编写Python脚本,集成控制器故障检测逻辑,实现全自动切换。

示例脚本

from mininet.net import Mininet
from mininet.node import RemoteController, OVSSwitch
from mininet.cli import CLI
from mininet.log import setLogLevel, info
import time
import socket

def check_controller(ip, port):
    """检测控制器是否可达"""
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.settimeout(2)
    try:
        return sock.connect_ex((ip, port)) == 0
    finally:
        sock.close()

def main():
    setLogLevel('info')
    # 按优先级排序的控制器列表
    ctrl_list = [('192.168.1.10', 6633), ('192.168.1.11', 6633), ('192.168.1.12', 6633)]
    current_idx = 0
    curr_ip, curr_port = ctrl_list[current_idx]

    # 初始化网络,连接第一个控制器
    net = Mininet(controller=RemoteController, switch=OVSSwitch)
    info(f"连接初始控制器: {curr_ip}:{curr_port}\n")
    main_ctrl = net.addController('c0', ip=curr_ip, port=curr_port)
    
    # 定义拓扑(可根据需求修改)
    s1 = net.addSwitch('s1')
    h1 = net.addHost('h1')
    h2 = net.addHost('h2')
    net.addLink(s1, h1)
    net.addLink(s1, h2)

    net.start()
    info("网络启动完成\n")

    # 后台监控控制器状态的线程
    def monitor_and_switch():
        nonlocal current_idx, main_ctrl
        while True:
            time.sleep(5)
            # 检测当前控制器状态
            if not check_controller(ctrl_list[current_idx][0], ctrl_list[current_idx][1]):
                info(f"\n控制器 {ctrl_list[current_idx][0]}:{ctrl_list[current_idx][1]} 故障!\n")
                # 删除旧控制器
                net.delController(main_ctrl)
                # 切换到下一个控制器(循环切换)
                current_idx = (current_idx + 1) % len(ctrl_list)
                new_ip, new_port = ctrl_list[current_idx]
                info(f"切换到备用控制器: {new_ip}:{new_port}\n")
                # 添加新控制器并绑定到所有交换机
                main_ctrl = net.addController('c0', ip=new_ip, port=new_port)
                for switch in net.switches:
                    switch.setController(main_ctrl)
                info("控制器切换完成\n")

    # 启动监控线程
    import threading
    monitor_thread = threading.Thread(target=monitor_and_switch)
    monitor_thread.daemon = True
    monitor_thread.start()

    # 启动Mininet CLI
    CLI(net)
    net.stop()

if __name__ == '__main__':
    main()

脚本说明

  • 采用定时检测控制器端口可达性的方式判断故障(也可替换为监听OpenFlow的ECHO超时事件,更精准)
  • 控制器列表按优先级排序,故障时循环切换
  • 后台线程自动处理切换逻辑,无需人工干预

内容的提问来源于stack exchange,提问作者Titus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 15:00:37