2019独角兽企业重金招聘Python工程师标准>>>

原文地址: https://blogs.oracle.com/ronen/entry/diving_into_openstack_network_architecture1

在上一篇文章中,我们了解了几个网络组件,如openvswitch/network namespace/Linux bridges/veth pairs。这篇文章中,我们将用3个简单的use case,展示这些基本网络组件如何以工作从而实现openstack的SDN方案。
在这些use case中,我们会了解整个网络配置和他们如何一起运行。use case如下:

  1. 创建网络——我们创建网络时,发生了什么。如何创建多个隔离的网络。
  2. 创建虚拟机——一旦我们有了网络,我们可以创建虚拟机并将其接入网络。
  3. 虚拟机的DHCP请求——opensack可以自动为虚拟机配置IP。通过openstack neutron控制的DHCP服务完成。我们来了解这个服务如何运行,DHCP请求和回应是什么样子的?

这篇文章中,我们会展示网络连接的原理,我们会了解网络包如何从A到B。我们先了解已经完成的网络配置是什么样子的?然后我们讨论这些网络配置是如何以及何时创建的?我个人认为,通过例子和具体实践看到真实的网络接口如何工作以及如何将他们连接起来是非常有价值的。然后,一切真相大白,我们知道网络连接如何工作,在后边的文章中,我将进一步解释neutron如何配置这些组件,从而提供这样的网络连接能力。

我推荐在你自己的环境上尝试这些例子或者使用Oracle Openstack Tech Preview。完全理解这些网络场景,对我们调查openstack环境中的网络问题非常有帮助。

Use case #1: Create Network

创建network的操作非常简单。我们可以使用GUI或者命令行完成。openstack的网络仅供创建该网络的租户使用。当然如果这个网络是“shared”,它也可以被其他所有租户使用。一个网络可以有多个subnets,但是为了演示目的和简单,我们仅为每一个network创建一个subnet。通过命令行创建network:

# neutron net-create net1Created a new network:+---------------------------+--------------------------------------+| Field                     | Value                                |+---------------------------+--------------------------------------+| admin_state_up            | True                                 || id                        | 5f833617-6179-4797-b7c0-7d420d84040c || name                      | net1                                 || provider:network_type     | vlan                                 || provider:physical_network | default                              || provider:segmentation_id  | 1000                                 || shared                    | False                                || status                    | ACTIVE                               || subnets                   |                                      || tenant_id                 | 9796e5145ee546508939cd49ad59d51f     |+---------------------------+--------------------------------------+

为这个network创建subnet::

# neutron subnet-create net1 10.10.10.0/24Created a new subnet:+------------------+------------------------------------------------+| Field            | Value                                          |+------------------+------------------------------------------------+| allocation_pools | {"start": "10.10.10.2", "end": "10.10.10.254"} || cidr             | 10.10.10.0/24                                  || dns_nameservers  |                                                || enable_dhcp      | True                                           || gateway_ip       | 10.10.10.1                                     || host_routes      |                                                || id               | 2d7a0a58-0674-439a-ad23-d6471aaae9bc           || ip_version       | 4                                              || name             |                                                || network_id       | 5f833617-6179-4797-b7c0-7d420d84040c           || tenant_id        | 9796e5145ee546508939cd49ad59d51f               |+------------------+------------------------------------------------+

现在我们有了一个network和subnet,网络拓扑像这样:

现在让我们深入看下到底发生了什么?在控制节点,我们一个新的namespace被创建:

# ip netns listqdhcp-5f833617-6179-4797-b7c0-7d420d84040c

这个namespace的名字是qdhcp- (参见上边),让我们深入namespace中看看有什么?

# ip netns exec qdhcp-5f833617-6179-4797-b7c0-7d420d84040c ip addr1: lo:  mtu 65536 qdisc noqueue state UNKNOWNlink/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host loinet6 ::1/128 scope hostvalid_lft forever preferred_lft forever12: tap26c9b807-7c:  mtu 1500 qdisc noqueue state UNKNOWNlink/ether fa:16:3e:1d:5c:81 brd ff:ff:ff:ff:ff:ffinet 10.10.10.3/24 brd 10.10.10.255 scope global tap26c9b807-7cinet6 fe80::f816:3eff:fe1d:5c81/64 scope linkvalid_lft forever preferred_lft forever

我们发下在namespace下有两个网络接口,一个是loop设备,另一个叫“tap26c9b807-7c”。这个接口设置了IP地址10.10.10.3,他会接收dhcp请求(后边会讲)。接下来我们来跟踪下“tap26c9b807-7c”的网络连接性。我们从OVS上看下这个接口所连接的OVS网桥"br-int"。

# ovs-vsctl show
8a069c7c-ea05-4375-93e2-b9fc9e4b3ca1Bridge "br-eth2"Port "br-eth2"Interface "br-eth2"type: internalPort "eth2"Interface "eth2"Port "phy-br-eth2"Interface "phy-br-eth2"Bridge br-exPort br-exInterface br-extype: internalBridge br-intPort "int-br-eth2"Interface "int-br-eth2"Port "tap26c9b807-7c"tag: 1Interface "tap26c9b807-7c"type: internalPort br-intInterface br-inttype: internalovs_version: "1.11.0"

由上可知,veth pair的两端“int-br-eth2” 和 "phy-br-eth2",这个veth pari连接两个OVS网桥"br-eth2"和"br-int"。上一篇文章中,我们解释过如何通过ethtool命令查看veth pairs的两端。就如下边的例子:

# ethtool -S int-br-eth2
NIC statistics:peer_ifindex: 10
.
.#ip link
.
.
10: phy-br-eth2:  mtu 1500 qdisc pfifo_fast state UP qlen 1000
.
.

注意“phy-br-eth2”连接到网桥"br-eth2",这个网桥的一个网口是物理网卡eth2。这意味着我们创建的网络创建了一个连接到了物理网卡eth2的namespace。eth2所在的虚拟机网络会连接所有的虚拟机的。

关于网络隔离:

Openstack支持创建多个隔离的网络,也可以使用多种机制完成网络间的彼此隔离。这些隔离机制包括VLANs/VxLANs/GRE tunnels,这个在我们部署openstack环境时配置。本文中我们选择了VLANs。当使用VLAN标签作为隔离机制,Neutron会从预定义好的VLAN池中选择一个VLAN标签,并分配给一个新创建的network。通过分配VLAN标签给network,Neutron允许在一个物理网卡上创建多个隔离的网络。与其他的平台的最大的区别是,用户不需要负责管理VLAN如何分配给networks。Neutron会负责管理分配VLAN标签,并负责回收。在我们的例子中,net1使用VLAN标签1000,这意味着连接到该网络的虚拟机,发出的包会被打上VLAN标签1000然后发送到物理网络中。对namespace也是同样的,如果我们希望namespace连接到某个特定网络,我们需要确保这个namespace发出的/接收的包被正确的打上了标签。

在上边的例子中,namespace中的网络接口“tap26c9b807-7c”被分配了VLAN标签1。如果我们从OVS观察下,会发现VLAN1会被改为VLAN1000,当包进入eth2所在的uxniji网络。反之亦然。我们通过OVS的dump-flows命令可以看到进入虚拟机网络的网络包在br-eth2上进行了VLAN标签的修改:

#  ovs-ofctl dump-flows br-eth2
NXST_FLOW reply (xid=0x4):cookie=0x0, duration=18669.401s, table=0, n_packets=857, n_bytes=163350, idle_age=25, priority=4,in_port=2,dl_vlan=1 actions=mod_vlan_vid:1000,NORMALcookie=0x0, duration=165108.226s, table=0, n_packets=14, n_bytes=1000, idle_age=5343, hard_age=65534, priority=2,in_port=2 actions=dropcookie=0x0, duration=165109.813s, table=0, n_packets=1671, n_bytes=213304, idle_age=25, hard_age=65534, priority=1 actions=NORMAL

从网络接口到namespace我们看到VLAN标签的修改如下:

#  ovs-ofctl dump-flows br-int
NXST_FLOW reply (xid=0x4):cookie=0x0, duration=18690.876s, table=0, n_packets=1610, n_bytes=210752, idle_age=1, priority=3,in_port=1,dl_vlan=1000 actions=mod_vlan_vid:1,NORMALcookie=0x0, duration=165130.01s, table=0, n_packets=75, n_bytes=3686, idle_age=4212, hard_age=65534, priority=2,in_port=1 actions=dropcookie=0x0, duration=165131.96s, table=0, n_packets=863, n_bytes=160727, idle_age=1, hard_age=65534, priority=1 actions=NORMAL

总之,当用户创建network,neutrong会创建一个namespace,这个namespace通过OVS连接到虚拟机网络。OVS还负责namespace与虚拟机网络之间VLAN标签的修改。现在,让我们看下创建虚拟机时,发生了什么?虚拟机是怎么连接到虚拟机网络的?

Use case #2: Launch a VM

从Horizon或者命令行创建并启动一个虚拟机,下图是从Horzion创建的例子:

挂载网络并启动虚拟机:


一旦虚拟机启动并运行,我们发下nova支持给虚拟机绑定IP:

# nova list
+--------------------------------------+--------------+--------+------------+-------------+-----------------+
| ID                                   | Name         | Status | Task State | Power State | Networks        |
+--------------------------------------+--------------+--------+------------+-------------+-----------------+
| 3707ac87-4f5d-4349-b7ed-3a673f55e5e1 | Oracle Linux | ACTIVE | None       | Running     | net1=10.10.10.2 |
+--------------------------------------+--------------+--------+------------+-------------+-----------------+

nova list命令显示虚拟机在运行中,并被分配了IP 10.10.10.2。我们通过虚拟机定义文件,查看下虚拟机与虚拟机网络之间的连接性。虚拟机的配置文件在目录/var/lib/nova/instances//下可以找到。通过查看虚拟机定义文件,libvirt.xml,我们可以看到虚拟机连接到网络接口“tap53903a95-82”,这个网络接口连接到了Linux网桥 “qbr53903a95-82”:

<interface type="bridge"><mac address="fa:16:3e:fe:c7:87"/><source bridge="qbr53903a95-82"/><target dev="tap53903a95-82"/></interface>

通过brctl查看网桥信息如下:

# brctl show
bridge name     bridge id               STP enabled     interfaces
qbr53903a95-82          8000.7e7f3282b836       no              qvb53903a95-82tap53903a95-82

网桥有两个网络接口,一个连接到虚拟机(“tap53903a95-82 “),另一个( “qvb53903a95-82”)连接到OVS网桥”br-int"。

# ovs-vsctl show
83c42f80-77e9-46c8-8560-7697d76de51cBridge "br-eth2"Port "br-eth2"Interface "br-eth2"type: internalPort "eth2"Interface "eth2"Port "phy-br-eth2"Interface "phy-br-eth2"Bridge br-intPort br-intInterface br-inttype: internalPort "int-br-eth2"Interface "int-br-eth2"Port "qvb53903a95-82"tag: 3Interface "qvb53903a95-82"ovs_version: "1.11.0"

我们之前看过,OVS网桥“br-int"连接到"br-eth2",通过veth pair(int-br-eth2,phy-br-eth2 ),br-eth2连接到物理网卡eth2。整个流入如下:

VM  ->  tap53903a95-82 (virtual interface)  ->  qbr53903a95-82 (Linux bridge)  ->  qvb53903a95-82 (interface connected from Linux bridge to OVS bridge br-int)  ->  int-br-eth2 (veth one end)  ->  phy-br-eth2 (veth the other end)  ->  eth2 physical interface.

与虚拟机相连的Linux bridage主要用于基于Iptables的安全组设置。安全组用于对虚拟机的网络隔离进行增强,由于iptables不能用于OVS网桥,因此我们使用了Linux网桥。后边我们会看到Linux网桥的规则设置。

VLAN tags:我们在第一个use case中提到过,net1使用VLAN标签1000,通过OVS我们看到qvo41f1ebcf-7c使用VLAN标签3。VLAN标签从3到1000的转换在OVS中完成,通过br-eth2中实现。 总结如下,虚拟机通过一组网络设备连入虚拟机网络。虚拟机和网络之间,VLAN标签被修改。

Use case #3: Serving a DHCP request coming from the virtual machine

之前的use case中,我们看到了一个叫dhcp-的namespace和虚拟机,两者最终连接到物理网络eth2。他们都会被打上VLAN标签1000。我们看到该namespace中的网络接口使用IP 10.10.10.3。因为虚拟机和namespace彼此连接并在相同子网,因此可以ping到对方。如下图,虚拟机中网络接口被分配了IP 10.10.10.2,我们尝试ping namespace中的网络接口的IP:

namespace与虚拟机之间连通,并且可以互相ping通,对于定位问题非常有用。我们可以从虚拟机ping通namespace,可以使用tcpdump或其他工具定位网络中断问题。

为了响应虚拟机的dhcp请求,Neutron使用了”dnsmasq“的Linux工具,这个工具是一个轻量的DNS、DHCP服务,更多的信息请查看(http://www.thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html)。我们可以在控制节点通过PS命令看到:

dnsmasq --no-hosts --no-resolv --strict-order --bind-interfaces --interface=tap26c9b807-7c --except-interface=lo --pid-file=/var/lib/neutron/dhcp/5f833617-6179-4797-b7c0-7d420d84040c/pid --dhcp-hostsfile=/var/lib/neutron/dhcp/5f833617-6179-4797-b7c0-7d420d84040c/host --dhcp-optsfile=/var/lib/neutron/dhcp/5f833617-6179-4797-b7c0-7d420d84040c/opts --leasefile-ro --dhcp-range=tag0,10.10.10.0,static,120s --dhcp-lease-max=256 --conf-file= --domain=openstacklocal

DHCP服务在namespace中连接到了一个tap接口(“--interface=tap26c9b807-7c”),从hosts文件我们可以看到:

# cat  /var/lib/neutron/dhcp/5f833617-6179-4797-b7c0-7d420d84040c/host
fa:16:3e:fe:c7:87,host-10-10-10-2.openstacklocal,10.10.10.2

之前的console输出可以看到虚拟机MAC为fa:16:3e:fe:c7:87 。这个mac地址与IP 10.10.10.2 关联,当包含该MAC的DHCP请求到达,dnsmasq返回10.10.10.2。在这个初始过程(可以重启网络服务触发)中从namespace中看,可以看到如下的DHCP请求:

# ip netns exec qdhcp-5f833617-6179-4797-b7c0-7d420d84040c tcpdump -n
19:27:12.191280 IP 0.0.0.0.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from fa:16:3e:fe:c7:87, length 310
19:27:12.191666 IP 10.10.10.3.bootps > 10.10.10.2.bootpc: BOOTP/DHCP, Reply, length 325

总之,DHCP服务由dnsmasq提供,这个服务由Neutron配置,监听在DHCP namespace中的网络接口上。Neutron还配置dnsmasq中的MAC/IP映射关系,所以当DHCP请求时会受到分配给它的IP。

总结

本文,我们基于之前讲解的各种网络组件,分析了三种use case下网络如何连通的。这些use cases对了解整个网络栈以及了解虚拟机/计算节点/DHCP namespace直接如何连通很有帮助。
根据我们的分析,我们确信启动虚拟机、虚拟机发出DHCP请求、虚拟机收到正确的IP后这个网络按照我们预想的工作。我们看到一个包经过一长串路径最终到达目的地,如果这一切成功,意味着这些组件功能正常。
下一篇文章中,我们会学习更复杂的neutron服务并分析他们如何工作。

转载于:https://my.oschina.net/u/2381034/blog/477269

深入理解openstack网络架构(2)----Basic Use Cases相关推荐

  1. 一文理解OpenStack网络

    摘要:如果你能理解OpenStack的网络,那么对于其他云平台的网络,应该也可以通过分析后理解掌握了. 本文分享自华为云社区<<跟唐老师学习云网络> - OpenStack网络实现& ...

  2. openstack的逻辑概念_基本概念 - 深入理解 OpenStack 网络实现 Neutron

    Neutron管理下面的实体: 网络:隔离的 L2 域,可以是虚拟.逻辑或交换. 子网:隔离的 L3 域,IP 地址块.其中每个机器有一个 IP,同一个子网的主机彼此 L3 可见. 端口:网络上虚拟. ...

  3. 深入理解 Neutron -- OpenStack 网络实现(2):VLAN 模式

    问题导读 1.br-int.br-ethx的作用是什么? 2.安全组策略是如何实现的? 3.VLAN 模式与GRE模式有哪些不同点?流量上有哪些不同? 4.L3 agent实现了什么功能? 接上篇深入 ...

  4. 深入理解OpenStack Neutron之---2 Neutron的网络实现模型---读书笔记

    目标: 掌握neutron在计算节点,网络节点,控制节点的网络实现模型. 目录: 1 Neutron的三类节点 2 计算节点的网络实现模型 3 网络节点的网络实现模型 4 控制节点的实现模型 5 总结 ...

  5. 何恺明团队新作!深度学习网络架构新视角:通过相关图表达理解神经网络

    标题&作者团队 导语:恺明大神出品,必属精品.Facebook的研究员从一个新奇的角度对神经网络的表示与设计进行探索,提出了一种新颖的相关图表示方式.它有助于对现有网络架构进行更深层次的分析与 ...

  6. 理解 OpenStack Swift (2):架构、原理及功能 [Architecture, Implementation and Features]...

    本系列文章着重学习和研究OpenStack Swift,包括环境搭建.原理.架构.监控和性能等. (1)OpenStack + 三节点Swift 集群+ HAProxy + UCARP 安装和配置 ( ...

  7. 【论文解读】深度学习网络架构新视角:通过相关图表达理解神经网络(何恺明团队新作)...

    文章来源于极市平台,作者Happy 标题&作者团队 导语:恺明大神出品,必属精品.Facebook的研究员从一个新奇的角度对神经网络的表示与设计进行探索,提出了一种新颖的相关图表示方式.它有助 ...

  8. 理解并取证:DLS网络架构和PPPOE数据帧

    理解并取证:DLS网络架构和PPPOE数据帧 对应的教学录像在: http://edu.51cto.com/lecturer/user_id-7648423.html9.9发布,待管理员24小时审核后 ...

  9. 一个深度学习痴呆选手对AlexNet网络架构的一些理解

    最近开始入坑深度学习,之前根本没接触过关于AI领域的知识,也就对着B站上的CS231N课水了水,但完全就是半懂不懂很懵逼的感觉,毕竟神经网络就类似于一个黑箱,难以理解也是很正常的.现在打算写一篇关于极 ...

最新文章

  1. 受用一生的高效 PyCharm 使用技巧(六)
  2. C++编译器何时为用户提供默认构造函数
  3. java inflaterinputstream_java.util.zip.InflaterInputStream.available()方法示例
  4. 面试题4:二维数组中的查找
  5. Exchange2007 从零到入门(2)---收件人管理
  6. 聚合复合_聚合复合微生物菌剂的功能
  7. (数据科学学习手札45)Scala基础知识
  8. mac brew install nginx遇到的坑
  9. 吴恩达机器学习作业3.2神经网络
  10. linux命令行模式连接网络,在Linux环境命令行中实现Wifi 连接的方法
  11. 【回血赠书第6期】拯救吃圭人,不剁手也能实现11月新书自由!
  12. swift中高阶函数map、flatMap、filter、reduce
  13. 算法:将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。
  14. element提交图片限制一张_ElementUI 上传文件以及限制
  15. python opengl书籍_初试PyOpenGL一 (Python+OpenGL)
  16. NOIP2017提高组复赛总结
  17. 电力安全教育之临时用电
  18. .net的反射技术(2)深究及 性能比较
  19. 自动驾驶深度多模态目标检测和语义分割:数据集、方法和挑战
  20. 手机客户端访问本机计算机局域网服务器

热门文章

  1. js实现轮播图,模拟flash上下滚动(原生JS,没有任何框架)
  2. js模块化编程之CommonJS和AMD/CMD
  3. CentOS7系统启动、排错、修复、破解root口令
  4. 【leetcode】45. Jump Game II 非负数组的最少跳跃步数
  5. orion的简单测试
  6. 在MasterPage下FindControl的使用方法
  7. JavaScript常用判断函数 [转]
  8. react项目部署nginx服务器
  9. Appium的环境搭建和配置
  10. ZIL (ZFS intent log) zil.c