概述
作者:张华 发表于:2015-07-01
版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明
( http://blog.csdn.net/quqi99)
DragonFlow的部署图如下:
在计算节点上要安装DragonFlow L2 Agent, 在网络节点上安装DragonFlow L3 Controler Agent, 后者会通过调用Ryu openflow控制器的为每一个计算节点上的openvswith/datapath安装下图流规则(Ryu入门教程:
http://www.sdnlab.com/1785.html):
每个虚机出来的流量经过qvb接口进入br-int网桥后都会将seg_id设置到流规则里的metadata里,显然,不同的子网就会有不同的seg_id, 再结合destination ip就可以判断是L2还是L3流量,在这里:
1, 对于ARP流量,会通过table 51有ARP响应
2, table 52表用于识别所有可能形式的东西向流量, 在计算节点上会控制南北向流量与东西向流量走不同的port出去。东西向流量这里可以替代DVR特性。
3, table 53用于处理南北向流量, 南北向流量走集中节点。
这些流详细的解释可以参见文档:
Dragonflow Deep Dive (Part 1)
http://galsagie.github.io/sdn/openstack/ovs/dragonflow/2015/05/09/dragonflow-1/
将seg_id存储在ovs的metadata(不跨ovs桥)和markup标签里(跨ovs桥),然后 使用seg_id与destination_ip判断是子网内的流量还是子网间的流量,其余的是南北流量。
1, 写metadata
cookie=0x0, duration=153.339s, table=0, n_packets=27, n_bytes=2462, priority=1000,in_port=11 actions=write_metadata:0x1f42/0xffff,goto_table:40
2, 将tunnel_id存储到markup标签里
cookie=0x0, duration=2211.658s, table=60, n_packets=0, n_bytes=0, priority=1 actions=move:NXM_NX_TUN_ID[0..31]->NXM_NX_PKT_MARK[],output:6
3, 东西向流量,例如两个子网10.1.0.0(seg_id=0x1f42)与10.2.0.0(seg_id=0x1f43), 目前这些流在每个计算节点都添加了。今后,可以优化,只添加计算节点有的子网的流。例如如果VM2 (10.2.0.3) ping VM1 (10.1.0.3), 第一个包会送到CONTROLLER:65535, 控制器会检查路由连通性(两个虚机是否在一个route上),然后配置流规则让通过,这样第一个包会稍微有点延迟。
cookie=0x0, duration=3063.423s, table=52, n_packets=0, n_bytes=0, priority=20,ip,metadata=0x1f43,nw_dst=10.1.0.0/24 actions=CONTROLLER:65535
cookie=0x0, duration=3063.421s, table=52, n_packets=0, n_bytes=0, priority=30,ip,metadata=0x1f42,nw_dst=10.1.0.0/24 actions=NORMAL
cookie=0x0, duration=3063.423s, table=52, n_packets=0, n_bytes=0, priority=20,ip,metadata=0x1f42,nw_dst=10.2.0.0/24 actions=CONTROLLER:65535
cookie=0x0, duration=3063.423s, table=52, n_packets=0, n_bytes=0, priority=30,ip,metadata=0x1f43,nw_dst=10.2.0.0/24 actions=NORMAL
4, 南北向流量,除了东西向流量剩下默认的都走南北向,10.1.0.3访问10.2.0.3,但当10.2.0.3向10.1.0.3返回数据时,下面流规则告诉它从该虚机在br-int上的那个qvo端口进入。
cookie=0x1008000040051, duration=5.708s, table=52, n_packets=1, n_bytes=98, idle_timeout=300, priority=100,ip,metadata=0x1f42,in_port=11,dl_src=fa:16:3e:00:17:e6,dl_dst=fa:16:3e:c0:8d:8b,nw_src=10.1.0.3,nw_dst=10.2.0.3 actions=dec_ttl,set_field:fa:16:3e:c0:8d:8b->eth_src,set_field:fa:16:3e:cf:4b:ed->eth_dst,output:12
output=NORMAL的含义如下图 (http://www.slideshare.net/gampel/dragonflow-sdn-based-distributed-virtual-router-for-openstack-neutron):
output=controller如下图:
上图对应的代码逻辑是, dragonflow启动时会执行sync_port,port里有seg_id等信息,然后通过调用每一个controller管理的datapath(即openflow的数据转发平面)(for switch in self.dp_list.values())为每一个port都在每个openflow设备上设置了ARP响应。
def install_l3_forwarding_flows(
self,
datapath,
msg,
in_port_data,
pkt_eth,
pkt_ipv4,
gateway_port_data,
dst_port_data,
cookie_filter,
):
"""Install the l3 forwarding flows.
:param datapath: Datapath to install into
:param msg: Message to act upon
:param in_port_data: The port that the message arrived in
:type in_port_data: PortData
:param pkt_eth: The ethernet part of the packet
:param pkt_ipv4: The ipv4 part of the packet
:param gateway_port_data: The gateway port through which the packet
would have been routed
:type gateway_port_data: PortData
:param dst_port_data: The destination port.
:type dst_port_data: PortData
:param cookie_filter: The cookie to attach to all flows
:type cookie_filter: CookieFilter
"""
dst_port_dp_id = dst_port_data.local_datapath_id
dst_seg_id = dst_port_data.segmentation_id
in_port = in_port_data.local_port_number
dst_port = dst_port_data.local_port_number
src_seg_id = in_port_data.segmentation_id
cookie = cookie_filter.to_cookie()
if dst_port_dp_id == datapath.id:
# The dst VM and the source VM are on the same compute Node
# Send output flow directly to port, use the same datapath
actions = self.add_flow_subnet_traffic(
datapath,
self.L3_VROUTER_TABLE,
MEDIUM_PRIORITY_FLOW,
in_port,
src_seg_id,
pkt_eth.src,
pkt_eth.dst,
pkt_ipv4.dst,
pkt_ipv4.src,
gateway_port_data.mac_address,
dst_port_data.mac_address,
dst_port,
cookie=cookie,
)
# Install the reverse flow return traffic
self.add_flow_subnet_traffic(
datapath,
self.L3_VROUTER_TABLE,
MEDIUM_PRIORITY_FLOW,
dst_port,
dst_seg_id,
dst_port_data.mac_address,
gateway_port_data.mac_address,
pkt_ipv4.src,
pkt_ipv4.dst,
pkt_eth.dst,
in_port_data.mac_address,
in_port,
cookie=cookie,
)
self.handle_packet_out_l3(datapath, msg, dst_port, actions)
else:
# The dst VM and the source VM are NOT on the same compute node
# Send output to br-tun patch port and install reverse flow on the
# dst compute node
remote_switch = self.dp_list.get(dst_port_dp_id)
local_switch = self.dp_list.get(datapath.id)
actions = self.add_flow_subnet_traffic(
datapath,
self.L3_VROUTER_TABLE,
MEDIUM_PRIORITY_FLOW,
in_port,
src_seg_id,
pkt_eth.src,
pkt_eth.dst,
pkt_ipv4.dst,
pkt_ipv4.src,
gateway_port_data.mac_address,
dst_port_data.mac_address,
local_switch.patch_port_num,
dst_seg_id=dst_seg_id,
cookie=cookie,
)
# Remote reverse flow install
self.add_flow_subnet_traffic(
remote_switch.datapath,
self.L3_VROUTER_TABLE,
MEDIUM_PRIORITY_FLOW,
dst_port,
dst_seg_id,
dst_port_data.mac_address,
gateway_port_data.mac_address,
pkt_ipv4.src,
pkt_ipv4.dst,
pkt_eth.dst,
in_port_data.mac_address,
remote_switch.patch_port_num,
dst_seg_id=src_seg_id,
cookie=cookie,
)
self.handle_packet_out_l3(remote_switch.datapath,
msg, dst_port, actions)
def handle_packet_out_l3(self, datapath, msg, in_port, actions):
data = None
parser = datapath.ofproto_parser
ofproto = datapath.ofproto
if msg.buffer_id == ofproto.OFP_NO_BUFFER:
data = msg.data
out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id,
in_port=in_port, actions=actions, data=data)
datapath.send_msg(out)
self,
datapath,
msg,
in_port_data,
pkt_eth,
pkt_ipv4,
gateway_port_data,
dst_port_data,
cookie_filter,
):
"""Install the l3 forwarding flows.
:param datapath: Datapath to install into
:param msg: Message to act upon
:param in_port_data: The port that the message arrived in
:type in_port_data: PortData
:param pkt_eth: The ethernet part of the packet
:param pkt_ipv4: The ipv4 part of the packet
:param gateway_port_data: The gateway port through which the packet
would have been routed
:type gateway_port_data: PortData
:param dst_port_data: The destination port.
:type dst_port_data: PortData
:param cookie_filter: The cookie to attach to all flows
:type cookie_filter: CookieFilter
"""
dst_port_dp_id = dst_port_data.local_datapath_id
dst_seg_id = dst_port_data.segmentation_id
in_port = in_port_data.local_port_number
dst_port = dst_port_data.local_port_number
src_seg_id = in_port_data.segmentation_id
cookie = cookie_filter.to_cookie()
if dst_port_dp_id == datapath.id:
# The dst VM and the source VM are on the same compute Node
# Send output flow directly to port, use the same datapath
actions = self.add_flow_subnet_traffic(
datapath,
self.L3_VROUTER_TABLE,
MEDIUM_PRIORITY_FLOW,
in_port,
src_seg_id,
pkt_eth.src,
pkt_eth.dst,
pkt_ipv4.dst,
pkt_ipv4.src,
gateway_port_data.mac_address,
dst_port_data.mac_address,
dst_port,
cookie=cookie,
)
# Install the reverse flow return traffic
self.add_flow_subnet_traffic(
datapath,
self.L3_VROUTER_TABLE,
MEDIUM_PRIORITY_FLOW,
dst_port,
dst_seg_id,
dst_port_data.mac_address,
gateway_port_data.mac_address,
pkt_ipv4.src,
pkt_ipv4.dst,
pkt_eth.dst,
in_port_data.mac_address,
in_port,
cookie=cookie,
)
self.handle_packet_out_l3(datapath, msg, dst_port, actions)
else:
# The dst VM and the source VM are NOT on the same compute node
# Send output to br-tun patch port and install reverse flow on the
# dst compute node
remote_switch = self.dp_list.get(dst_port_dp_id)
local_switch = self.dp_list.get(datapath.id)
actions = self.add_flow_subnet_traffic(
datapath,
self.L3_VROUTER_TABLE,
MEDIUM_PRIORITY_FLOW,
in_port,
src_seg_id,
pkt_eth.src,
pkt_eth.dst,
pkt_ipv4.dst,
pkt_ipv4.src,
gateway_port_data.mac_address,
dst_port_data.mac_address,
local_switch.patch_port_num,
dst_seg_id=dst_seg_id,
cookie=cookie,
)
# Remote reverse flow install
self.add_flow_subnet_traffic(
remote_switch.datapath,
self.L3_VROUTER_TABLE,
MEDIUM_PRIORITY_FLOW,
dst_port,
dst_seg_id,
dst_port_data.mac_address,
gateway_port_data.mac_address,
pkt_ipv4.src,
pkt_ipv4.dst,
pkt_eth.dst,
in_port_data.mac_address,
remote_switch.patch_port_num,
dst_seg_id=src_seg_id,
cookie=cookie,
)
self.handle_packet_out_l3(remote_switch.datapath,
msg, dst_port, actions)
def handle_packet_out_l3(self, datapath, msg, in_port, actions):
data = None
parser = datapath.ofproto_parser
ofproto = datapath.ofproto
if msg.buffer_id == ofproto.OFP_NO_BUFFER:
data = msg.data
out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id,
in_port=in_port, actions=actions, data=data)
datapath.send_msg(out)
目前,DragonFlow仅支持中心化的SNAT与DNAT,还不支持在计算节点上做SNAT与DNAT.
下面是Neutron的几张重要的图:
1, 计算节点,
计算节点没有使用namespace,采用的是local vlan id来隔离不同网络的流量。出计算节点之后,因为计算节点只有二层,所以
使用MAC地址也能区分。这样就不需要namesapce.
2, 下面是网络节点,网络节点在br-int上使用了namespace为每一个子网来提供 gateway
其路线图见[1].
1, 分布式SNAT/DNAT
2, 服务链,允许外部应用定义服务链
3, 支持硬件NIC
4, 层次化的Port Binding (SDN TORs)
5, 虚机里跑容器的支持,和Kuryr的支持(Kuryr是一个docker libnetwork网络对neturon网络的桥接器,允许docker不通过nova而直接使用neutron)
2, 服务链,允许外部应用定义服务链
3, 支持硬件NIC
4, 层次化的Port Binding (SDN TORs)
5, 虚机里跑容器的支持,和Kuryr的支持(Kuryr是一个docker libnetwork网络对neturon网络的桥接器,允许docker不通过nova而直接使用neutron)
[1] http://galsagie.github.io/sdn/openstack/ovs/dragonflow/2015/10/14/dragonflow-liberty/
最后
以上就是悦耳钢铁侠为你收集整理的DragonFlow导读(by quqi99)的全部内容,希望文章能够帮你解决DragonFlow导读(by quqi99)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复