Kubernetes EKS 叢集中的 IP 地址分配問題

rife發表於2023-04-01

文字翻譯自: https://itnext.io/ip-and-pod-allocations-in-eks-5be6612b8325


執行 EKS 叢集時,你可能會遇到兩個問題:

  • 分配給 pod 的 IP 地址用完了。
  • 每個節點的 pod 數量少(由於 ENI 限制)。

在本文中,你將學習如何克服這些問題。

在我們開始之前,這裡有一些關於節點內網路如何在 Kubernetes 中工作的背景知識。

建立節點時,kubelet 委託:

  1. 建立容器到容器執行時。
  2. 將容器連線到 CNI 的網路。
  3. 將卷安裝到 CSI。

kubelet 將任務委託給 CRI、CNI 和 CSI

讓我們關注 CNI 部分。

每個 pod 都有自己獨立的 Linux 網路名稱空間,並連線到一個網橋。

CNI 負責建立網橋、分配 IP 並將 veth0 連線到 cni0。

大多數情況下,一個節點上的所有容器都連線到一個網橋上

這通常會發生,但不同的 CNI 可能會使用其他方式將容器連線到網路。

例如,可能沒有 cni0 網橋。

AWS-CNI 是此類 CNI 的一個示例。

並非所有 CNI 都使用網橋連線同一節點上的容器

在 AWS 中,每個 EC2 例項都可以有多個網路介面 (ENI)。

你可以為每個 ENI 分配有限數量的 IP。

例如,一個 m5.large 例項可以為 ENI 分配最多 10 個 IP。

在這 10 個 IP 中,你必須將一個分配給網路介面。

剩下的你可以不用管。

彈性網路介面和 IP 地址

以前,你可以使用額外的 IP 並將它們分配給 Pod。

但是有一個很大的限制:IP 地址的數量。

讓我們看一個例子。

使用 m5.large 例項,你最多有 3 個 ENI,每個有 10 個 IP 私有地址。

由於保留了一個 IP,每個 ENI 還剩下 9 個(總共 27 個)。

這意味著你的 m5.large 例項最多可以執行 27 個 Pod。

這不是很多。

你最多可以在 m5.large 中擁有 27 個 pod

但是 AWS 釋出了對 EC2 的更改,允許將“地址字首”分配給網路介面。

地址字首是什麼?!

簡而言之,ENI 現在支援範圍而不是單個 IP 地址。

如果以前你可以擁有 10 個私有 IP 地址,那麼現在你可以擁有 10 個 IP 地址槽。

地址槽有多大呢?

預設情況下,16 個 IP 地址。

使用 10 個槽,你最多可以擁有 160 個 IP 地址。

這是一個相當顯著的變化!

讓我們看一個例子。

EC2 中的地址前後對比

使用 m5.large 例項,你有 3 個 ENI,每個有 10 個插槽(或 IP)。

由於為 ENI 保留了一個 IP,因此你還剩下 9 個插槽。

每個插槽是 16 個 IP,所以是 9*16=144 個 IP。

由於有 3 個 ENI,那就是 144x3=432 個 IP。

你現在最多可以擁有 432 個 Pod(之前是 27 個)。

你最多可以在 m5.large 中擁有 432 個 pod

AWS-CNI 支援插槽並將 Pod 的最大數量限制為 110 或 250,因此你最多可以在 m5.large 中擁有 432 個 pod 。

還值得指出的是,這不是預設啟用的——即使在較新的叢集中也是如此。

可能是因為只有 nitro 例項支援它。

分配插槽非常棒,直到你意識到 CNI 一次提供 16 個 IP 地址,而不是僅提供 1 個,這具有以下含義:

  • 更快地耗盡 IP 空間。
  • 碎片化。

讓我們回顧一下。

EC2 和 EKS 中的字首問題

一個 pod 被排程到一個節點。

AWS-CNI 分配 1 個 slot(16 個 IP),pod 使用一個。

現在想象一下有 5 個節點和一個包含 5 個副本的部署。

會發生什麼?

Kubernetes 排程程式更喜歡將 pod 分佈在整個叢集中。

很可能,每個節點接收 1 個 pod,AWS-CNI 分配 1 個插槽(16 個 IP)。

你從你的網路分配了 5*15=75 個 IP,但僅使用了 5 個。

使用 AWS CNI 分配 IP

但還有更多。

插槽分配一個連續的 IP 地址塊。

如果分配了一個新 IP(例如建立了一個節點),你可能會遇到碎片問題。

怎麼解決這些問題呢?

相關連結: