声明:
本博客欢迎转载,但请保留原作者信息!
作者:柯晓东
团队:华为杭州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 add-port br-int eth0 |
通过patch将2个网桥互连 |
ovs-vsctl add-port br-int patch1 – set Interface patch1 type=patch – set Interface patch1 options:peer=patch2 |
添加bond |
ovs-vsctl add-bond br-int bond0 eth1 eth2 |
添加一个虚拟网口,并设为外部可见的internal类型。 |
ovs-vsctl add-port br-int tap1 – set Interface tap1 type=internal |
设置端口的vlan id |
ovs-vsctl set port tap0 tag=9 |
添加流表 |
ovs-ofctl add-flow br-tun “in_port=2,actions=output:8” |
删除流表 |
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 |
为网桥添加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把日志记录下来。
- iptables -t raw -A OUTPUT -p icmp -j TRACE
- iptables -t raw -A PREROUTING -p icmp -j TRACE
- 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
- iptables -t raw -F
- 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查找虚拟机名
- nova show 1229782a-6ecd-4bb2-bdec-34b5d61fe19e |grep instance
- | 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口
- virsh dumpxml instance-00000002 |grep tap
- <target dev=‘tap937f3ad2-d5’/>
virsh dumpxml instance-00000002 |grep tap
<target dev='tap937f3ad2-d5'/>
再用ovs-vsctl查看对应的tag信息
- Port “qvo937f3ad2-d5”
- tag: 1
- Interface “qvo937f3ad2-d5”
Port "qvo937f3ad2-d5"
tag: 1
Interface "qvo937f3ad2-d5"
知道tag后,我们创建一个port带上对应的tag号即可和虚拟机通
- 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
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
- 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 |
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通过
- 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
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登虚拟机了
- root@openstack:~# ssh [email protected]
- [email protected]’s password:
- $ ls
root@openstack:~# ssh [email protected]
[email protected]’s password:
$ ls
原地址:https://blog.csdn.net/canxinghen/article/details/46761591