深入理解openstack網路架構(4)-----連線到public network
在上一篇文章中,我們介紹了openstack中的路由,瞭解到openstack如何通過namespace實現的router將兩個network連通。本文中,我們進一步分析路由功能,說明實現內部internal network和public network的路由(而不僅僅是internal network之間)。
我們還會分析neutron如何將浮動IP配置給虛擬機器,從而實現public network與虛擬機器的連通。
Use case #5: Connecting VMs to the public network
所謂“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。
# 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。
# 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,使用下列命令建立:
# 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)。
執行上述的操作後,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
Use case #6: Attaching a floating IP to a VM
現在,虛擬機器可以訪問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 |
+---------------------+--------------------------------------+
根據"my-public" network的能力,使用者可以建立很多這樣的IP。將浮動IP與虛擬機器關聯,可以通過命令列或者GUI完成。下圖是GUI的例子:
在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進行NAT操作。對於router收到的目的地址為180.180.180.3的請求,會被轉換成目標地址為20.20.20.2。反之亦然。
繫結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
這兩條規則,允許ping和ssh。
Iptables是一個複雜而強大的工具。如果想更好的理解iptables規則,可以檢視iptables的幫助檔案。
Summary
本文介紹瞭如何將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是如何實現這些功能的。
全文結束。