Mininet中host与外网通信

在学习SDN的过程中,mininet是一个必不可少的网络虚拟环境。从上个学期开始学了许多的mininet的用法,但是一直是在一个mininet生成的虚拟的拓扑内部进行主机内通信测试,没办法访问外网。在网络上查了许多资料,也踩了很多的坑,下面我来分享下我将host连接外网的方法。

目前为止host与外网通信我试过的有2种方法,第一种是使用mininet/example/nat.py这个脚本来实现NAT,另外一种就是将交换机与虚拟机中的虚拟网卡进行桥接的方式,主要介绍一下第二种方法,这种方法我主要是参考http://blog.csdn.net/jackieleewelas/article/details/50532690的这篇文章,写的比较详细。

下面开始详细介绍一下:

首先是在虚拟器设置2张网卡,2张网卡都选择NAT模式,选择NAT的话对应的是VM8,需要在虚拟网络编辑器上再进行一下设置。

Mininet中host与外网通信_第1张图片


在网络编辑器中将NAT设置DHCP启动,也就是说虚拟机的网口会自动获得一个IP地址

Mininet中host与外网通信_第2张图片

再设置一下网关和DHCP地址池

Mininet中host与外网通信_第3张图片

Mininet中host与外网通信_第4张图片


全部都设置好了之后 打开虚拟机,输入Ifconfig,可以看到2张虚拟网卡,IP地址分别是10.0.0.0/24网段的241和240

Mininet中host与外网通信_第5张图片

分别用ping -I ifname www.baidu.com命令测试一下各个接口与外网的连通性

Mininet中host与外网通信_第6张图片


发现eth1接口上出去的icmp包是没办法访问外网的,所以这个闲置的网口可以被我们用来与mininet环境中的switch进行桥接,从而实现对外网的访问

使用sudo ifconfig eth1 0.0.0.0命令将eth1的ip地址设为0.0.0.0,可以看到在ifconfig中我们看不到eth1的ip地址了


Mininet中host与外网通信_第7张图片

#!/usr/bin/python  
#-*- coding:utf-8 -*-
import re  
import sys  
from mininet.cli import CLI  
from mininet.log import setLogLevel, info, error  
from mininet.net import Mininet  
from mininet.link import Intf  
from mininet.util import quietRun  
from mininet.node import OVSSwitch, OVSController, Controller, RemoteController  
from mininet.topo import Topo  
  
class MyTopo( Topo ):  
#    "this topo is used for Scheme_1"  
      
    def __init__( self ):  
        "Create custom topo."  
  
        # Initialize topology  
        Topo.__init__( self )  
  
        # Add hosts   
        h1 = self.addHost( 'h1' , ip="10.0.0.1/24", mac="00:00:00:00:00:01", defaultRoute="via 10.0.0.254")  
        h2 = self.addHost( 'h2' , ip="10.0.0.2/24", mac="00:00:00:00:00:02", defaultRoute="via 10.0.0.254")  
        h3 = self.addHost( 'h3' , ip="10.0.0.3/24", mac="00:00:00:00:00:03", defaultRoute="via 10.0.0.254")  
        h4 = self.addHost( 'h4' , ip="10.0.0.4/24", mac="00:00:00:00:00:04", defaultRoute="via 10.0.0.254")  
          
        # Add switches  
        s1 = self.addSwitch( 's1' )  
        s2 = self.addSwitch( 's2' )  
        s3 = self.addSwitch( 's3' )  
  
        # Add links  
        self.addLink( s1, s2 )  
        self.addLink( s1, s3 )  
        self.addLink( s2, h1 )  
        self.addLink( s2, h2 )  
        self.addLink( s3, h3 )  
        self.addLink( s3, h4 )  
#检查eth1或者其他指定的网卡资源是不是已经被占用  
def checkIntf( intf ):  
    "Make sure intf exists and is not configured."  
    if ( ' %s:' % intf ) not in quietRun( 'ip link show' ):  
        error( 'Error:', intf, 'does not exist!\n' )  
        exit( 1 )  
    ips = re.findall( r'\d+\.\d+\.\d+\.\d+', quietRun( 'ifconfig ' + intf ) )  
    if ips:  
        error( 'Error:', intf, 'has an IP address,'  
               'and is probably in use!\n' )  
        exit( 1 )  
  
if __name__ == '__main__':  
    setLogLevel( 'info' )  
  
    # try to get hw intf from the command line; by default, use eth1  
    intfName = sys.argv[ 1 ] if len( sys.argv ) > 1 else 'eth1'  
    info( '*** Connecting to hw intf: %s' % intfName )  
  
    info( '*** Checking', intfName, '\n' )  
    checkIntf( intfName )  
  
    info( '*** Creating network\n' )  
    net = Mininet( topo=MyTopo(),controller=None) #关键函数,创建mininet网络,指定拓扑和控制器。这里的控制器在后面添加进去  
    switch = net.switches[ 0 ] #取第一个交换机与eth1桥接  
    info( '*** Adding hardware interface', intfName, 'to switch', switch.name, '\n' )  
    _intf = Intf( intfName, node=switch ) #最关键的函数,用作把一个网卡与一个交换机桥接  
  
    info( '*** Note: you may need to reconfigure the interfaces for '  
          'the Mininet hosts:\n', net.hosts, '\n' )  
    c0 = RemoteController( 'c0', ip='127.0.0.1', port=6633 )  
    net.addController(c0)  
    net.start()  
    CLI( net )  
    net.stop()  

这边的代码基本都来自我参考的博客,而在mininet官方github上也有用Intf连接外网的例子。

python脚本完成后,启动控制器,我这边使用的是POX,pox控制器默认监听的是6633端口,控制器使用的是默认的forwarding目录下的l2_learning.py,这个脚本实现了一个2层交换机的基本功能。另外,运行POX控制器的时候在命令行加入log.level --DEBGU 可以输出更加详细的信息

Mininet中host与外网通信_第8张图片

控制器启动之后运行我们上面mininet脚本

Mininet中host与外网通信_第9张图片

运行xterm启动h1

Mininet中host与外网通信_第10张图片

查看一下h1的基本配置,然后ping外网发现目标主机未知,猜想可能是DNS原因

Mininet中host与外网通信_第11张图片

通过gedit /etc/resolv.conf 查看dns设置,发现dns设置为127.0.0.1,在自己原来的主机中通过Ipconfig -all命令查询DNS服务器并修改resolv.conf文件

Mininet中host与外网通信_第12张图片

改成192.168.2.3

Mininet中host与外网通信_第13张图片


回到h1的界面发现此时ping 百度可以通了!大功告成

Mininet中host与外网通信_第14张图片

可以通过ovs-ofctl dump-flows switchname 命令来查看交换机的流表发现此时通过pox控制器给交换机下发了很多流表

Mininet中host与外网通信_第15张图片


关闭mininet之后,通过sudo mn -c 可以清空之前mininet的缓存,这样原先生成的交换机和eth1的接口也就消失了

host访问外网的流程大致就是这样了!有想要学习相关的知识最好的方法还是google和github上面mininet的wiki

还是很多东西不懂,第一篇自己写的博客,虚心向大家学习!

你可能感兴趣的:(SDN)