在这篇文章中,我们将用1个简单的use case,展示基本网络组件如何以工作从而实现openstack的SDN方案。
在这些use case中,我们会了解整个网络配置和他们如何一起运行。use case如下:
创建网络——我们创建网络时,发生了什么。如何创建多个隔离的网络。
创建虚拟机——一旦我们有了网络,我们可以创建虚拟机并将其接入网络。
虚拟机的DHCP请求——opensack可以自动为虚拟机配置IP。通过openstack neutron控制的DHCP服务完成。我们来了解这个服务如何运行,DHCP请求和回应是什么样子的?
这篇文章中,我们会展示网络连接的原理,我们会了解网络包如何从A到B。我们先了解已经完成的网络配置是什么样子的?然后我们讨论这些网络配置是如 何以及何时创建的?
Use case #1: Create Network
创建network的操作非常简单。我们可以使用GUI或者命令行完成。openstack的网络仅供创建该网络的租户使用。当然如果这个网络是 “shared”,它也可以被其他所有租户使用。一个网络可以有多个subnets,但是为了演示目的和简单,我们仅为每一个network创建一个 subnet。通过命令行创建network:
1. # neutron net-create net1
2.
3. Created a new network:
4.
5. +---------------------------+--------------------------------------+
6.
7. | Field | Value |
8.
9. +---------------------------+--------------------------------------+
10.
11.| admin_state_up | True |
12.
13.| id | 5f833617-6179-4797-b7c0-7d420d84040c |
14.
15.| name | net1 |
16.
17.| provider:network_type | vlan |
18.
19.| provider:physical_network | default |
20.
21.| provider:segmentation_id | 1000 |
22.
23.| shared | False |
24.
25.| status | ACTIVE |
26.
27.| subnets | |
28.
29.| tenant_id | 9796e5145ee546508939cd49ad59d51f |
30.
31.+---------------------------+--------------------------------------+
为这个network创建subnet::
1. # neutron subnet-create net1 10.10.10.0/24
2.
3. Created a new subnet:
4.
5. +------------------+------------------------------------------------+
6.
7. | Field | Value |
8.
9. +------------------+------------------------------------------------+
10.
11.| allocation_pools | {"start": "10.10.10.2", "end": "10.10.10.254"} |
12.
13.| cidr | 10.10.10.0/24 |
14.
15.| dns_nameservers | |
16.
17.| enable_dhcp | True |
18.
19.| gateway_ip | 10.10.10.1 |
20.
21.| host_routes | |
22.
23.| id | 2d7a0a58-0674-439a-ad23-d6471aaae9bc |
24.
25.| ip_version | 4 |
26.
27.| name | |
28.
29.| network_id | 5f833617-6179-4797-b7c0-7d420d84040c |
30.
31.| tenant_id | 9796e5145ee546508939cd49ad59d51f |
32.
33.+------------------+------------------------------------------------+
现在我们有了一个network和subnet,网络拓扑像这样:
现在让我们深入看下到底发生了什么?在控制节点,我们一个新的namespace被创建:
1. # ip netns list
2.
3. qdhcp-5f833617-6179-4797-b7c0-7d420d84040c
这个namespace的名字是qdhcp- (参见上边),让我们深入namespace中看看有什么?
1. # ip netns exec qdhcp-5f833617-6179-4797-b7c0-7d420d84040c ip addr
2.
3. 1: lo: mtu 65536 qdisc noqueue state UNKNOWN
4.
5. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
6.
7. inet 127.0.0.1/8 scope host lo
8.
9. inet6 ::1/128 scope host
10.
11. valid_lft forever preferred_lft forever
12.
13.12: tap26c9b807-7c: mtu 1500 qdisc noqueue state UNKNOWN
14.
15. link/ether fa:16:3e:1d:5c:81 brd ff:ff:ff:ff:ff:ff
16.
17. inet 10.10.10.3/24 brd 10.10.10.255 scope global tap26c9b807-7c
18.
19. inet6 fe80::f816:3eff:fe1d:5c81/64 scope link
20.
21. valid_lft forever preferred_lft forever
我们发下在namespace下有两个网络接口,一个是loop设备,另一个叫“tap26c9b807-7c”。这个接口设置了IP地址 10.10.10.3,他会接收dhcp请求(后边会讲)。接下来我们来跟踪下“tap26c9b807-7c”的网络连接性。我们从OVS上看下这个接 口所连接的OVS网桥"br-int"。
1. # ovs-vsctl show
2. 8a069c7c-ea05-4375-93e2-b9fc9e4b3ca1
3. Bridge "br-eth2"
4. Port "br-eth2"
5. Interface "br-eth2"
6. type: internal
7. Port "eth2"
8. Interface "eth2"
9. Port "phy-br-eth2"
10. Interface "phy-br-eth2"
11. Bridge br-ex
12. Port br-ex
13. Interface br-ex
14. type: internal
15. Bridge br-int
16. Port "int-br-eth2"
17. Interface "int-br-eth2"
18. Port "tap26c9b807-7c"
19. tag: 1
20. Interface "tap26c9b807-7c"
21. type: internal
22. Port br-int
23. Interface br-int
24. type: internal
25. ovs_version: "1.11.0"
由上可知,veth pair的两端“int-br-eth2” 和 "phy-br-eth2",这个veth pari连接两个OVS网桥"br-eth2"和"br-int"。上一篇文章中,我们解释过如何通过ethtool命令查看veth pairs的两端。就如下边的例子:
1. # ethtool -S int-br-eth2
2. NIC statistics:
3. peer_ifindex: 10
4. .
5. .
6.
7. #ip link
8. .
9. .
10.10: phy-br-eth2: mtu 1500 qdisc pfifo_fast state UP qlen 1000
11..
12..
注意“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标签的修改:
1. # ovs-ofctl dump-flows br-eth2
2. NXST_FLOW reply (xid=0x4):
3. 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
4. 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
5. 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标签的修改如下:
1. # ovs-ofctl dump-flows br-int
2. NXST_FLOW reply (xid=0x4):
3. 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
4. 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
5. 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标签的修改。