Cloudflare 的眾多技術皆有據可查,例如,我們如何處理 Eyeball(用戶端)與伺服器之間的流量,這篇部落格上已經探討多次:「Anycast 技術簡介(2011 年)」、「沒有負載平衡器的負載平衡(2013 年)」、「實踐中的路徑 MTU 發現(2015 年)」、「Cloudflare 的邊緣負載平衡器(2020 年)」、「我們如何修復 BSD 通訊端 API(2022 年)」。
不過,我們極少談論網路設定的第二部分:我們的伺服器如何從網際網路擷取內容。在這篇部落格中,我們將闡述此差距。我們將探討如何管理用於從網際網路擷取資料的 Cloudflare IP 位址、我們的輸出網路設計如何演進,以及如何對其實施最佳化,以發揮可用 IP 空間的最大用處。
做好充分的準備。我們會講到很多內容。
先來說說術語!
每個 Cloudflare 伺服器均會處理多種網路流量,但有兩個粗略的分類較為醒目:
網際網路來源流量 - 由 Eyeball 發起的到我們伺服器的傳入連線。根據這篇部落格文章的背景資訊,我們將這些稱為「輸入連線」。
Cloudflare 來源流量 - 由我們伺服器發起的與網際網路上其他主機的傳出連線。為簡便起見,我們將這些稱為「輸出連線」。
本部落格中雖極少探討輸出部分,但這對我們的營運至關重要。我們的伺服器必須啟動傳出連線才能完成作業!按讚:
我們的 CDN 產品中,在快取內容之前,會從原始伺服器擷取內容。請參閱「Pingora,連線 Cloudflare 至網際網路的代理(2022 年)」、Argo 和分層快取。
對於 Spectrum 產品,每個輸入 TCP 連線均會產生一個輸出連線。
Workers 常常執行多個子請求來構造 HTTP 回應。其中一些子請求可能正向網際網路查詢伺服器。
我們還營運面向客戶端的正向代理產品,如 WARP 和 Cloudflare Gateway。這些代理處理目的地為網際網路的 Eyeball 連線。我們的伺服器需要代表使用者建立與網際網路的連線。
諸如此類
輸入的 Anycast,輸出的 Unicast
我們的輸入網路架構與輸出網路架構大有不同。在輸入網路中,來自網際網路的連線完全由我們的 Anycast IP 範圍處理。Anycast 是一種技術,我們的每個資料中心均「宣布」並能處理相同的 IP 範圍。由於可能有多個目的地,網際網路如何知曉將封包路由至何處?Eyeball 封包根據網際網路 BGP 指標路由至最近的資料中心,通常在地理位置上亦是最近的資料中心。通常,BGP 路由不會有太大的變化,每個 Eyeball IP 皆可路由至單個資料中心。
不過,雖然 Anycast 在輸入方向順利執行,但它不能在輸出上運作。從 Anycast IP 建立傳出連線不起作用。將回應封包納入考量。此封包有可能會被路由回錯誤的地方:地理位置最接近寄件者的資料中心,不一定是來源資料中心!
因此,直到不久之前,我們以一種直截了當且傳統的方式建立了傳出連線:每個伺服器皆有專門的 Unicast IP 位址。「Unicast IP」係指全世界僅有一個伺服器使用此位址。返回封包將正常運作,並完全返回至由 Unicast IP 標識的正確伺服器。
根據輸出 IP 對流量進行分割
Cloudflare 來源的連線原本主要是轉至網際網路上原始伺服器的 HTTP 擷取。隨著我們產品線的成長,流量的多樣性亦在增加。最值得注意的範例是我們的 WARP 應用程式。對於 WARP,我們的伺服器運行正向代理,並處理源自終端使用者裝置的流量。這並未消耗與 CDN 產品相同程度的中間資源。這就引發了一個問題。網際網路上的第三方伺服器(如原始伺服器)必須能夠區分來自 Cloudflare 服務及我們 WARP 使用者的連線。通常來說,此類流量分割係透過對不同流量類型使用不同 IP 範圍來實現(儘管我們最近引入了更強大的技術,如經認證的原始提取)。
為了解決受信任與不受信任的流量池區分問題,我們為每個伺服器新增了一個不受信任的 WARP IP 位址:
國家/地區標記的輸出 IP 位址
很快就發現,受信任與不受信任並非唯一需要的標記。對於 WARP 服務,我們還需要國家/地區標記。例如,英國的 WARP 使用者希望 bbc.com 網站能夠正常運作。但 BBC 將許多服務限定為僅限在英國的人存取。
此網站透過_地理柵欄_來實現這一點 — 使用將公共 IP 位址對應至國家/地區的資料庫,並且僅允許英國的 IP 位址。地理柵欄在當今的網際網路十分普遍。為避免地理柵欄問題,我們需要根據 WARP 使用者位置,選擇標記有相應國家/地區的特定輸出位址。與網際網路上的許多其他方一樣,我們用國家/地區代碼標記我們的輸出 IP 空間,並將其發布為地理源(如此項所示)。請注意,已發布的地理源僅僅是資料。事實上,比如說,一個 IP 標記為英國,這並不意味著就是英國提供的,只不過是指,營運商希望將其地理位置定位到英國。像是網際網路上的許多事物,係以信任為基礎。
請注意,我們現時有三個獨立的地理標記:
WARP 使用者的國家/地區標記 - 連線 IP 的 Eyeball
Eyeball 連線的資料中心位置
輸出 IP 的國家/地區標記
為了獲得最佳服務,我們想要選擇輸出 IP,以便其國家/地區標記與 Eyeball IP 的國家/地區相符。但是,從特定國家/地區標記的 IP 輸出具有挑戰性:我們的資料中心為來自世界各地的使用者提供服務,可能來自多個國家/地區!記住:由於採用 Anycast,我們不會直接控制輸入路由。網際網路地理並不總是與自然地理相符。例如,我們的倫敦資料中心不僅接收來自英國使用者的流量,還接收來自愛爾蘭及沙烏地阿拉伯使用者的流量。因此,我們在倫敦的伺服器需要與多個國家/地區關聯的多個 WARP 輸出位址:
您能看出這是怎麼回事嗎?問題空間簡直要爆掉!並非每個伺服器都有一個或兩個輸出 IP 位址,現在我們需要幾十個位址,而 IPv4 位址並不便宜。透過採用這種設計,每個伺服器需要多個位址,而我們運行數千個伺服器。這種架構變得費用高昂。
Anycast 有問題嗎?
我來回顧一下:採用 Anycast 輸入時,我們不能控制使用者要路由至哪個資料中心。因此,我們的每個資料中心都必須能夠從具有任何可信標記的位址輸出。在資料中心內部,我們亦不能控制將連線路由至哪個伺服器。可能有多個標記、多個資料中心,而一個資料中心內可能有多個伺服器。
也許問題在於輸入架構?或許最好使用傳統的網路設計,其中特定的 Eyeball 透過 DNS 路由至特定的資料中心,甚至是伺服器?
這是一種思維方式,但我們決定提出反對。我們喜歡 Anycast 輸入。這為我們帶來了諸多優勢:
效能:根據定義,使用 Anycast 時,Eyeball 會路由至最近的(依據 BGP 指標)資料中心。對於給定使用者而言,這通常是最快的資料中心。
自動容錯移轉:如果我們的其中一個資料中心變得不可用,流量會立即自動重新路由至下一個最佳位置。
DDoS 復原能力:在拒絕服務攻擊或流量暴增期間,多個資料中心的負載會自動平衡,顯著降低所產生的影響。
統一的軟體:每個資料中心和資料中心內每個伺服器的功能均相同。我們在全球所有伺服器上均使用相同的軟體堆疊。每台機器均可對任何產品執行任何操作。這樣能夠輕鬆偵錯,帶來良好的可擴充性。
出於這些原因,我們希望在輸出上保留 Anycast。我們決定以其他某些方式解決輸出位址基數問題。
解決關鍵問題
在我們營運的數千個伺服器中,每個伺服器均應能夠使用帶任何可能標記的輸出 IP。先展示兩個極端設計,是解釋我們解決方案的最簡單辦法。
每個伺服器皆擁有需要的所有 IP:每個伺服器均有帶所需標記的所有專用輸出 IP。
一個伺服器擁有所需的 IP:帶特定標記的專用輸出 IP 集中於一處,而其他伺服器會將流量轉寄至此。
這兩個選項都有其優缺點:
每個伺服器上的專用 IP
Specialized IP on every server | Specialized IP on one server |
---|---|
Super expensive $$$, every server needs many IP addresses. | Cheap $, only one specialized IP needed for a tag. |
Egress always local - fast | Egress almost always forwarded - slow |
Excellent reliability - every server is independent | Poor reliability - introduced chokepoints |
每個伺服器上的專用 IP
一個伺服器上的專用 IP
超昂貴 $$$,每個伺服器需要多個 IP 位址。
低價 $,一個標記只需要一個專用 IP。
Specialized IP on every server | Specialized IP per data center | Specialized IP on one server |
---|---|---|
Super expensive $$$ | Reasonably priced $$ | Cheap $ |
Egress always local - fast | Egress always local - fast | Egress almost always forwarded - slow |
Excellent reliability - every server is independent | Excellent reliability - every server is independent | Poor reliability - many choke points |
輸出始終在本地 - 快速
輸出幾乎總為轉寄 - 緩慢
出色的可靠性 - 每個伺服器均為獨立型
可靠性欠佳 - 引入阻塞點
還有第三種方式
我們一直在認真思考此問題。坦白來講,第一個極端選項是在每個 Cloudflare 伺服器上本地提供所需的每個 IP,這並非完全不可行。粗略來講,這就是我們能夠為 IPv6 達成的目標。藉由 IPv6,存取所需的龐大 IP 空間不在話下。
不過,在 IPv4 中,這兩個選項均不可接受。第一個選項提供快速可靠的輸出,但需要高昂的費用 - 需要的 IPv4 位址代價不菲。第二個選項可能佔用的 IP 空間最小,因此價格便宜,但效能和可靠性受到影響。
我們設計的解決方案折中了這兩個極端選項。粗略的想法是變更分配單位。我們沒有為每個伺服器分配一個 /32 IPv4 位址,而是設計了一種為每個資料中心分配一個 /32 IP 的方法,然後在實體伺服器之間共用。
每個伺服器上的專用 IP
198.51.100.1 - forward to LHR
198.51.100.2 - forward to CDG
198.51.100.3 - forward to MAN
...
每個資料中心的專用 IP
一個伺服器上的專用 IP
超昂貴 $$$
價格合理 $$
低價 $
輸出始終在本地 - 快速
輸出始終在本地 - 快速
輸出幾乎總為轉寄 - 緩慢
出色的可靠性 - 每個伺服器均為獨立型
出色的可靠性 - 每個伺服器均為獨立型
可靠性欠佳 - 多個阻塞點
在資料中心內共用 IP
在伺服器之間共用 IP 的想法並不新鮮。從傳統上來說,這可以透過路由器上的來源 NAT 實現。很遺憾,我們所需的輸出 IP 數量和營運規模之大,使我們無法依賴於路由器層級的狀態防火牆/NAT。我們亦不喜歡共用狀態,因此,我們並不熱衷於分散式 NAT 安裝。
相反,我們選擇的是按連接埠範圍在伺服器之間拆分輸出 IP。對於給定的輸出 IP,每個伺服器皆擁有一小部分可用來源連接埠(一個連接埠片段)。
當返回封包從網際網路到達時,我們必須將其路由回正確的機器。針對這項任務,我們已自訂「Unimog」(我們基於 L4 XDP 的負載平衡器,「Unimog,Cloudflare 的負載平衡器(2020 年)」),此負載平衡器運行順暢。
透過使用一個連接埠片段(比如說 2,048 個連接埠),我們能夠在 31 個伺服器之間共用一個 IP。不過,總會有連接埠耗盡的情況出現。為了解決此問題,我們一直努力有效地重複利用輸出連接埠。請參閱「如何防止連接埠耗盡(2022 年)」、「如何共用 IPv4 位址(2022 年)」以及我們的 Cloudflare.TV 區段。
差不多就這樣。每個伺服器皆知擁有哪些 IP 位址及連接埠片段。針對傳入路由,Unimog 會檢查連接埠,並將封包分派至相應的機器。
在資料中心之間共用子網路
但這並非故事的結束,我們尚未討論如何將單個 /32 位址路由至資料中心。從傳統上來說,在公共網際網路中,只能路由粒度為 /24 或 256 個 IP 位址的子網路。在我們的個案中,這會導致大量浪費 IP 空間。
為解決此問題並提高 IP 空間利用率,我們將輸出範圍部署為...Anycast!落實此項後,我們已自訂 Unimog,並教導其透過我們的骨幹網路將封包轉寄至正確的資料中心。Unimog 依這種方式維護資料庫:
透過這種設計,遞送哪個資料中心返回封包並不重要。Unimog 總能予以修復,並將資料轉寄至正確的地方。基本而言,雖然我們在 BGP 層級使用 Anycast,但由於我們採用特定的設計,IP 能在語義上標識資料中心,而 IP 和連接埠範圍可標識特定的機器。Unimog 的表現與 Unicast 相差無幾。
我們將這種技術堆疊稱為「軟 Unicast」,這有些妙不可言,就像是我們在軟體中通過 BGP 層級的 Anycast 運行 Unicast。
軟 Unicast 與魔法無異
透過這種設定,我們能夠獲得一些明顯的優勢:
我們能夠在很多伺服器之間共用 /32 輸出 IP。
我們能夠將單個子網路分佈至多個資料中心,輕鬆快速地執行變更。如此一來,我們能夠充分利用我們的輸出 IPv4 範圍。
我們能夠將相似的 IP 位址分組到一起。例如,所有標記為「UK」的 IP 位址可能形成一個連續範圍。這將減小已發布地理源的大小。
我們可輕鬆加入新的輸出 IP 範圍,例如客戶 IP。這對於我們的部分產品很實用,例如 Cloudflare Zero Trust。
這一切均能以合理的費用實現,不會損害效能及可靠性:
通常,使用者能夠直接從最近的資料中心輸出,帶來可能的最佳效能。
我們能夠視乎實際需要來分配或釋放 IP 位址。這為我們帶來了 IP 成本管理的靈活性,我們並不需要預先超支。
我們在不同位置運行多個輸出 IP 位址,因此,可靠性不會受到影響。
我們 IP 位址的真實位置是:「雲端」
雖然軟 Unicast 能讓我們獲得較高的效率,但我們遇到了一些問題。有時我們會遇到這樣的問題:「這個 IP 的實際位置是哪裡?」但這並沒有答案!我們的輸出 IP 並沒有任何實際位置。從 BGP 的角度來看,我們的輸出範圍為 Anycast,因此它們無處不在。從邏輯上來說,每個位址一次在一個資料中心使用,但我們可以根據需要來進行移動。
內容傳遞網路誤導使用者
這是我們使用第三方 CDN 遇到的一個問題(問題的另一個範例)。正如之前所述,我們的管道中有三個國家/地區標記:
正在連線的 IP Eyeball 國家/地區標記。
我們資料中心所處的位置。
我們為輸出連線選擇的 IP 位址國家/地區標記。
我們的輸出位址標記為「UK」,這一事實並不總表示此位址實際上正在英國使用。我們遇到過這種情況:由於對我們的 LHR 資料中心實施維護,一個帶英國標記的 WARP 使用者已被路由至巴黎。一個熱門 CDN 對我們的輸出 IP 執行了反向對應,發現此位址被標記為「UK」,並將使用者導向至某個倫敦 CDN 伺服器。這通常是可以的...但我們當時實際上是從巴黎輸出的。此使用者最終將封包從他們英國的家中路由至巴黎,再路由回英國。這嚴重影響了效能。
我們透過在輸出資料中心執行 DNS 請求來解決這個問題。對於DNS,我們使用標記有資料中心位置的 IP 位址,而非使用者的預期地理位置。這通常能夠解決問題,但遺憾的是,仍然會有一些例外情況。
未來已至
我們在 2021 年進行的尋址敏捷性實驗證明,我們有大量機會在解決輸出問題方面實施創新。軟 Unicast 表明,我們能夠在輸出端實現極大的靈活性及密度。
隨著每個新產品的出現,我們在輸出方面需要的標記數量也在增長(從流量可信度、產品類別到地理位置)。隨著可使用 IPv4 位址池的縮小,我們堅信此領域會湧現更多的創新。軟 Unicast 是我們推出的解決方案,但可以肯定的是,我們的研發絕不會止步於此。
但是,就目前而言,我們似乎離傳統的 Unicast 漸行漸遠。我們的輸出 IP 不再真正存在於固定的位置,而一些伺服器現在甚至沒有真正的 Unicast IP。