neutron中网络虚拟化技术的应用

声明:
 本博客欢迎转载,但请保留原作者信息!
 作者:柯晓东
 团队:华为杭州OpenStack团队

Neutron依赖的组件多,看起来太麻烦。买了某本珠玑的书,该书字间距太大,唠嗑比较多,知识普及了但不深入。

最后通过看问人、看代码,终于搞通了一点。字不如表,表不如图。下面尽量画图表示。

Neutron将网络按照三层交换机的概念分为:
  Network:隔离的L2域,可以是虚拟、逻辑或交换,同一个网络中的主机彼此L2可见
  Subnet:隔离的L3域,IP地址块。其中每个机器有一个IP,同一个子网的主机彼此L3可见
  Port:相当于交换机的一个物理端口,可以设置IP和MAC

Neutron再为此在数据库里面建了几个表,它本身只管理这些表和下发配置,而把网络配置的活交给各个agent去干了。

和Nova一样,Neutron也定义了很多种的插件来适配不同的网络虚拟化技术。
但纵使Core driver有很多种,我想大家也只会用ML2 driver。因为只有它可以同时使用多种虚拟化技术。
ML2又分为Type Driver和Mechanism Driver。
  Type Drivers:表示Network的方式,类型有这几种local、flat、vlan、vxlan、gre
  Mechanism Drivers:指导Port怎么创建,和网络虚拟化技术相匹配

gre

ovs自动搞定

vxlan

ovs自动搞定

vlan

需要设置交换机

local/flat

不常用

 
在nova那边,libvirt基本把所有的底层事情都做完了,nova只要管调用libvirt就可以了。
Neutron却没有那么幸运,虽然可以靠ovs(openvswitch)控制转发,但是不管各种网桥的初始化。neutron不管为了保证网口可靠性的组bound,也不管为了Host间通讯的交换机的设置。

先上Neutron整体的网络图(点击查看大图)

Neutron只负责linux bridge的创建和配置、ovs网桥(br-int、br-ethx、br-tun)的配置,其他各个部分的创建和配置都要另外自己作。

下面就依次详细介绍各部分:
(1)物理网络类型
该类型对应ML2的Type Drivers,就是数据包出了主机后传送的模式。
flat就是把各个物理口直接用网线将各个主机连起来,这样各个子网就不能隔离。
GRE、Vxlan则是通过软件的方式在同一根网线上传送多个子网的数据包。他们要使用br-tun,这个网桥neutron会自己自动建。这两种组网用的隧道,neutron也会自己建立。有N个主机的话,最大需要建立N*(N-1)条隧道。
Vlan则是使用交换机来隔离多个子网。交换机一般的家里是没有的,而且还要另外配置好交换机的端口,这就导致这种类型的网络很少被使用。

这里顺便说一点交换机的知识。
如上图所示,交换机的接线方式也分3种(untag、tagged、pvid+untag)。其中“tagged”和“untag”的区别如下:










tagged(上图黑圈)

untag(上图白圈)

接收

当数据包本身不包含VLAN的话,输入的数据包就加上该缺省vlan;如果数据包本身已经包含了VLAN,那么就不再添加。

输入的数据包全部都要加上该缺省vlan,不管输入的数据包是否已经有VLAN标记。

发送

如果端口缺省VLAN等于发送的数据包所含的VLAN,那么就会将VLAN标记从发送的数据包中去掉;如果不相等,则数据包将带着VLAN发送出去,实现VLAN的透传。

不管端口缺省VLAN为多少,是否等于要输出的数据包的VLAN,都会将VLAN ID从数据包中去掉。

“pvid+untag”是“untag”的特殊形式,它在untag基础上,再加上了缺省vlan也是当前的vlan。

交换机中有3种不同的类型的网口:
  access 只能接入1个vlan(只能“pvid+untag”一个vlan,不能再和其他vlan有关系了);
  trunk 可以接入1个vlan,再tagged几个vlan(有一个“pvid+untag”的vlan,有N个“tagged”的vlan);
  hybrid 可以接入1个vlan,再tagged或untag几个vlan(有一个“pvid+untag”的vlan,有N个“tagged”的vlan,有M个“untag”的vlan)。该类型网口为我司特有。
典型的交换机中网口和vlan的对应图如下:

无论是什么类型的网口,只要他们在某一个vlan上的接线方式是“pvid+untag”的,他们就可以不加任何处理地互通。特别在pxe安装环境时,是要检测这个条件的。例如现在G0/0/1、G0/0/2、G0/0/3在vlan 1001中均为“pvid+untag”,所以这3台集群在同一个可以pxe安装的vlan内。而G0/0/3和G0/0/4、G0/0/5则不在同一个pxe安装vlan内。

 (2)ovs网桥
除了使用硬直通和软直通,其他的情况都需要使用到openvswitch。ovs是一个高质量的,多层虚拟交换机,它可以实现网络隔离、QoS 配置、流量监控、数据包分析等物理交换网络所具有的功能。
namespace是 Linux 2.6提供一种资源隔离方案。利用namespace后,PID,IPC,Network等系统资源不再是全局性的,而是属于特定的Namespace。每个Namespace还可以有自己独立的根目录。虚拟化曾经基于它做出了轻量级的虚拟化技术lxc,这也是docker的前身。更多namespace请参看http://www.cnblogs.com/lisperl/archive/2012/05/03/2480316.html
ovs的虚拟网络利用namespace,将物理口虚拟成多个虚拟网口,且还让每一个有自己的配置。


如上neutron总图所示,ovs-vsctl主要是管配置的,ovs-ofctl主要控制流表。下面将常用操作汇总一下:

查看信息

ovs-vsctl  show br-int

增删网桥

ovs-vsctl  add-br br-int
ovs-vsctl del-br br-int

处理网桥上的端口
通过网桥联通eth0和eth1

ovs-vsctl  add-port br-int eth0
ovs-vsctl  add-port br-int eth1
ovs-vsctl del-port br-int eth0

通过patch将2个网桥互连

ovs-vsctl  add-port br-int patch1 – set Interface patch1 type=patch – set Interface  patch1 options:peer=patch2
ovs-vsctl add-port br-tun patch2 – set Interface patch2 type=patch – set Interface patch2 options:peer=patch1

添加bond
(将2个网口变成1个来用,提高可靠性)

ovs-vsctl  add-bond br-int bond0 eth1 eth2
ovs-vsctl del-port br-int bond0

添加一个虚拟网口,并设为外部可见的internal类型。
然后通过namespace对其设置ip

ovs-vsctl  add-port br-int tap1 – set Interface tap1 type=internal
ip link set tap1 netns ns1
ip netns exec ns1 ip addr add 192.168.0.102/24 dev tap1
ip netns exec ns1 ip link set tap1 up
ip netns exec ns1 ip link set lo up

设置端口的vlan id

ovs-vsctl  set port tap0 tag=9

添加流表

ovs-ofctl  add-flow br-tun “in_port=2,actions=output:8”
ovs-ofctl add-flow br-tun “in_port=2,dl_type=0x0800,dl_src=00:01:02:03:04:05,nw_src=1.2.3.4,nw_proto=1,tp_src=1,actions=drop”
说明:
    in_port: switch的端口
    dl_src: 源mac地址
    dl_dst:目的mac地址
    dl_type:0x0806是arp packet,0x0800是ip  packet
    nw_src:源ip
    nw_dst:目的ip
    nw_proto:协议类型,dl_type的细分
    tp_src: tcp udp源端口
    tp_dst: tcp udp目的端口
    actions:对应的处理,有drop,resubmit,strip_vlan,set_field等等

删除流表

ovs-ofctl  del-flows br-int

查看流表

ovs-ofctl  dump-flows br-int

 可以看出ovs就像一个虚拟的交换机,能够互连互通多个物理网口,也能够互连互通多个网桥,还可以像物理交换机一样控制报文的转发或丢弃、给报文加vlan标签或剥离vlan标签。
通过使用ovs-ofctl查看openstack环境上的br-tun,我们可以大体了解ovs是怎么通过流表来控制报文的走向的:
ovs-ofctl dump-flows br-tun

cookie=0x0, duration=19596.862s, table=0, n_packets=344, n_bytes=66762, idle_age=4, priority=1,in_port=1 actions=resubmit(,1)
cookie=0x0, duration=19537.588s, table=0, n_packets=625, n_bytes=125972, idle_age=4, priority=1,in_port=2actions=resubmit(,2)
cookie=0x0, duration=19596.602s, table=0, n_packets=2, n_bytes=140, idle_age=19590, priority=0 actions=drop
cookie=0x0, duration=19596.343s, table=1, n_packets=323, n_bytes=65252, idle_age=4, priority=0,dl_dst=00:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,20)
cookie=0x0, duration=19596.082s, table=1, n_packets=21, n_bytes=1510, idle_age=5027, priority=0,dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,21)
cookie=0x0, duration=9356.289s, table=2, n_packets=625, n_bytes=125972, idle_age=4, priority=1,tun_id=0x1 actions=mod_vlan_vid:1,resubmit(,10)
cookie=0x0, duration=19595.821s, table=2, n_packets=0, n_bytes=0, idle_age=19595, priority=0 actions=drop
cookie=0x0, duration=19595.554s, table=3, n_packets=0, n_bytes=0, idle_age=19595, priority=0 actions=drop
cookie=0x0, duration=19595.292s, table=10, n_packets=625, n_bytes=125972, idle_age=4, priority=1 actions=learn(table=20,hard_timeout=300,priority=1,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:NXM_OF_IN_PORT[]),output:1
cookie=0x0, duration=9314.338s, table=20, n_packets=323, n_bytes=65252, hard_timeout=300, idle_age=4, hard_age=3, priority=1,vlan_tci=0x0001/0x0fff,dl_dst=fa:16:3e:cb:11:f6 actions=load:0->NXM_OF_VLAN_TCI[],load:0x1->NXM_NX_TUN_ID[],output:2
cookie=0x0, duration=19595.026s, table=20, n_packets=0, n_bytes=0, idle_age=19595, priority=0 actions=resubmit(,21)
cookie=0x0, duration=9356.592s, table=21, n_packets=9, n_bytes=586, idle_age=5027, priority=1,dl_vlan=1actions=strip_vlan,set_tunnel:0x1,output:2
cookie=0x0, duration=19594.759s, table=21, n_packets=12, n_bytes=924, idle_age=5057, priority=0 actions=drop

画成图就是:
 
另外连接2个网桥的方式,大家一般都会把使用ovs的patch和linux的veth来比较。由于ovs的patch的性能比veth高多了,所以我们只选择ovs的patch。
详细的ovs操作手册,请看http://www.pica8.org/document/picos-1.6-ovs-configuration-guide.pdf

(3)linux网桥
linux(brctl)+ iptables 能够实现和上面的ovs类似的功能,即:创建虚拟网桥,再控制报文的转发或丢弃。
那么为什么有了ovs之后,openstack还要引入这2个东西呢?原因是iptables的配置更灵活,很容易实现针对某个子网配置规则,而ovs却很难做到这样的流控操作。
openstack用他们2个来实现了安全组。

下面是brctl的常用命令

添加网桥

brctl  addbr br

添加网口

brctl  addif br eth0
ifconfig eth0 0.0.0.0

为网桥添加ip

ifconfig  br 10.0.0.1 netmask 255.255.0.0 up

删除网口

brctl  delif br eth0

设置网口转发延迟时间

brctl  setfd br 0

暂停网桥

brctl  stp bridge off

查看网桥mac

brctl  showmacs br

删除网桥

brctl  delbr br

下面说一下iptables,它是老牌的控制报文转发的工具。由于有namespace,iptables就可以只针对某个namespace(虚拟机范围)来指定规则,这样它就演化为了虚拟机的安全组(防火墙)。下面是iptables内的报文处理路径,报文只有经过它的过滤后,才会到“应用程序”这边,程序才能收到报文。


iptables的常用命令如下:

列出所有规则

iptables-save 

列出filter表的规则

iptables -L -n

清除所有规则

iptables  -F

不允许连接21端口

iptables  -A INPUT -i eth0 -p tcp –dport 21 -j DROP

允许连接8080端口

iptables  -A INPUT -i eth0 -p tcp dport 8080 -j ACCEPT

将80端口映射到8080

iptables  -t nat -A PREROUTING -p tcp –dport 80 -j REDIRECT –to-ports 8080

了解iptables最好的办法就是看一个例子,那么动手用ping命令,然后获取iptables的日志就好明白了。
为了获取日志,首先需要打开iptables的调试开关,通过trace把日志记录下来。

  1. iptables -t raw -A OUTPUT -p icmp -j TRACE  
  2. iptables -t raw -A PREROUTING -p icmp -j TRACE  
  3. modprobe ipt_LOG  
iptables -t raw -A OUTPUT -p icmp -j TRACE 
iptables -t raw -A PREROUTING -p icmp -j TRACE
modprobe ipt_LOG
这样运行ping命令后,就可以在 /var/log/firewall 下面看到iptables的日志。
通过下面的方法可以关闭trace
  1. iptables -t raw -F  
  2. modprobe ipt_LOG  
iptables -t raw -F 
modprobe ipt_LOG

(4)硬直通和软直通
把物理口组成网桥,固然方便了管理,但是经过网桥转发,报文的转发性能会降低1/6。为了避免转发性能的消耗,intel等硬件厂商搞出特殊的网卡。这些网卡(82599、mellonax等),一个物理网卡能虚拟出63个VF。每个VF就好像一个独立的物理网卡一样,通过将VF直接挂到虚拟机上,实现报文转发对比真实物理网卡几乎不下降。这就是所谓的硬直通。相对的,也有一套类似的用软件实现的直通,即netmap方式。

这两种方式都是直接将VF挂给虚拟机,不通过虚拟网桥(为了提升性能),因此本来在iptables、ovs上的隔离就用不到了,他们的网络隔离只能靠交换机划vlan。

 (5)问题定位常用命令























给arp表添加一项

arp  -s [IP] [MAC]

给arp表删除一项

arp  -d [IP]

查看是否有ip冲突

arping  -A -U -I eth0 192.168.0.1

通过指定port获取dhcp

dhcpcd  eth0

添加路由

ip  route add 10.0.0/24 via 192.168.0.1

添加路由

route  add -net 192.168.1.0 netmask 255.255.255.0 dev eth0

添加默认网关

route  add default gw mango-gw

删除默认网关

route  del default  gw 192.168.1.3

查看本机打开的端口

netstat  -nap

抓起指定节点的数据包

tcpdump  -i eth0 dst host 192.168.0.1

获取210.27.48.1的telnet包

tcpdump  tcp port 23 host 210.27.48.1


 (6)Nova创建虚拟机时怎么创建虚拟网口的
下面通过分析创建虚拟机的流程(点击查看大图)、brctl、iptables的过程连起来。

 

从上述调用栈可以看出,neutron-sever就只干了添加数据库的事情,nova这边调用brctl和ovs-vsctl创建真正的port,ovs-agent定期刷新后作绑定。

进一步,为了让hostos能够直接登陆虚拟机,我们可以通过在ovs网桥挂port的方式来实现。

首先先通过nova show查找虚拟机名

  1. nova show 1229782a-6ecd-4bb2-bdec-34b5d61fe19e |grep instance  
  2. | OS-EXT-SRV-ATTR:instance_name        | instance-00000002                                        |  
nova show 1229782a-6ecd-4bb2-bdec-34b5d61fe19e |grep instance 
| OS-EXT-SRV-ATTR:instance_name | instance-00000002 |

然后用libvrit查找对应的tap口

  1. virsh dumpxml instance-00000002 |grep tap  
  2.       <target dev=‘tap937f3ad2-d5’/>  
virsh dumpxml instance-00000002 |grep tap 
<target dev='tap937f3ad2-d5'/>

再用ovs-vsctl查看对应的tag信息

  1. Port “qvo937f3ad2-d5”  
  2.     tag: 1  
  3.     Interface “qvo937f3ad2-d5”  
        Port "qvo937f3ad2-d5" 
tag: 1
Interface "qvo937f3ad2-d5"

知道tag后,我们创建一个port带上对应的tag号即可和虚拟机通

  1. ovs-vsctl  add-port br-int mytap – set Interface mytap type=internal  
  2. ovs-vsctl set Port mytap tag=1  
  3. ifconfig mytap 10.10.10.16  
ovs-vsctl  add-port br-int mytap -- set Interface mytap type=internal 
ovs-vsctl set Port mytap tag=1
ifconfig mytap 10.10.10.16

接着查询port使用的安全组uuid

  1. root@openstack:~# neutron port-list |grep 10.10.10.2  
  2. | 937f3ad2-d57b-40c0-8291-4941d2b4315b |      | fa:16:3e:fb:3b:0c | {“subnet_id”                                                      : “cde61131-8314-4714-aa74-dab47469690a”, “ip_address”: “10.10.10.2”} |  
  3.   
  4. root@openstack:~# neutron port-show 937f3ad2-d57b-40c0-8291-4941d2b4315b |grep security  
  5. | security_groups       | f7e0465d-729d-46e1-9cd0-e7f0658330d2                                              |  
root@openstack:~# neutron port-list |grep 10.10.10.2 
| 937f3ad2-d57b-40c0-8291-4941d2b4315b | | fa:16:3e:fb:3b:0c | {“subnet_id” : “cde61131-8314-4714-aa74-dab47469690a”, “ip_address”: “10.10.10.2”} |

root@openstack:~# neutron port-show 937f3ad2-d57b-40c0-8291-4941d2b4315b |grep security
| security_groups | f7e0465d-729d-46e1-9cd0-e7f0658330d2 |


最后再允许ssh和ping通过

  1. neutron security-group-rule-create –protocol icmp –direction ingress f7e0465d-729d-46e1-9cd0-e7f0658330d2  
  2. neutron security-group-rule-create –protocol tcp –port-range-min 22 –port-range-max 22 –direction ingress f7e0465d-729d-46e1-9cd0-e7f0658330d2  
neutron security-group-rule-create --protocol icmp --direction ingress f7e0465d-729d-46e1-9cd0-e7f0658330d2 
neutron security-group-rule-create --protocol tcp --port-range-min 22 --port-range-max 22 --direction ingress f7e0465d-729d-46e1-9cd0-e7f0658330d2

这样就可以直接从HostOS登虚拟机了

  1. root@openstack:~# ssh cirros@10.10.10.2  
  2. cirros@10.10.10.2’s password:  
  3. $ ls  
root@openstack:~# ssh cirros@10.10.10.2 
cirros@10.10.10.2’s password:
$ ls

原地址:https://blog.csdn.net/canxinghen/article/details/46761591

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值