原文地址: https://blogs.oracle.com/ronen/entry/diving_into_openstack_network_architecture3
git
在上一篇文章中,咱们介绍了openstack中的路由,了解到openstack如何经过namespace实现的router将两个network连通。本文中,咱们进一步分析路由功能,说明实现内部internal network和public network的路由(而不单单是internal network之间)。
咱们还会分析neutron如何将浮动IP配置给虚拟机,从而实现public network与虚拟机的连通。github
所谓“public network”,指openstack部署环境之外的网络。这个网络能够是datacenter中的另外一个网络、internet、或者一个不被openstack控制的私有网络。 安全
与public network通讯,咱们须要在openstack中建立一个network并设置为public。这个network用于虚拟机与public network通讯。虚拟机不能直接链接到这个新建立的属性为public的network,全部网络流量必须使用openstack建立的router从private network路由到public network。在openstack中建立public network,咱们只须要使用neutron net-create 命令,并将router:external设置为True。
在咱们的例子中,public newtork叫作“my-public”。
网络
# neutron net-create my-public --router:external=True Created a new network: +---------------------------+--------------------------------------+ | Field | Value | +---------------------------+--------------------------------------+ | admin_state_up | True | | id | 5eb99ac3-905b-4f0e-9c0f-708ce1fd2303 | | name | my-public | | provider:network_type | vlan | | provider:physical_network | default | | provider:segmentation_id | 1002 | | router:external | True | | shared | False | | status | ACTIVE | | subnets | | | tenant_id | 9796e5145ee546508939cd49ad59d51f | +---------------------------+--------------------------------------+
在咱们的环境中,控制节点的eth3是一个没有绑定IP的网卡。咱们使用它接入外部public network。所以咱们将eth3加入OVS网桥"br-ex",Neutron会将虚拟机向外部网络的发送的网络包路由到这个bridge。oracle
# ovs-vsctl add-port br-ex eth3 # ovs-vsctl show 8a069c7c-ea05-4375-93e2-b9fc9e4b3ca1 . . . Bridge br-ex Port br-ex Interface br-ex type: internal Port "eth3" Interface "eth3" . . .
咱们在eth3上建立了一个IP范围是180.180.180.0/24的public network。这个public network存在于datacenter中,经过gateway 180.180.180.1能够链接到datacenter网络。为了将这个网络与Openstack环境相连,咱们须要在“my-public"这个network,上建立一个有相同IP范围的subnet,并告诉neutron这个network的gateway。ssh
# neutron subnet-create my-public 180.180.180.0/24 --name public_subnet --enable_dhcp=False --allocation-pool start=180.180.180.2,end=180.180.180.100 --gateway=180.180.180.1 Created a new subnet: +------------------+------------------------------------------------------+ | Field | Value | +------------------+------------------------------------------------------+ | allocation_pools | {"start": "180.180.180.2", "end": "180.180.180.100"} | | cidr | 180.180.180.0/24 | | dns_nameservers | | | enable_dhcp | False | | gateway_ip | 180.180.180.1 | | host_routes | | | id | ecadf103-0b3b-46e8-8492-4c5f4b3ea4cd | | ip_version | 4 | | name | public_subnet | | network_id | 5eb99ac3-905b-4f0e-9c0f-708ce1fd2303 | | tenant_id | 9796e5145ee546508939cd49ad59d51f | +------------------+------------------------------------------------------+
而后,咱们须要将router接入咱们新建立的public network,使用下列命令建立:tcp
# neutron router-gateway-set my-router my-public Set gateway for router my-router
注意:咱们在两种状况下使用术语“public network",一个是datacenter中真实的public network,为了区分咱们把它(180.180.180.0/24)叫作"external public network"。另外一个是openstack中咱们使用的"public network",咱们称之为“my-public"的接口网络。咱们还涉及两个”gateways“,一个是外部Public network用的gateway(180.180.180.1),另外一个是router中的gateway接口(180.180.180.2)。 ide
执行上述的操做后,router上(以前已经拥有两个网络接口,链接两个不一样的internal network)增长了第三个网络接口(被称做gateway)。router能够有多个网络接口,链接普通的internal subnet或者做为gateway连入“my-public"网络。一个常常犯的错误是,试图以一般网络接口的方式接入public network,操做可能成功,可是却并不能与外部网络连通。在咱们建立一个public network,subnet并接入router,网络拓扑看起来是这样的: 工具
进入router的namespace中,咱们看到其中增长了一个180.180.180.0/24网段IP的网络接口,IP为180.180.180.2:
学习
# ip netns exec qrouter-fce64ebe-47f0-4846-b3af-9cf764f1ff11 ip addr . . 22: qg-c08b8179-3b: mtu 1500 qdisc noqueue state UNKNOWN link/ether fa:16:3e:a4:58:40 brd ff:ff:ff:ff:ff:ff inet 180.180.180.2/24 brd 180.180.180.255 scope global qg-c08b8179-3b inet6 2606:b400:400:3441:f816:3eff:fea4:5840/64 scope global dynamic valid_lft 2591998sec preferred_lft 604798sec inet6 fe80::f816:3eff:fea4:5840/64 scope link valid_lft forever preferred_lft forever . .
在这里router的gateway地址180.180.180.2与虚拟机是联通的,虚拟机能够ping到它。咱们也能从虚拟机ping到外部网络的gateway180.180.180.1以及这个gateway所连的网络。若是咱们查看router namespace,发现iptables的NAT talbe中有如下两行规则。
# ip netns exec qrouter-fce64ebe-47f0-4846-b3af-9cf764f1ff11 iptables-save . . -A neutron-l3-agent-snat -s 20.20.20.0/24 -j SNAT --to-source 180.180.180.2 -A neutron-l3-agent-snat -s 10.10.10.0/24 -j SNAT --to-source 180.180.180.2 . .
所以,从net1或net2向外网发出的网络包,其源IP地址会被修改成180.180.180.2。咱们能够在虚拟机中ping外网的某个地址,看下请求包的IP地址是不是这个IP地址。
namespace中的路由表会把全部外部流量路由到外网的gateway(180.180.180.1)。
# ip netns exec qrouter-fce64ebe-47f0-4846-b3af-9cf764f1ff11 route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 180.180.180.1 0.0.0.0 UG 0 0 0 qg-c08b8179-3b 10.10.10.0 0.0.0.0 255.255.255.0 U 0 0 0 qr-15ea2dd1-65 20.20.20.0 0.0.0.0 255.255.255.0 U 0 0 0 qr-dc290da0-0a 180.180.180.0 0.0.0.0 255.255.255.0 U 0 0 0 qg-c08b8179-3b
虚拟机中发出的流向public network的请求,会被NAT映射为源地址为180.180.180.2,而后发给public network的gateway。一样,咱们能够看到在namespace中ip forward功能是启动的。
# ip netns exec qrouter-fce64ebe-47f0-4846-b3af-9cf764f1ff11 sysctl net.ipv4.ip_forward net.ipv4.ip_forward = 1
如今,虚拟机能够访问public network。下一步,咱们尝试容许外部客户访问Openstack环境中的虚拟机,经过floating IP能够完成这个功能。 Floating IP由外部网络提供,用户能够将它设置给虚拟机,从而容许外部客户接入虚拟机。
建立Floating IP,第一步是按照上一个usecase的讲解,将虚拟机连入外部网络。第二步时使用命令行,产生一个浮动IP。
# neutron floatingip-create public Created a new floatingip: +---------------------+--------------------------------------+ | Field | Value | +---------------------+--------------------------------------+ | fixed_ip_address | | | floating_ip_address | 180.180.180.3 | | floating_network_id | 5eb99ac3-905b-4f0e-9c0f-708ce1fd2303 | | id | 25facce9-c840-4607-83f5-d477eaceba61 | | port_id | | | router_id | | | tenant_id | 9796e5145ee546508939cd49ad59d51f | +---------------------+--------------------------------------+
在router namespace中咱们能够看到,新增长了3跳iptabales规则:
-A neutron-l3-agent-OUTPUT -d 180.180.180.3/32 -j DNAT --to-destination 20.20.20.2 -A neutron-l3-agent-PREROUTING -d 180.180.180.3/32 -j DNAT --to-destination 20.20.20.2 -A neutron-l3-agent-float-snat -s 20.20.20.2/32 -j SNAT --to-source 180.180.180.3
绑定Floating IP后,咱们能够链接到虚拟机。须要确认安全组规则已经被设置,从而容许这样链接:
nova secgroup-add-rule default icmp -1 -1 0.0.0.0/0 nova secgroup-add-rule default tcp 22 22 0.0.0.0/0
Iptables是一个复杂而强大的工具。若是想更好的理解iptables规则,能够查看iptables的帮助文件。
本文介绍了如何将openstack环境中的虚拟机与public network连通。经过namespace和routing table,虚拟机不只能在openstack环境内的不一样网络间实现消息路由,还能与外部网络连通。
本文是这个系列文章的最后一篇。网络是opesntack最复杂的部分,是理解openstack的一个关键。阅读这四篇文章,对理解和分析openstack各类网络拓扑是很好的入门。使用咱们提到的这些内容,能够更好的理解诸如Firewall as a service、Load Balance as a service、Metadata service这些网络概念。基本的学习方式是,进入namespace中,看到底是如何利用Linux网络能力实现这些功能的。
咱们在最开始说过,这些use case中咱们只是使用了openstack众多网络配置方法的一种。咱们的例子都是用了open vswitch 插件,能够独立于网络设备使用。经过与这里的例子对比,有助于分析其余的插件和功能。不少状况下,商业插件会使用open vswitch/bridges/namespace以及一些相似的方法和原理。
本系列文章的目的,在于让大多数用户了解oepnstack网络。文章中自下而上,使用一下简单的usecase,试着分析了openstack network 的整个结构以及如何工做的。与网上的其余一些资料不一样,咱们没有介绍各类openstack网络agent以及他们的功能,而是讲了他们作什么以及如何作的。下一步,你能够查阅这些资料,试着了解不一样的agents是如何实现这些功能的。
全文结束。