天天看點

ECS彈性網卡+彈性公網IP配置最佳實踐之政策路由

作者:霄翎

概述

目前阿裡雲ECS部分機型可以配置多張網卡(一張原生網卡+若幹張彈性網卡),用來實作業務上對于系統内多網卡的需求,詳細可以參考

【新功能】彈性公網IP綁定彈性網卡新功能及最佳實踐

。在使用過程中,可能會遇到多個彈性公網IP綁定到一個ECS上的原生網卡、彈性網卡上後無法通信的問題,這個時候需要檢查系統内的路由配置和政策(policy rules)。

從route路由表說起

預設情況下,linux系統中都會有一張路由表,使用route或ip route就可以進行檢視,如

default via 172.16.127.253 dev eth0
169.254.0.0/16 dev eth0 scope link metric 1002
172.16.112.0/20 dev eth0 proto kernel scope link src 172.16.115.242           

以上起到關鍵作用的是第一行路由,它聲明了一條預設路由,從eth0網卡中出去,目标是網關172.16.127.253。在隻有一張網卡的執行個體中,這樣的配置是沒有問題的,但如果有多張網卡的情況下,入流量會從不同的網卡中進入執行個體,但出流量都會從eth0網卡中出去(譬如從外部ping 綁定在彈性網卡上的彈性公網IP,ICMP request包會從執行個體的彈性網卡中進入執行個體,而執行個體回複的ICMP reply包會從eth0中流出),導緻出入路徑不一緻,會造成一系列的問題,如單網卡流量瓶頸、負載不均衡等問題。

真實的路由表

在linux系統中,實際上是有255張路由表的,預設使用的是254這張路由表,使用route指令展示的即是這張表中的路由條目。除此之外的路由表我們可以對它進行适當的配置,以實作自定義或進階需求。

我們可以使用ip route list table [table index]來檢視系統内的路由表條目,如

[root@xiaoling-hz-test ~]# ip route list table 254
default via 172.16.127.253 dev eth0
169.254.0.0/16 dev eth0 scope link metric 1002
172.16.112.0/20 dev eth0 proto kernel scope link src 172.16.115.242           

以上條目可以看到系統内預設的254号路由表内的條目,另外,還可以将index置為0來檢視系統内所有的路由條目,這在需要循環周遊系統内自定義路由表時非常有用。

PS. table==253這張路由表被系統預設為是default表,建議使用1-252号路由表來添加自定義的路由條目。被linux預先定義的路由表詳情可以檢視系統内/etc/iproute2/rt_tables,以下是一個示例,可以看到253 - 255已經被系統定義:

# reserved values
#
255     local
254     main
253     default
0       unspec
#
# local
#
#1      inr.ruhep
           

政策路由

為什麼會需要多張路由表呢?這不得不提到政策路由,目前我們需要實作的功能是同進同出,保證從eth0口進來的包從eth0口出去,eth1進從eth1出,但彈性公網IP需要有一條預設路由來讓ECS可以正常通路公網,但卻又不能直接在預設路由表裡添加兩個目标網段是0.0.0.0,分别從eth0、eth1中出去的路由,這個時候政策路由就派上用場了,我們需要根據源位址進行政策選擇。

簡單來說就是配置兩張路由表,路由表中分别有從eth0、eth1中出去的預設路由,在系統需要發包時,根據包的源IP進行選擇,eth0的源IP就從包含eth0的路由表出去,eth1的源IP就從eth1的路由表走,進而實作同進同出。

linux系統内關于政策的索引是一個無符号的32位整型數值,是以理論上政策索引的數值可以達到4294967295之多,當然通常我們隻需要使用個位數的索引條目即可。

具體的一個配置

以上說的都是理論,可能會有一些虛,下面我們來實際進行一個配置。我們特意選取阿裡雲官方尚未支援自動配置的鏡像Ubuntu 16.04 64位來進行配置,以下是這個場景中相關參數:

ECS執行個體網關位址:172.16.127.253

==原生網卡資訊==
名稱:eth0
IP位址:172.16.116.38
綁定的彈性公網IP:47.99.42.x

==彈性網卡資訊==
名稱:eth1
IP位址:172.16.116.39
綁定的彈性公網IP:116.62.163.x           

如何獲得ECS執行個體完整的網卡資訊

阿裡雲ECS控制台對于執行個體的網卡資訊展示的不是很完全,建議通過API方法 DescribeNetworkInterfaces 來擷取,若沒有API調試環境,可以使用阿裡雲的API Explorer來調試,非常友善,以下是一個示例 URL ,點選後可以直接進入線上調試頁面。

檢查系統的預設配置

依次檢視網卡、預設路由,可以看到系統内的配置殘缺不全:

root@iZbp14bxrlofsqs3d5dw43Z:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:16:3e:0c:72:5d brd ff:ff:ff:ff:ff:ff
    inet 172.16.116.38/20 brd 172.16.127.255 scope global eth0
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 00:16:3e:10:aa:7e brd ff:ff:ff:ff:ff:ff           
root@iZbp14bxrlofsqs3d5dw43Z:~# ip route list table 254
default via 172.16.127.253 dev eth0
172.16.112.0/20 dev eth0  proto kernel  scope link  src 172.16.116.38           

首先編輯/etc/network/interfaces檔案,在最後加上關于eth1的定義,新添加的兩行分别告訴系統在啟動時自動拉起eth1、eth1的參數配置使用DHCP協定,詳細的配置說明可以參考man interfaces:

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp

auto eth1
iface eth1 inet dhcp           

儲存後執行systemctl restart networking重新開機網絡服務,可以看到eth1網卡已經配置上IP位址了:

root@iZbp14bxrlofsqs3d5dw43Z:~# ip address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:16:3e:0c:72:5d brd ff:ff:ff:ff:ff:ff
    inet 172.16.116.38/20 brd 172.16.127.255 scope global eth0
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:16:3e:10:aa:7e brd ff:ff:ff:ff:ff:ff
    inet 172.16.116.39/20 brd 172.16.127.255 scope global eth1
       valid_lft forever preferred_lft forever           

接下去就需要配置政策路由了,針對這個場景,我們定義了以下資訊:

==原生網卡==
使用路由表100,政策路由優先級索引為200
添加路由的指令(網關位址根據實際情況而定):ip route add default via 172.16.127.253 dev eth0 tab 100
添加政策的指令(源IP根據實際情況而定):ip rule add from 172.16.116.38 tab 100 priority 200

==彈性網卡==
使用路由表101,政策路由優先級索引為300
添加路由的指令(網關位址根據實際情況而定):ip route add default via 172.16.127.253 dev eth1 tab 101
添加政策的指令(源IP根據實際情況而定):ip rule add from 172.16.116.39 tab 101 priority 300           

執行以上指令後,系統内政策路由就已經配好了,通過相關指令檢視的結果如下(已經略去無關資訊):

root@iZbp14bxrlofsqs3d5dw43Z:~# ip route list table 0
default via 172.16.127.253 dev eth0  table 100
default via 172.16.127.253 dev eth1  table 101
default via 172.16.127.253 dev eth0
172.16.112.0/20 dev eth0  proto kernel  scope link  src 172.16.116.38
172.16.112.0/20 dev eth1  proto kernel  scope link  src 172.16.116.39           
root@iZbp14bxrlofsqs3d5dw43Z:~# ip rule list
0:      from all lookup local
200:    from 172.16.116.38 lookup 100
300:    from 172.16.116.39 lookup 101
32766:  from all lookup main
32767:  from all lookup default           

可以看到系統中增加了table==100、101的兩張路由表,增加了200、300兩個優先級的政策,分别指定eth0、eth1出入的規則,這樣就可以做到一張網卡同進同出了。

持久化配置

以上的配置,除了網卡的IP資訊可以持久化,其他的配置如路由、政策都會在重新開機後失效,可以把以上指令寫到系統的配置檔案中。理論上更優雅的方法是在/etc/sysconfig/network-scripts/ (CentOS) 、 /etc/network/ (Ubuntu)目錄下将指令寫到特定的檔案中來解決這個問題,但無奈無法測試所有的場景,我采取了比較“暴力”的方法來統一的解決:将指令寫到/etc/rc.local檔案中,可以無視發行版。

比如本文中的場景,就可以将四條ip route/ip rule指令添加到rc.local中:

root@iZabcdeZ:~# vim /etc/rc.local

ip route add default via 172.16.127.253 dev eth0 tab 100
ip rule add from 172.16.116.38 tab 100 priority 200
ip route add default via 172.16.127.253 dev eth1 tab 101
ip rule add from 172.16.116.39 tab 101 priority 300           

阿裡雲原生的做法

檢視阿裡雲官方關于配置 ECS 執行個體的彈性網卡的說明,以下幾種鏡像是可以直接支援不需要手工配置:

CentOS 7.3 64 位
CentOS 6.8 64 位
Windows Server 2016 資料中心版 64 位
Windows Server 2012 R2 資料中心版 64 位           

實際上CentOS系統内部也是采用了類似的政策來實作的,使用ip route和ip rule指令可以檢視到響應的政策,隻是路由表索引和政策路由的優先級序号有些許不同,各位可以實際驗證一下。

參考文獻

https://www.linuxjournal.com/article/7291

繼續閱讀