顺利完成目标~~~开开心心地开始学Open vSwitch
概念
简而言之就是一个虚拟交换机。主要有如下两个作用:
- 传递虚拟机啊VM之间的流量
- 实现VM和外界网络的通信
- Bridge: Bridge 代表一个以太网交换机(Switch),一个主机中可以创建一个或者多个 Bridge 设备。
- Port: 端口与物理交换机的端口概念类似,每个 Port 都隶属于一个 Bridge。
- Interface: 连接到 Port 的网络接口设备。在通常情况下,Port 和 Interface 是一对一的关系, 只有在配置 Port 为 bond 模式后,Port 和 Interface 是一对多的关系。
- Controller: OpenFlow 控制器。OVS 可以同时接受一个或者多个 OpenFlow 控制器的管理。
- datapath: 在 OVS 中,datapath 负责执行数据交换,也就是把从接收端口收到的数据包在流表中进行匹配,并执行匹配到的动作。
- Flow table: 每个 datapath 都和一个“flow table”关联,当 datapath 接收到数据之后, OVS 会在 flow table 中查找可以匹配的 flow,执行对应的操作, 例如转发数据到另外的端口。支持 OpenFlow 协议的交换机应该包括一个或者多个流表,流表中的条目包含:数据包头的信息、匹配成功后要执行的指令和统计信息
- Flow : 在 OpenFlow 的白皮书中,Flow 被定义为某个特定的网络流量。例如,一个 TCP 连接就是一个 Flow,或者从某个 IP 地址发出来的数据包,都可以被认为是一个 Flow。
架构
-
ovs-vswitchd:OVS守护进程,OVS的核心部件,实现交换功能,和Linux内核兼容模块一起,实现基于流的交换(flow-based switching)。它和上层 controller 通信遵从 OPENFLOW 协议,它与 ovsdb-server 通信使用 OVSDB 协议,它和内核模块通过netlink通信,它支持多个独立的 datapath(网桥),它通过更改flow table 实现了绑定和VLAN等功能。
-
ovsdb-server:轻量级的数据库服务,主要保存了整个OVS 的配置信息,包括接口啊,交换内容,VLAN啊等等。ovs-vswitchd 会根据数据库中的配置信息工作。它于 manager 和 ovs-vswitchd 交换信息使用了OVSDB(JSON-RPC)的方式。
-
ovs-dpctl:一个工具,用来配置交换机内核模块,可以控制转发规则。
-
ovs-vsctl:主要是获取或者更改ovs-vswitchd 的配置信息,此工具操作的时候会更新ovsdb-server 中的数据库。
-
ovs-appctl:主要是向OVS 守护进程发送命令的,一般用不上。ovs-appctl ofproto/trace 可以用来生成测试用的模拟数据包,并一步步的展示 OVS 对数据包的流处理过程。
-
ovsdbmonitor:GUI 工具来显示ovsdb-server 中数据信息。
-
ovs-controller:一个简单的OpenFlow 控制器
-
ovs-ofctl:用来控制OVS 作为OpenFlow 交换机工作时候的流表内容。
工作流程
VM实例 instance 产生一个数据包并发送至实例内的虚拟网络接口 VNIC,图中就是 instance 中的 eth0.
这个数据包会传送到物理机上的VNIC接口,如图就是vnet接口。
数据包从 vnet NIC 出来,到达桥(虚拟交换机) br100 上.
数据包经过交换机的处理,从物理节点上的物理接口发出,如图中物理机上的 eth0 .
数据包从 eth0 出去的时候,是按照物理节点上的路由以及默认网关操作的,这个时候该数据包其实已经不受你的控制了。
一般 L2 switch 连接 eth0 的这个口是一个 trunk 口, 因为虚拟机对应的 VNET 往往会设置 VLAN TAG, 可以通过对虚拟机对应的 vnet 打 VALN TAG 来控制虚拟机的网络广播域. 如果跑多个虚拟机的话, 多个虚拟机对应的 vnet 可以设置不同的 vlan tag, 那么这些虚拟机的数据包从 eth0(4)出去的时候, 会带上TAG标记. 这样也就必须是 trunk 口才行.
知识点补充
交换机端口
交换机端口分为四种:
- Access类型的端口只能属于1个VLAN,一般用于连接计算机的端口;
- Trunk类型的端口可以允许多个VLAN通过,可以接收和发送多个VLAN的报文,一般用于交换机之间连接的端
- link还介绍了另外两种
桥
在网络中,交换机和桥都是同一个概念,OVS实现了一个虚拟机的以太交换机,换句话说,OVS也就是实现了一个以太桥。那么,在OVS中,给一个交换机,或者说一个桥,用了一个专业的名词,叫做DataPath。网桥是以混杂模式工作的
在ovs中:
当我们创建了一个交换机(网桥)以后,此时网络功能不受影响,但是会产生一个虚拟网卡,名字就是网桥的名称(br-int),之所以会产生一个虚拟网卡,是为了实现接下来的网桥(交换机)功能。有了这个交换机以后,还需要为这个交换机增加端口(port),一个端口,就是一个物理网卡,当网卡加入到这个交换机之后,其工作方式就和普通交换机的一个端口的工作方式类似了。
给虚拟网卡br-int(交换机的管理接口)配置IP以后,就相当于给交换机的管理接口配置了IP,此时一个正常的虚拟交换机就搞定了。
Flow语法说明
当数据包进入 OVS 后,会将数据包和流表中的流表项进行匹配,如果发现了匹配的流表项,则执行该流表项中的指令集。相反,如果数据包在流表中没有发现任何匹配,OVS 会通过控制通道把数据包发到 OpenFlow 控制器中。
在 OVS 中,流表项作为 ovs-ofctl 的参数,采用如下的格式:字段=值。如果有多个字段,可以用逗号或者空格分开。
一些常用的字段列举如下:
字段名称 | 说明 |
---|---|
in_port=port | 传递数据包的端口的OpenFlow端口编号 |
dl_vlan=vlan | 数据包的 VLAN Tag 值,范围是 0-4095,0xffff 代表不包含 VLAN Tag 的数据包 |
dl_src=MAC dl_dst=MAC | 匹配源或者目标的 MAC 地;01:00:00:00:00:00/01:00:00:00:00:00 代表广播地址;00:00:00:00:00:00/01:00:00:00:00:00 代表单播地址 |
dl_type=ethertype | 匹配以太网协议类型,其中:dl_type=0x0800 代表 IPv4 协议;dl_type=0x086dd 代表 IPv6 协议;dl_type=0x0806 代表 ARP 协议 |
nw_src=ip[/netmask] | |
nw_dst=ip[/netmask] | 当 dl_typ=0x0800 时,匹配源或者目标的 IPv4 地址,可以使 IP 地址或者域名 |
nw_proto=proto | 和 dl_type 字段协同使用。;当 dl_type=0x0800 时,匹配 IP 协议编号;当 dl_type=0x086dd 代表 IPv6 协议编号 |
table=number | 指定要使用的流表的编号,范围是 0-254。在不指定的情况下,默认值为 0。通过使用流表编号,可以创建或者修改多个 Table 中的 Flow |
reg=value[/mask] | 交换机中的寄存器的值。当一个数据包进入交换机时,所有的寄存器都被清零,用户可以通过 Action 的指令修改寄存器中的值 |
对于 add−flow,add−flows 和 mod−flows 这三个命令,还需要指定要执行的动作:actions=[target][,target…]
一个流规则中可能有多个动作,按照指定的先后顺序执行。
常见的操作有:
- output:port: 输出数据包到指定的端口。port 是指端口的 OpenFlow 端口编号
- mod_vlan_vid: 修改数据包中的 VLAN tag
- strip_vlan: 移除数据包中的 VLAN tag
- mod_dl_src/ mod_dl_dest: 修改源或者目标的 MAC 地址信息
- mod_nw_src/mod_nw_dst: 修改源或者目标的 IPv4 地址信息
- resubmit:port: 替换流表的 in_port 字段,并重新进行匹配
- load:value−>dst[start…end]: 写数据到指定的字段
实践学习
安装完毕后,检查OVS运行情况
查看版本信息
查看支持的OpenFlow版本
创建一个新的OVS交换机
ovs-vsctl add-br ovs-switch 该交换机的名字叫做ovs-switch
创建端口
ovs-vsctl add-port ovs-switch p0
Error :
尝试解决又遇到了
后来换了个教程emm
ovs-vsctl add-port ovs-switch p0 -- set Interface p0 ofport_request=100
port和Interface默认是一一对应的
指定了OpenFlow端口编号为100,不指定OVS会自动生成一个
不要慌,咱继续。设置网络接口设备类型为internal。该类型的网络接口,OVS会同时在Linux系统中创建一个可以用来收发数据的模拟网络设备。我们可以为整个网络设备配置IP地址,进行数据监听等等。
为了避免网络接口上的地址和本机已有网络地址冲突,我们可以创建一个虚拟网络空间 ns0,把 p0 接口移入网络空间 ns0,并配置 IP 地址为 192.168.1.101。之后在root下就不能直接对p0进行操作了
ip netns add ns0
$ ip link set p0 netns ns0
$ ip netns exec ns0 ip addr add 192.168.1.100/24 dev p0
$ ip netns exec ns0 ifconfig p0 promisc up
当端口被移入网络接口空间后,就要用ip netns exec ns_name 的方式执行可在命令行下执行的命令
查看交换机信息
使用ovs-ofctl创建并测试OpenFlow命令
- 查看Open vSwitch中的额端口信息。从输出结果中,可以获得交换机对应的 datapath ID (dpid),以及每个端口的 OpenFlow 端口编号,端口名称,当前状态等等
想获得网络接口的OpenFlow编号,可以在OVS的数据库中查询:
查看datapath信息
- 屏蔽数据报
屏蔽所有进入OVS的以太网广播数据报
ovs-ofctl add-flow ovs-switch "table=0, dl_src=01:00:00:00:00:00/01:00:00:00:00:00, actions=drop"
屏蔽 STP 协议的广播数据包
ovs-ofctl add-flow ovs-switch "table=0, dl_dst=01:80:c2:00:00:00/ff:ff:ff:ff:ff:f0, actions=drop"
- 修改数据包
添加新的 OpenFlow 条目,修改从端口 p0 收到的数据包的源地址为 9.181.137.1
ovs-ofctl add-flow ovs-switch "priority=1 idle_timeout=0,\ in_port=100,actions=mod_nw_src:9.181.137.1,normal"没有看明白为什么有的地方是带引号有的地方不带引号
从端口 p0(192.168.1.100)发送测试数据到端口 p1(192.168.1.101)
ip netns exec ns0 ping 192.168.1.101
在接收端口 p1 监控数据,发现接收到的数据包的来源已经被修改为 9.181.137.1
ip netns exec ns1 tcpdump -i p1 icmp
从这里可以看到 OpenFlow的规则是无视netns的
配置错误?
参考了[link](https://serverfault.com/questions/646605/hosts-cannot-ping-in-two-name-spaces-using-open-vswitch/646631#646631)这个回答,难道是因为type不是veth的原因?
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191016171706581.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2lyb3kzMw==,size_16,color_FFFFFF,t_70)为什么ping失败:ovs-ofctl Example Usage中搭建的网络没有controller,因此交换机不知道该做什么,需要我们手动添加流
# ovs-ofctl add-flow ovs-switch in_port=100,actions=output:101
# ovs-ofctl add-flow ovs-switch in_port=101,actions=output:100
这个时候看流表,它就不是空的了,但是这显然没有达到想要的目的
IP地址没有改变?难道是因为空间不一样?
这个是流表内容,感到困惑
10/17 继续学习
ip netns exec ns0 之后就是命令行内容可以执行~
换了环境后就成功了,不知道是openflow版本问题还是ovs版本问题
在接收端口 p1 监控数据,发现接收到的数据包的来源已经被修改为 9.181.137.1
- 重定向数据包
添加新的 OpenFlow 条目,重定向所有的 ICMP 数据包到端口 p2
**哪里体现是ICMP包了orz???
ip netns exec ns3 tcpdump -i p2 icmp
- 修改数据报的VLAN tag
除了使用“ping”、“tcpdump”和“iperf” 等 Linux 命令以外,我们也可以使用 OVS 提供的 ovs-appctl ofproto/trace 工具来测试 OVS 对数据包的转发状况。ovs-appctl ofproto/trace 可以用来生成测试用的模拟数据包,并一步步的展示 OVS 对数据包的流处理过程。
修改端口 p1 的 VLAN tag 为 101,使端口 p1 成为一个隶属于 VLAN 101 的端口
ovs-vsctl set Port p1 tag=101
现在由于端口 p0 和 p1 属于不同的 VLAN,它们之间无法进行数据交换。我们使用 ovs-appctl ofproto/trace 生成一个从端口 p0 发送到端口 p1 的数据包,这个数据包不包含任何 VLAN tag,并观察 OVS 的处理过程
第一行:“Flow”描述了输入的流的信息。未指定的字段被OVS设置为空值0x0000
第二行:“Rule”描述匹配成功的流表项
第三行:“OpenFlow actions”描述了实际执行的操作
最后一行:“Final flow”是整个处理过程的总结,“Datapath actions:10,7”代表数据包被发送到datapath的10和7号端口
可以看到,10是ovs switch,7是p2。没有涉及到我们的目标p0和p1
不明白那个MAC地址对是怎么出来的
dl_vlan=0xffff
不包含VLAN tag的数据包
再次尝试从端口 p0 发送一个不包含任何 VLAN tag 的数据包,发现数据包进入端口 p0 之后, 会被加上 VLAN tag101, 同时转发到端口 p1 上
看最后一行Datapath,先加标签101,发给ovs-switch,然后弹出标签,发给port1,最后达到port2。到达port2是因为所有的ICMP包被重定向给p2了吗,感觉不太对
反过来从端口 p1 发送数据包,由于 p1 现在是带有 VLAN tag 101 的 Access 类型的端口,所以数据包进入端口 p1 之后,会被 OVS 添加 VLAN tag 101 并发送到端口 p0,看最后一行Datapath
6. 其他OpenFlow常用的操作
- 查看交换机中所有的table
ovs-ofctl dump-tables ovs-switch - 查看交换机中的所有流表项
ovs−ofctl dump−flows ovs-switch - 删除编号为 100 的端口上的所有流表项
ovs-ofctl del-flows ovs-switch “in_port=100” - 查看交换机上的端口信息
ovs-ofctl show ovs-switch