原文地址: 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是如何實現這些功能的。
全文結束。