如何深入理解openstack网络架中的Basic Use Cases

72次阅读
没有评论

共计 9311 个字符,预计需要花费 24 分钟才能阅读完成。

丸趣 TV 小编今天带大家了解如何深入理解 openstack 网络架中的 Basic Use Cases,文中知识点介绍的非常详细。觉得有帮助的朋友可以跟着丸趣 TV 小编一起浏览文章的内容,希望能够帮助更多想解决这个问题的朋友找到问题的答案,下面跟着丸趣 TV 小编一起深入学习“如何深入理解 openstack 网络架中的 Basic Use Cases”的知识吧。

我们将用 3 个简单的 use case,展示这些基本网络组件如何以工作从而实现 openstack 的 SDN 方案。

在这些 use case 中,我们会了解整个网络配置和他们如何一起运行。use case 如下:

创建网络——我们创建网络时,发生了什么。如何创建多个隔离的网络。

创建虚拟机——一旦我们有了网络,我们可以创建虚拟机并将其接入网络。

虚拟机的 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 net1
Created 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/24
Created 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 list
qdhcp-5f833617-6179-4797-b7c0-7d420d84040c

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

# ip netns exec qdhcp-5f833617-6179-4797-b7c0-7d420d84040c ip addr
1: lo: mtu 65536 qdisc noqueue state UNKNOWN
 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
 inet 127.0.0.1/8 scope host lo
 inet6 ::1/128 scope host
 valid_lft forever preferred_lft forever
12: tap26c9b807-7c: mtu 1500 qdisc noqueue state UNKNOWN
 link/ether fa:16:3e:1d:5c:81 brd ff:ff:ff:ff:ff:ff
 inet 10.10.10.3/24 brd 10.10.10.255 scope global tap26c9b807-7c
 inet6 fe80::f816:3eff:fe1d:5c81/64 scope link
 valid_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-b9fc9e4b3ca1
 Bridge  br-eth3 
 Port  br-eth3 
 Interface  br-eth3 
 type: internal
 Port  eth3 
 Interface  eth3 
 Port  phy-br-eth3 
 Interface  phy-br-eth3 
 Bridge br-ex
 Port br-ex
 Interface br-ex
 type: internal
 Bridge br-int
 Port  int-br-eth3 
 Interface  int-br-eth3 
 Port  tap26c9b807-7c 
 tag: 1
 Interface  tap26c9b807-7c 
 type: internal
 Port br-int
 Interface br-int
 type: internal
 ovs_version:  1.11.0

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

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

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

关于网络隔离:

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,当包进入 eth3 所在的 uxniji 网络。反之亦然。我们通过 OVS 的 dump-flows 命令可以看到进入虚拟机网络的网络包在 br-eth3 上进行了 VLAN 标签的修改:

# ovs-ofctl dump-flows br-eth3
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,NORMAL
 cookie=0x0, duration=165108.226s, table=0, n_packets=14, n_bytes=1000, idle_age=5343, hard_age=65534, priority=2,in_port=2 actions=drop
 cookie=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,NORMAL
 cookie=0x0, duration=165130.01s, table=0, n_packets=75, n_bytes=3686, idle_age=4212, hard_age=65534, priority=2,in_port=1 actions=drop
 cookie=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-82
 tap53903a95-82

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

# ovs-vsctl show
83c42f80-77e9-46c8-8560-7697d76de51c
 Bridge  br-eth3 
 Port  br-eth3 
 Interface  br-eth3 
 type: internal
 Port  eth3 
 Interface  eth3 
 Port  phy-br-eth3 
 Interface  phy-br-eth3 
 Bridge br-int
 Port br-int
 Interface br-int
 type: internal
 Port  int-br-eth3 
 Interface  int-br-eth3 
 Port  qvb53903a95-82 
 tag: 3
 Interface  qvb53903a95-82 
 ovs_version:  1.11.0

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

VM -  tap53903a95-82 (virtual interface) -  qbr53903a95-82 (Linux bridge) -  qvb53903a95-82 (interface connected from Linux bridge to OVS bridge br-int) -  int-br-eth3 (veth one end) -  phy-br-eth3 (veth the other end) -  eth3 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-eth3 中实现。总结如下,虚拟机通过一组网络设备连入虚拟机网络。虚拟机和网络之间,VLAN 标签被修改。

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

之前的 use case 中,我们看到了一个叫 dhcp- 的 namespace 和虚拟机,两者最终连接到物理网络 eth3。他们都会被打上 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。

感谢大家的阅读,以上就是“如何深入理解 openstack 网络架中的 Basic Use Cases”的全部内容了,学会的朋友赶紧操作起来吧。相信丸趣 TV 丸趣 TV 小编一定会给大家带来更优质的文章。谢谢大家对丸趣 TV 网站的支持!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-04发表,共计9311字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)