EndpointSlice

EndpointSlice API 是 Kubernetes 用來讓你的 Service 能夠擴充套件以處理大量後端,並允許叢集高效更新其健康後端列表的機制。
特性狀態: Kubernetes v1.21 [stable]

Kubernetes 的 **EndpointSlice** API 提供了一種在 Kubernetes 叢集中跟蹤網路端點的方法。

EndpointSlice API

在 Kubernetes 中,EndpointSlice 包含對一組網路端點的引用。控制平面會自動為任何具有指定選擇器的 Kubernetes Service 建立 EndpointSlices。這些 EndpointSlices 包含對與 Service 選擇器匹配的所有 Pod 的引用。EndpointSlices 透過 IP 家族、協議、埠號和 Service 名稱的唯一組合對網路端點進行分組。EndpointSlice 物件的名稱必須是有效的DNS 子域名

例如,這是一個示例 EndpointSlice 物件,由 `example` Kubernetes Service 擁有。

apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
  name: example-abc
  labels:
    kubernetes.io/service-name: example
addressType: IPv4
ports:
  - name: http
    protocol: TCP
    port: 80
endpoints:
  - addresses:
      - "10.1.2.3"
    conditions:
      ready: true
    hostname: pod-1
    nodeName: node-1
    zone: us-west2-a

預設情況下,控制平面建立和管理 EndpointSlices,每個 EndpointSlice 最多包含 100 個端點。你可以透過 `kube-controller-manager` 的 `--max-endpoints-per-slice` kube-controller-manager 標誌配置此值,最大為 1000。

EndpointSlices 作為 kube-proxy 路由內部流量的真相來源。

地址型別

EndpointSlices 支援兩種地址型別

  • IPv4
  • IPv6

每個 `EndpointSlice` 物件代表一個特定的 IP 地址型別。如果你的 Service 同時支援 IPv4 和 IPv6,那麼將至少有兩個 `EndpointSlice` 物件(一個用於 IPv4,一個用於 IPv6)。

狀況

EndpointSlice API 儲存可能對消費者有用的端點狀態。這三個狀態是 `serving`、`terminating` 和 `ready`。

Serving (服務中)

功能狀態: Kubernetes v1.26 [stable]

`serving` 狀態表示端點當前正在提供響應,因此應將其用作 Service 流量的目標。對於由 Pod 支援的端點,這對映到 Pod 的 `Ready` 狀態。

Terminating (正在終止)

功能狀態: Kubernetes v1.26 [stable]

`terminating` 狀態表示端點正在終止。對於由 Pod 支援的端點,當 Pod 首次被刪除時(即當它收到刪除時間戳時,但很可能在 Pod 容器退出之前),此狀態會被設定。

Service 代理通常會忽略 `terminating` 狀態的端點,但如果所有可用端點都處於 `terminating` 狀態,它們可能會將流量路由到同時處於 `serving` 和 `terminating` 狀態的端點。(這有助於確保在底層 Pod 進行滾動更新期間不會丟失 Service 流量。)

Ready (就緒)

`ready` 狀態實際上是“`serving` 且未 `terminating`”的快捷方式(儘管對於 `spec.publishNotReadyAddresses` 設定為 `true` 的 Service,它也總是 `true`)。

拓撲資訊

EndpointSlice 中的每個端點都可以包含相關的拓撲資訊。拓撲資訊包括端點的位置以及有關相應節點和區域的資訊。這些資訊在 EndpointSlices 中以下每個端點欄位中可用:

  • `nodeName` - 此端點所在的節點的名稱。
  • `zone` - 此端點所在的區域。

管理

最常見的情況是,控制平面(特別是端點切片控制器)建立和管理 EndpointSlice 物件。EndpointSlices 還有其他各種用例,例如服務網格實現,可能導致其他實體或控制器管理額外的 EndpointSlices 集。

為了確保多個實體可以管理 EndpointSlices 而不會相互干擾,Kubernetes 定義了標籤 `endpointslice.kubernetes.io/managed-by`,它指示管理 EndpointSlice 的實體。端點切片控制器將 `endpointslice-controller.k8s.io` 作為其管理的所有 EndpointSlice 的此標籤的值。管理 EndpointSlices 的其他實體也應為此標籤設定一個唯一值。

所有權

在大多數用例中,EndpointSlices 由 EndpointSlice 物件所跟蹤端點的 Service 擁有。這種所有權透過每個 EndpointSlice 上的所有者引用以及 `kubernetes.io/service-name` 標籤來表明,該標籤使得查詢屬於某個 Service 的所有 EndpointSlice 變得簡單。

EndpointSlice 的分發

每個 EndpointSlice 都有一組適用於該資源中所有端點的埠。當服務使用命名埠時,Pod 可能為相同的命名埠分配不同的目標埠號,這需要不同的 EndpointSlice。

控制平面會嘗試儘可能地填充 EndpointSlices,但不會主動重新平衡它們。其邏輯相當簡單:

  1. 遍歷現有的 EndpointSlices,移除不再需要的端點,並更新已更改的匹配端點。
  2. 遍歷在第一步中已修改的 EndpointSlices,並用任何所需的新端點填充它們。
  3. 如果仍有新的端點要新增,嘗試將其放入先前未更改的切片中和/或建立新的切片。

重要的是,第三步優先限制 EndpointSlice 的更新,而不是實現 EndpointSlice 的完美分佈。例如,如果有 10 個新端點要新增,並且有 2 個 EndpointSlice 各有 5 個空閒位置,這種方法會建立一個新的 EndpointSlice,而不是填滿這 2 個現有 EndpointSlice。換句話說,建立一個 EndpointSlice 比多次更新 EndpointSlice 更可取。

由於 kube-proxy 在每個節點上執行並監視 EndpointSlices,對 EndpointSlice 的每次更改都相對昂貴,因為它將被傳輸到叢集中的每個節點。這種方法旨在限制需要傳送到每個節點的更改數量,即使這可能導致多個 EndpointSlice 未完全填充。

在實踐中,這種不理想的分佈應該很少見。EndpointSlice 控制器處理的大多數更改都足夠小,可以放入現有的 EndpointSlice 中,如果不能,無論如何都可能很快需要一個新的 EndpointSlice。Deployment 的滾動更新也提供了一種自然的 EndpointSlice 重打包方式,所有 Pod 及其相應的端點都將被替換。

重複端點

由於 EndpointSlice 變更的性質,端點可能在同一時間出現在多個 EndpointSlice 中。這自然發生在對不同 EndpointSlice 物件的變更可能在不同的時間到達 Kubernetes 客戶端 watch / cache 時。

EndpointSlice 映象

功能狀態: `Kubernetes v1.33 [已棄用]`

EndpointSlice API 替代了舊的 Endpoints API。為了保持與期望 kube-proxy 基於 Endpoints 資源路由流量的舊控制器和使用者工作負載的相容性,叢集的控制平面會將大多數使用者建立的 Endpoints 資源映象到相應的 EndpointSlices。

(然而,此功能,與 Endpoints API 的其餘部分一樣,已棄用。手動為無選擇器的 Service 指定端點的使用者應該透過直接建立 EndpointSlice 資源來實現,而不是透過建立 Endpoints 資源並允許它們被映象。)

控制平面會映象 Endpoints 資源,除非:

  • Endpoints 資源具有 `endpointslice.kubernetes.io/skip-mirror` 標籤且其值為 `true`。
  • Endpoints 資源具有 `control-plane.alpha.kubernetes.io/leader` 註解。
  • 相應的 Service 資源不存在。
  • 相應的 Service 資源具有非空選擇器。

單個 Endpoints 資源可能會轉換為多個 EndpointSlice。如果 Endpoints 資源有多個子集或包含具有多個 IP 家族(IPv4 和 IPv6)的端點,則會發生這種情況。每個子集最多 1000 個地址將被映象到 EndpointSlices。

下一步

最後修改於 2025 年 4 月 9 日太平洋標準時間上午 5:08:更新 Endpoints API 棄用文件 (#49831) (649bda2cbd)