Neutron 的设计目标是实现“网络即服务”,为了达到这一目标,在设计上遵循了基于“软件定义网络”实现网络虚拟化的原则,在实现上充分利用了 Linux 系统上的各种网络相关的技术
涉及的linux网络技术如下:
bridge:网桥,Linux中用于表示一个能连接不同网络设备的虚拟设备,linux中传统实现的网桥类似一个hub设备,而ovs管理的网桥一般类似交换机。
br-int:bridge-integration,综合网桥,常用于表示实现主要内部网络功能的网桥。
br-ex:bridge-external,外部网桥,通常表示负责跟外部网络通信的网桥。
GRE:General Routing Encapsulation,一种通过封装来实现隧道的方式。在openstack中一般是基于L3的gre,即original pkt/GRE/IP/Ethernet
VETH:虚拟ethernet接口,通常以pair的方式出现,一端发出的网包,会被另一端接收,可以形成两个网桥之间的通道。
qvb:neutron veth, Linux Bridge-side
qvo:neutron veth, OVS-side
TAP设备:模拟一个二层的网络设备,可以接受和发送二层网包。
TUN设备:模拟一个三层的网络设备,可以接受和发送三层网包。
iptables:Linux 上常见的实现安全策略的防火墙软件。
Vlan:虚拟 Lan,同一个物理 Lan 下用标签实现隔离,可用标号为1-4094。
VXLAN:一套利用 UDP 协议作为底层传输协议的 Overlay 实现。一般认为作为 VLan 技术的延伸或替代者。
namespace:用来实现隔离的一套机制,不同 namespace 中的资源之间彼此不可
以neutron的gre模式为例,简化示意如下
一、命名空间
在 Linux 中,命名空间(namespace)可以被认为是隔离的拥有单独网络栈(网卡、路由转发表、iptables)的环境。网络名字空间经常用来隔离网络设备和服务,只有拥有同样网络名字空间的设备,才能看到彼此。
可以用ip netns list命令来查看已经存在的名字空间。
ip net list
qdhcp开头的名字空间是dhcp服务器使用的,qrouter开头的则是router服务使用的。 可以通过 ip netns exec namespaceid command 来在指定的网络名字空
间中执行网络命令,例如
ip netns exec qdhcp-3bb9ca55-d2e5-45eb-b782-e4de1f60014a ip addr
可以看到,dhcp服务的网络命名空间只有有一个网络接口"aa08fc00-39",它通过"tapa08fc00-39"连接到br-int上。
1.1DHCP服务
dhcp服务是通过dnsmasq进程(轻量级服务器,可以提供dns、dhcp、tftp等服务)来实现的,该进程绑定到dhcp名字空间中的br-int的接口上。可以查看相关的进程
例如查询”qdhcp-3bb9ca55-d2e5-45eb-b782-e4de1f60014a“的服务进程
ps -ef |grep 3bb9ca55-d2e5-45eb-b782-e4de1f60014a
此dhcp服务,主要是给租户私有网络提供dhcp服务,在openstack的dashboard显示如下:
2.1 路由服务
router是提供跨 subnet 的互联功能的。比如用户的内部网络中主机想要访问外部互联网的地址,就需要router来转发(因此,所有跟外部网络的流量都必须经过router)。目前router的实现是通过iptables进行的。
同样的,router服务也运行在自己的名字空间中,可以通过如下命令查看:
ip netns exec qrouter-014e0e10-47fc-469f-9883-3a5130fc79e6 ip addr
可以看出,该名字空间中包括两个网络接口。
第一个接口 qr-d1a40252-8b(192.168.1.1/24)跟 br-int 上的接口相连。即任何从 br-int 来的找 192.168.1.0/24 (租户的私有网段)的网包都会到达这个接口。
第一个接口 qg-2fe564e2-cd 连接到 br-ex 上的接口,即任何从外部来的网包,询问 172.31.208.102(默认的静态 NAT 外部地址)或 172.31.208.110(租户申请的
floating IP 地址),都会到达这个接口。
在dashboard上也可以看到
查看该名字空间中的路由表
ip netns exec qrouter-014e0e10-47fc-469f-9883-3a5130fc79e6 ip route
默认情况,以及访问外部网络的时候,休会从 qg-xxx 接口发出,经过 br-ex 发布到
外网。访问租户内网的时候,会从 qr-xxx 接口发出,发给 br-int
查看路由的snat和dnat规则
ip netns exec qrouter-014e0e10-47fc-469f-9883-3a5130fc79e6 iptables -t nat -S
其中SNAT和DNAT规则完成外部 floating ip (172.31.208.110)到内部ip(192.168.1.17) 的映射
另外有一条SNAT规则把所有其他的内部IP出来的流量都映射到外部IP172.31.208.102。这样即使在内部虚拟机没有外部浮动IP的情况下,也可以发起对外网的访
问
二、安全组
Security group通过Linux IPtables来实现,为此,在控制节点上引入了qbr*这样的Linux传统bridge(iptables规则目前无法加载到直接挂在到ovs的tap设备上)。 首先在控制节点上用neutron port-list命令列出虚拟机的端口id
neutron port-list
其中id的前10位数字被用作虚机对外连接的qbr(同时也是tap口)的id。i或o加上前9位数字被用作安全组chain的id。
所有的规则默认都在Compute节点上的filter表(默认表)中实现,分别来查看filter表的INPUT、OUTPUT、FORWARD三条链上的规则。
在Compute节点上,可以用 iptables --line-numbers -vnL [CHAIN] 来获得filter表(可以指定某个链上的)规则。
2.1INPUT
iptables --line-numbers -vnL INPUT
可以看到,跟安全组相关的规则被重定向到neutron-openvswi-INPUT。 查看其规则,只有一条
iptables --line-numbers -vnL neutron-openvswi-INPUT
重定向到neutron-openvswi-ocleef425-c
iptables --line-numbers -vnL neutron-openvswi-oc1eef425-c
如果是vm发出的dhcp请求,直接通过,否则转到neutron-openvswi-ocleef424-c
2.2 OUTPUT
iptables --line-numbers -vnL OUTPUT
分别跳转到neutron-filter-top和neutron-openvswi-OUTPUT。
iptables --line-numbers -vnL neutron-filter-top
neutron-filter-top链是跳转到neutron-openvswi-local。
查看neutron-openvswi-OUTPUT
iptables --line-numbers -vnL neutron-openvswi-OUTPUT
可以看到 output 链无规则
同时查看neutron-openvswi-local链规则
iptables --line-numbers -vnL neutron-openvswi-local
可以看到neutron-oenvswi-local链也是无规则
2.3 FORWARD
FORWARD chain上主要实现安全组的功能。用户在配置缺省安全规则时候(例如允许ssh到vm,允许ping到vm),影响该chain
iptables --line-numbers -vnL FORWARD
同样跳转到neutron-filter-top,无规则。跳转到neutron-openvswi-FORWARD。
iptables --line-numbers -vnL neutron-openvswi-FORWARD
neutron-openvswi-FORWARD将匹配所有进出tapcleef425端口的流量。
iptables --line-numbers -vnL neutron-openvswi-sg-chain
如果是网桥从tap-cleef425端口发出到VM的流量,则跳转到neutron-openvswi-icleef425-c;如果是从tap-cleef425端口进入到网桥的(即vm发出来的)流量,则跳转到neutron-openvswi-ocleef425。
iptables --line-numbers -vnL neutron-openvswi-ic1eef425-c
neutron-openvswi-icleef425-c允许安全组中配置的策略(允许ssh、ping等)和dhcp reply通过。默认的neutron-openvswi-sg-fallback将drop所有流量。
可以看到,还有一个编号为4的规则,是允许tcp协议的目的端口22,这个就是我们开放的端口组进行ssh协议使用22端口进行登陆
iptables --line-numbers -vnL neutron-openvswi-oc1eef425-c
neutron-openvswi-ocleef425-c将跳转到neutron-openvswi-scleef425-c,允许DHCP Request和匹配VM的源IP和源MAC的流量通过。
2.4整体逻辑
整体逻辑如下所示:
2.5 快速查找安全组规则
从前面分析可以看出,某个vm的安全组相关规则的chain的名字,跟vm的id的前9个字符有关。因此,要快速查找qbr-XXX上相关的iptables规则,可以用iptables -S列出(默认是
filter表)所有链上的规则,其中含有id的链即为虚拟机相关的安全组规则。其中--physdev-in表示即将进入某个网桥的端口,--physdev-out表示即将从某个网桥端口发出
iptables -S |grep tapc1eef425-c0
可以看出,进出tap-cleef425-c0 口的FORWARD链上的流量都被扔到了neutron-openvswi-sg-chain这个链,neutron-openvswi-sg-chain上是security group具体的实现(两条
规则,访问虚拟机的流量扔给neutron-openvswi-icleef425-c;从虚拟机出来的扔给neutron-openvswi-ocleef4250-c。