原创

15-GRE与VXLAN网络

引入

需求描述

自家里的网络与公司的网络,相互隔离。现在下班后回到了家里,但是公司那边现在有一个业务需要自己去处理,这个时候自己就想要在家里访问公司内部的局域网了。
如果所有操作都通过公网ip绕,既不方便,也不安全。
如果拉专线,是最稳定可靠的办法。但是现在又没有多余的资金。
所以准备使用现有方案来解决这个需求。

背景介绍

自己家里的局域网是192.168.10.0/24,是通过PPOE拨号上网;

公网机里的局域网是10.100.0.0/24,有一个公网ip,通过公网ip进行上网;

这就遇到问题:自己家里的网络怎样能直接访问公司的内网?

这里有两个方案

1、点到点的虚拟专用网络。
2、GRE方案。

GRE网络

认识GRE

什么是GRE?

GRE是一种协议封装的格式,它规定了**如何用一种网络协议去封装另一种网络协议**。

有什么用?

将原来普通的包再封装一层GRE包,又**按照普通的ip包的路由方式进行路由**

如何工作的

**使用 tunnel(隧道)技术,数据报在tunnel的两端封装,并在这个通路上传输,到另外一端的时候解封装。**

概括

**物理上的三层通信,虚拟上的二层通信**

场景

GRE

通信过程

0)gre建立turnel通道

1、 双方建立turnel的过程。   

(1)局域网路由过程

1、主机MypC发送一个源为192.168.1.123,目的为10.100.0.123的包

(2)封装过程

1、根据默认路由网关,将之路由至192.168.1.1
2、192.168.1.1第1次封装包,增加增加gre包头,说明包的目的地址172.16.16.2和源地址172.16.16.1。
3、192.168.1.1第2次封装包,增加公网的包头(为了能在公网上传输),说明包的目的地址106.38.241.118和源地址221.234.230.1
4、192.168.1.1把所有到10.100.0.0/24的包,都地址转换为从172.16.16.1出(snat)

(3)公网路由过程

1、经过n个路由设备,该包最终路由到106.38.241.118

(4)拆包过程

1、CloudPC端的路由器检测到是到达自己的ip,就开始拆包
2、拆包之后发现有GRE协议,就进一步拆包
3、拆包之后发现目的地不是自己的内网ip、发现自己本地做了snat,就将至源ip替换为10.100.0.1

(5)到了局域网

1、数据包从源10.100.0.1到目标10.100.0.123,直接在局域网内广播。
2、10.100.0.123的主机经过确定后,发现是发送给自己的包,就接收。然后进一步处理。

原文字描述

GRE的好处

  1. 解决vlan上限问题,gre id有224个
  2. 只识别终端网络风暴(当包到达目的地再发到主机时)
  3. 三层网络
  4. 私有ip可以任意划分,ip子网划分问题也不存在了

GRE的不足

(1)Tunnel 的数量问题

GRE 是一种点对点(point to point)标准。Neutron 中,所有计算和网络节点之间都会建立 GRE Tunnel。当节点不多的时候,这种组网方法没什么问题。但是,当有一个很大的数据中心,有 40000 个节点的时候,又会是怎样一种情形呢?使用标准 GRE的话,将会有 780 millions 个 tunnels。

(2)扩大的广播域

GRE 不支持组播,因此一个网络(同一个 GRE Tunnel ID)中的一个虚机发出一个广播帧后,GRE 会将其广播到所有与该节点有隧道连接的节点。

(3)GRE封装的IP包的过滤和负载均衡问题

目前还是有很多的防火墙和三层网络设备无法解析 GRE Header,因此它们无法对 GRE 封装包做合适的过滤和负载均衡。

VXLAN网络

简介

VXLAN全称Virtual eXtensible LAN,是一种覆盖网络技术或隧道技术。

与GRE一样,封装、转发2层报文,物理上的三层通信,虚拟上的二层通信。

原始2层包+(1.vni id 2.组播地址)+udp报送+ip报头

使用VXLAN网络模式,它会将主机发出的数据包封装在UDP中(vxlan建立的隧道都是无状态的了,这个做的好处是不用占用大量连接),并使用物理网络的IP/MAC在头部进行封装,然后在物理IP网上传输,到达目的地后由隧道终结点解封并将数据发送给目标主机。

为什么需要Vxlan

  1. vlan的数量限制 4096个vlan远不能满足大规模云计算数据中心的需求
  2. 物理网络基础设施的限制 云主机跨网络迁移时MAC地址不能变,它需要在一个二层的网络中完成
  3. 交换机MAC表耗尽 虚拟化以及东西向流量导致更多的MAC表项

具体参考

https://www.cnblogs.com/xingyun/p/4620727.html

https://www.sdnlab.com/11819.html

http://www.opencloudblog.com/?p=300

实验

0.完成图

1.修改网络类型

  • 编辑控制节点ml2配置文件
[root@controller /]# vim /etc/neutron/plugins/ml2/ml2_conf.ini
[ml2]
type_drivers=flat,vlan,vxlan,gre,local
tenant_network_types=vxlan
mechanism_drivers=openvswitch,l2population

[ml2_type_vxlan]
#指定vxlan的id范围,给普通租户用的
vni_ranges=1000:2000
  • 重启服务
[root@controller /]# systemctl restart neutron-server

2.配置ovs代理

  • 控制节点
[root@controller ~]# vim /etc/neutron/plugins/ml2/openvswitch_agent.ini 
[ovs]
tenant_network_type=vxlan
#可以不要这一项了
bridge_mappings=
integration_bridge=br-int
tunnel_bridge=br-tun
#注意这个是本机的ip
local_ip=192.168.150.10
  • 计算节点
[root@computer /]# vim /etc/neutron/plugins/ml2/openvswitch_agent.ini
[ovs]
tenant_network_type=vxlan
bridge_mappings=
integration_bridge=br-int
tunnel_bridge=br-tun
local_ip=192.168.150.11
  • 重启服务
[root@controller /]# systemctl restart neutron-openvswitch-agent.service 
[root@computer /]# systemctl restart neutron-openvswitch-agent.service 

3.创建VXLAN网络

  • 使用管理员的身份去创建类型为vxlan,名为vxlan_net,vxlan_id=111的网络
[root@controller ~(keystone_admin)]# openstack network create vxlan_net --project admin --provider-network-type vxlan  --provider-segment 111
  • 创建子网
[root@controller ~(keystone_admin)]# openstack subnet create vxlan_subnet --project admin --network vxlan_net --subnet-range 172.16.166.0/24 --allocation-pool  start=172.16.166.100,end=172.16.166.200

4.创建云主机

  • 创建云主机ServerA在控制节点上
[root@controller ~(keystone_admin)]#  openstack server create ServerA --image ciross --flavor web.ciross --nic net-id=2175ed07-99c9-4821-8cd8-3fd7148ab9f5  --availability-zone nova
  • 创建云主机ServerB在计算点上
[root@controller ~(keystone_admin)]#  openstack server create ServerB --image ciross --flavor web.ciross --nic net-id=2175ed07-99c9-4821-8cd8-3fd7148ab9f5  --availability-zone cpu

5.连通性测试

ServerA->ping->ServerB

[root@controller opt]# virsh console instance-00000001 
连接到域 instance-00000001
换码符为 ^]


login as 'cirros' user. default password: 'cubswin:)'. use 'sudo' for root.
cirros login: cirros
Password: 
$ sudo su - root
# ifconfig eth0
eth0      Link encap:Ethernet  HWaddr FA:16:3E:7A:F5:1D  
          inet addr:172.16.166.117  Bcast:172.16.166.255  Mask:255.255.255.0
          inet6 addr: fe80::f816:3eff:fe7a:f51d/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1450  Metric:1
          RX packets:92 errors:0 dropped:0 overruns:0 frame:0
          TX packets:89 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:5319 (5.1 KiB)  TX bytes:5084 (4.9 KiB)

# ping 172.16.166.125
PING 172.16.166.125 (172.16.166.125): 56 data bytes
64 bytes from 172.16.166.125: seq=0 ttl=64 time=4.319 ms
64 bytes from 172.16.166.125: seq=1 ttl=64 time=1.883 ms
64 bytes from 172.16.166.125: seq=2 ttl=64 time=1.332 ms
 
--- 172.16.166.125 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 1.332/2.511/4.319 ms

ServerB->ping->ServerA

[root@computer /]# virsh console instance-00000002 
连接到域 instance-00000002
换码符为 ^]


login as 'cirros' user. default password: 'cubswin:)'. use 'sudo' for root.
cirros login: cirros
Password: 
$ sudo su - root
# ifconfig eth0
eth0      Link encap:Ethernet  HWaddr FA:16:3E:29:99:6A  
          inet addr:172.16.166.125  Bcast:172.16.166.255  Mask:255.255.255.0
          inet6 addr: fe80::f816:3eff:fe29:996a/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1450  Metric:1
          RX packets:92 errors:0 dropped:0 overruns:0 frame:0
          TX packets:89 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:5311 (5.1 KiB)  TX bytes:5084 (4.9 KiB)

# ping 172.16.166.117
PING 172.16.166.117 (172.16.166.117): 56 data bytes
64 bytes from 172.16.166.117: seq=0 ttl=64 time=25.137 ms
64 bytes from 172.16.166.117: seq=1 ttl=64 time=1.563 ms
64 bytes from 172.16.166.117: seq=2 ttl=64 time=1.587 ms
 
--- 172.16.166.117 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 1.563/9.429/25.137 ms

6.查看流表

实验环境图

image.png

内部网桥流表

  • 查看控制节点的br-int流表
 #进端口是qvo00a1bde0的arp请求就扔给table24
 cookie=0xb188cb61096fc88b, duration=943.793s, table=0, n_packets=73, n_bytes=3066, priority=10,arp,in_port="qvo00a1bde0-be" actions=resubmit(,24)
 
 #进端口是qvo00a1bde0的请求就扔给table25
 cookie=0xb188cb61096fc88b, duration=943.798s, table=0, n_packets=27, n_bytes=2872, priority=9,in_port="qvo00a1bde0-be" actions=resubmit(,25)
 
 #(table24)->进端口是qvo00a1bde0的arp请求,并且arp的源地址是172.16.166.117(ServerA)就扔给table25
  cookie=0xb188cb61096fc88b, duration=943.794s, table=24, n_packets=73, n_bytes=3066, priority=2,arp,in_port="qvo00a1bde0-be",arp_spa=172.16.166.117 actions=resubmit(,25)
  
  #(table24)->其他不符合table24匹配就丢掉
  cookie=0xb188cb61096fc88b, duration=1898.495s, table=24, n_packets=0, n_bytes=0, priority=0 actions=drop
  
  #(table25)->进端口是qvo00a1bde0并且MAC地址是ServerA的MAC地址,就扔给table60
 cookie=0xb188cb61096fc88b, duration=943.801s, table=25, n_packets=98, n_bytes=5798, priority=2,in_port="qvo00a1bde0-be",dl_src=fa:16:3e:7a:f5:1d actions=resubmit(,60)
 
 #(table60)->直接放行
 cookie=0xb188cb61096fc88b, duration=1898.496s, table=60, n_packets=240, n_bytes=16454, priority=3 actions=NORMAL

根据serverA的MAC地址进行ARP的转发,同时也转发ipv4,ipv6的数据包

隧道流表示意图

  • 查看br-tun的table0
[root@controller opt]# ovs-ofctl dump-flows br-tun |grep table=0
 cookie=0x49974807b8df046c, duration=2461.613s, table=0, n_packets=115, n_bytes=7801, idle_age=1020, priority=1,in_port=1 actions=resubmit(,2)
 cookie=0x49974807b8df046c, duration=2456.202s, table=0, n_packets=0, n_bytes=0, idle_age=16008, priority=1,in_port=2 actions=resubmit(,3)
 cookie=0x49974807b8df046c, duration=2456.154s, table=0, n_packets=98, n_bytes=5798, idle_age=1020, priority=1,in_port=3 actions=resubmit(,4)
 cookie=0x49974807b8df046c, duration=2461.612s, table=0, n_packets=0, n_bytes=0, idle_age=16224, priority=0 actions=drop

发现一个有四条规则,分别从1,2,3口进来,其中最后一个是丢弃

  • 查看br-tun端口
[root@controller opt]#   ovs-ofctl show br-tun 
OFPT_FEATURES_REPLY (xid=0x2): dpid:0000de7928e28a49
n_tables:254, n_buffers:0
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
 1(patch-int): addr:4e:e7:e5:f0:48:28
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 2(gre-c0a8960b): addr:d6:7e:9e:b8:d5:0b
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 3(vxlan-c0a8960b): addr:ae:d0:fd:a0:9a:a6
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 LOCAL(br-tun): addr:de:79:28:e2:8a:49
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0

得知2号口是gre可以不用管,看1和3口的规则就可以了 从1口(br-int,内部)进来的数据包转发到table2 从3口(vxlan-c0a,外部)进来的数据包转发到table4

  • 查看table4,也就是从外部进来的数据包
[root@controller opt]#  ovs-ofctl dump-flows br-tun |grep table=4
 cookie=0x49974807b8df046c, duration=2524.908s, table=4, n_packets=98, n_bytes=5798, idle_age=1197, priority=1,tun_id=0x6f actions=mod_vlan_vid:1,resubmit(,10)
 cookie=0x49974807b8df046c, duration=2638.056s, table=4, n_packets=0, n_bytes=0, idle_age=16400, priority=0 actions=drop

如果数据包的VXLAN tunnel ID为0x6f(十进制的111) 就添加内部VLAN ID 1(也就是br-int的tag),然后扔给table10去学习

  • 查看table10,是从table4扔过来的
[root@controller opt]#  ovs-ofctl dump-flows br-tun |grep table=10
 cookie=0x49974807b8df046c, duration=2723.722s, table=10, n_packets=98, n_bytes=5798, idle_age=1282, priority=1 actions=learn(table=20,hard_timeout=300,priority=1,cookie=0x49974807b8df046c,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:0->NXM_OF_VLAN_TCI[],load:NXM_NX_TUN_ID[]->NXM_NX_TUN_ID[],output:OXM_OF_IN_PORT[]),output:1

学习从tunnel进来的包,往table20中添加对返程包的正常转发规则,然后从从port1(patch-int)转发到br-int

  • 查看table2,从内部过来的包
[root@controller /]# ovs-ofctl dump-flows br-tun |grep "\btable=2\b"
 cookie=0x49974807b8df046c, duration=2795.990s, table=2, n_packets=23, n_bytes=2485, idle_age=1355, priority=0,dl_dst=00:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,20)
 cookie=0x49974807b8df046c, duration=2795.989s, table=2, n_packets=92, n_bytes=5316, idle_age=1724, priority=0,dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,22)

br-int发过来的如果是单播包,扔给table20处理 br-int发过来的如果是多播或广播包,扔给table22处理

  • 查看table20,处理来自br-int单播的包
[root@controller opt]# ovs-ofctl dump-flows br-tun |grep "table=20"
 cookie=0x49974807b8df046c, duration=15.750s, table=20, n_packets=17, n_bytes=1610, hard_timeout=300, idle_age=0, hard_age=0, priority=1,vlan_tci=0x0001/0x0fff,dl_dst=fa:16:3e:29:99:6a actions=load:0->NXM_OF_VLAN_TCI[],load:0x6f->NXM_NX_TUN_ID[],output:3
 
 cookie=0x49974807b8df046c, duration=2929.820s, table=20, n_packets=0, n_bytes=0, idle_age=16692, priority=0 actions=resubmit(,22)

第一条规则是table10学习来的结果。内部编号为4(tag=1),目标(ServerB)MAC地址是fa:16:3e:29:99:6a的数据包 处理动作是去掉VLAN号添加VXLAN tunnel ID 0x6f(111),并从port3(tunnel端口 vxlan-c0a8960b)发出 第二条规则是,对于没有学习到规则的数据包扔给table22处理

  • 查看table22
[root@controller /]# ovs-ofctl dump-flows br-tun |grep table=22
 cookie=0x49974807b8df046c, duration=2955.336s, table=22, n_packets=80, n_bytes=4216, idle_age=154, priority=1,dl_vlan=1 actions=strip_vlan,load:0x6f->NXM_NX_TUN_ID[],output:3
 
 cookie=0x49974807b8df046c, duration=3068.476s, table=22, n_packets=11, n_bytes=962, idle_age=2119, priority=0 actions=drop

如果数据包的内部VLAN号为(tag=1),处理动作就是去掉tag标记,添加VXLAN tunnel ID 0x6f(111),并从port3(tunnel端口 vxlan-c0a8960b)转发出去

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 04-OpenStack的命令行管理

    小朋友呢
  • 00-Ansible的简介与安装

    基于 Python paramiko 开发,分布式,无需客户端,轻量级,配置语法使用 YMAL 及 Jinja2模板语言,更强的远程命令执行操作。

    小朋友呢
  • 07-Cinder对接GlusterFs

    小朋友呢
  • awr中DB CPU过低的原因分析(r4笔记第20天)

    前几天在做巡检的时候发现有个库的负载在某一个时间段内极高,高达100倍。一个10分钟的awr报告,得到的db time 却有1000分钟。 Snap Id ...

    jeanron100
  • python测试开发django-18.admin后台中文版

    django的admin后台页面默认是英文的,不喜欢英文的话,可以改下setting.py里面的语言设置,改成中文版的显示

    上海-悠悠
  • python笔记44-HTTP对外接口sign签名

    一般公司对外的接口都会用到sign签名,对不同的客户提供不同的apikey ,这样可以提高接口请求的安全性,避免被人抓包后乱请求。 sign签名是一种很常见的方...

    上海-悠悠
  • 云中漫步,做个公众号方便生活、取悦自己

    随着云服务的日趋完善,有了好的idea,可以方便的基于云服务进行快速尝试,而无需考虑机器、网络等基础设施问题。文本将介绍如何基于腾讯云的云服务,快速、低成本地搭...

    刘卓夫
  • 时间戳转换

    大大大黑白格子
  • Introduction to RenderMonkey

    逍遥剑客
  • Flat风格的Qml滚动选择条

    Qt君

扫码关注云+社区

领取腾讯云代金券