當 Linux conntrack 不再是你的朋友時

當 Linux conntrack 不再是你的朋友時

連線追蹤(「conntrack」)是 Linux 核心網路堆疊的核心功能。 它允許核心追蹤所有邏輯網路連接或流,從而識別構成每個流的所有資料包,以便可以按順序一起處理它們。

Conntrack 是一個重要的核心功能,在一些基本情況下會用到:

  • NAT 依賴 conntrack 的訊息,因此它可以平等地對待來自同一流的所有資料包。 例如,當 Pod 存取 Kubernetes 服務時,kube-proxy 負載平衡器使用 NAT 將流量導向至叢集內的特定 Pod。 Conntrack 記錄對於給定的連接,所有發送到 IP 服務的封包都必須傳送到同一個 pod,且後端 pod 傳回的封包必須透過 NAT 回到發出請求的 pod。
  • Calico 等狀態防火牆依賴 connecttrack 的資訊將「回應」流量列入白名單。 這允許您編寫一個網路策略來表示“允許我的 pod 連接到任何遠端 IP 位址”,而無需編寫策略來明確允許回應流量。 (如果沒有這個,您將不得不添加安全性低得多的「允許封包從任何 IP 發送到我的 pod」規則。)

此外,conntrack 通常會提高系統效能(透過減少 CPU 消耗和資料包延遲),因為只有流中的第一個資料包
必須遍歷整個網路堆疊來決定如何處理它。 參見帖子“kube-proxy模式對比” 查看其工作原理的範例。

然而,conntrack 有其局限性......

那麼這一切到底是哪裡出了問題呢?

conntrack 表具有可配置的最大大小,如果它已滿,連接通常會開始被拒絕或丟棄。 表中有足夠的可用空間來處理大多數應用程式的流量,這永遠不會成為問題。 但是,在某些情況下您可能需要考慮使用 conntrack 表:

  • 最明顯的情況是您的伺服器處理大量並發活動連線。 例如,如果您的 conntrack 表配置為 128k 條目,但您有 >128k 並發連接,那麼您肯定會遇到問題!
  • 一個不太明顯的情況:如果您的伺服器每秒處理大量連線。 即使連接是短暫的,Linux 也會繼續監視它們一段時間(預設為 120 秒)。 例如,如果您的 conntrack 表配置為 128k 條目,並且您嘗試每秒處理 1100 個連接,則它們將超出 conntrack 表的大小,即使連接非常短暫(128k/120s = 1092 個連接/ s)。

有幾種利基類型的應用程式屬於這些類別。 此外,如果您有很多不良行為者,則用大量半打開連接填充伺服器的 conntrack 表可能會被用作拒絕服務 (DOS) 攻擊的一部分。 在這兩種情況下,conntrack 都可能成為系統中的限製瓶頸。 在某些情況下,調整 conntrack 表參數可能足以滿足您的需求 - 通過增加大小或減少 conntrack 超時(但如果您做錯了,您將遇到很多麻煩)。 對於其他情況,有必要繞過 conntrack 以獲取攻擊性流量。

真實例子

讓我們舉一個具體的例子:我們合作的一家大型 SaaS 供應商在主機(不是虛擬機器)上有許多 memcached 伺服器,每個伺服器每秒處理 50K 以上的短期連線。

他們嘗試了 conntrack 配置,增加表大小並減少追蹤時間,但配置不可靠,RAM 消耗顯著增加,這是一個問題(大約 GBytes!),而且連接太短,conntrack 沒有創建其通常的性能優勢(減少CPU 消耗或資料包延遲)。

他們轉向 Calico 作為替代方案。 Calico 網路策略可讓您不對某些類型的流量使用 conntrack(使用 doNotTrack 策略選項)。 這為他們提供了所需的性能水平,以及 Calico 提供的附加安全等級。

你需要走多遠才能繞過 conntrack?

  • 不追蹤網路策略通常應該是對稱的。 對於 SaaS 提供者:他們的應用程式在受保護區域內運行,因此,使用網路策略,他們可以將來自允許存取 memcached 的其他特定應用程式的流量列入白名單。
  • 不追蹤策略不考慮連線的方向。 因此,如果 memcached 伺服器被駭客攻擊,理論上您可以嘗試連接到任何 memcached 用戶端,只要它使用正確的來源連接埠即可。 但是,如果您為 memcached 用戶端正確定義了網路策略,那麼這些連線嘗試仍將在客戶端被拒絕。
  • 不追蹤策略應用於每個資料包,這與僅應用於流中的第一個資料包的普通策略相反。 這會增加每個資料包的 CPU 消耗,因為必須對每個資料包套用該策略。 但對於短期連接,此費用可以透過減少 conntrack 處理的資源消耗來平衡。 例如,對於 SaaS 供應商,每個連接的資料包數量非常小,因此對每個資料包應用策略時的額外 CPU 消耗是合理的。

讓我們開始測試

我們在具有 memcached 伺服器的單一 Pod 和在遠端節點上執行的多個 Memcached 用戶端 Pod 上執行測試,以便我們每秒可以執行大量連線。 具有 memcached 伺服器 Pod 的伺服器有 8 個核心,conntrack 表中有 512k 條目(主機的標準配置表大小)。
我們測量了以下之間的效能差異:無網路策略; 符合常規 Calico 政策; 和 Calico 不跟蹤政策。

對於第一個測試,我們將連線數設定為每秒 4.000 個,因此我們可以專注於 CPU 消耗的差異。 無策略和常規策略沒有顯著差異,但 do-not-track 的 CPU 消耗增加了約 20%:

當 Linux conntrack 不再是你的朋友時

在第二個測試中,我們啟動了客戶端可以產生的盡可能多的連接,並測量了 memcached 伺服器每秒可以處理的最大連接數。 正如預期的那樣,「無策略」和「常規策略」情況都達到了每秒超過 4,000 個連接的 conntrack 限制(512k / 120s = 4,369 個連接/秒)。 透過不追蹤策略,我們的客戶每秒發送 60,000 個連接,沒有出現任何問題。 我們確信可以透過增加更多客戶端來增加這個數字,但我們認為這些數字已經足以說明本文的要點!

當 Linux conntrack 不再是你的朋友時

結論

Conntrack 是一個重要的核心功能。 他完美地完成了他的工作。 它經常被關鍵系統組件使用。 然而,在某些特定場景下,conntrack 造成的擁塞超過了它提供的正常好處。 在這種情況下,Calico 網路策略可用於選擇性地停用 conntrack,同時提高網路安全性。 對於所有其他流量,conntrack 仍然是您的朋友!

也請閱讀我們部落格上的其他文章:

來源: www.habr.com

添加評論