透過永久 IP 位址控管通訊


本頁說明如何在 Google Kubernetes Engine (GKE) Pod 上實作永久 IP 位址。您可以透過自訂持續性 IP 位址對應,控管 GKE Pod 網路。如要進一步瞭解永久 IP 位址、用途和優點,請參閱「關於 GKE Pod 的永久 IP 位址」。

需求條件

  • GKE 1.31 以上版本。
  • 您可以選擇保留 Google 提供的 IP 位址,或是自備 IP 位址 (BYOIP)。
  • 設定在 Pod 中執行的應用程式,使其可辨識及使用指派的持續性 IP 位址。
  • 如要為 GKE Pod 設定永久 IP 位址,必須啟用 GKE Dataplane V2 和 Gateway API 的叢集。

限制

  • 您必須設定應用程式,才能使用指派的永久 IP 位址。 GKE 不會自動將 IP 位址設定新增至 Pod 的網路介面。
  • 您一次只能將每個持續性 IP 位址與單一 Pod 建立關聯。 如果有多個可用的 Pod,GKE 通常會將流量傳送至最新的相符 Pod。不過,只有在最新的 Pod 狀況良好時,GKE 才會執行這項操作,也就是說,Pod 預設會將 Ready 條件狀態設為 True。您可以在 GKEIPRoute 中使用 reactionMode 設定,設定及變更這項行為。
  • GKE 僅支援 IPv4 位址做為永久 IP 位址。
  • GKE 僅支援第 3 層或裝置類型的多重網路
  • 如果不是使用 DPDK,系統不支援使用永久 IP 位址的高可用性 (HA) 設定。
  • 單一 GKEIPRoute 最多可指定 16 個 IP 位址。如要設定更多地址,可以建立多個 GKEIPRoute 物件。

事前準備

開始之前,請確認你已完成下列工作:

  • 啟用 Google Kubernetes Engine API。
  • 啟用 Google Kubernetes Engine API
  • 如要使用 Google Cloud CLI 執行這項工作,請安裝初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行 gcloud components update,取得最新版本。

為 GKE Pod 實作永久 IP 位址

GKE 中的永久 IP 位址可為 Pod 提供穩定的網路身分,即使 Pod 本身更新或移動也沒問題。

本節將概述為 GKE Pod 實作永久 IP 位址的工作流程:

  1. 建立叢集:建立具有 Gateway API 和 GKE Dataplane V2 的叢集。
  2. 保留 IP 位址:決定您需要外部 (可公開存取) 或內部 (僅限 Google Cloud) IP 位址,並加以保留。選擇與 GKE 叢集相同的區域。
  3. 建立 Gateway:設定 Kubernetes Gateway 物件,該物件會保留您預留的永久 IP 位址,並讓您建立規則 (GKEIPRoutes),說明叢集中的哪些 Pod 可以使用這些永久 IP 位址。
  4. 建立或識別永久 IP 位址的工作負載:如果您在額外網路上使用永久 IP 位址,請啟用多個網路介面並定義永久 IP 位址所在的網路,準備讓 Pod 使用永久 IP 位址。
  5. 為所選工作負載建立 GKEIPRoute 物件:設定 GKEIPRoute,將永久 IP 位址指派給特定 Pod。您可以使用標籤指定正確的 Pod,並視需要設定路由對 Pod 變更的反應方式。
  6. 設定應用程式感知功能:在 Pod 中設定應用程式,主動使用持續性 IP 位址。
  7. 監控:追蹤閘道和 GKEIPRoute 物件的狀態,確保一切運作正常。

如要為 GKE Pod 實作永久 IP 位址,請按照下列步驟操作:

步驟 1:建立已啟用 Gateway API 和 GKE Dataplane V2 的 GKE 叢集

如要啟用進階網路轉送和 IP 位址管理功能,以便在 GKE Pod 上實作永久 IP 位址,請按照下列步驟建立 GKE Dataplane V2 叢集:

gcloud container clusters create CLUSTER_NAME \
    --cluster-version=CLUSTER_VERSION \
    --enable-dataplane-v2 \
    --enable-ip-alias \
    --gateway-api=standard

更改下列內容:

  • CLUSTER_NAME:叢集名稱。
  • CLUSTER_VERSION:叢集版本。

步驟 2:設定持續性 IP 位址

如要為 Pod 建立可靠的網路身分,並設定持續性 IP 位址,請先取得持續性 IP 位址。您可以選擇保留 Google 提供的 IP 位址,或使用自己的 IP 位址 (BYOIP)。

步驟 2a:預留 Google 提供的 IP 位址

如要保留外部 IP 位址,請執行下列指令:

gcloud compute addresses create ADDRESS_NAME \
   --region=REGION

更改下列內容:

  • ADDRESS_NAME:您要與這個地址建立關聯的名稱。
  • REGION:您要保留這個位址的地區。這個地區應與您要將 IP 位址附加至的 Pod 位於同個地區。

    注意:保留 IP 位址時必須指定區域,因為轉送規則 (用於處理持續性 IP 位址的流量路徑) 屬於區域性。IP 位址和 GKE 叢集必須位於相同區域,才能正確轉送。

如要保留內部 IP 位址,請執行下列指令:

gcloud compute addresses create ADDRESS_NAME \
    --region REGION
    --subnet SUBNETWORK \
    --addresses IP_ADDRESS

更改下列內容:

  • ADDRESS_NAME:要保留的一或多個地址名稱。如有數個地址,請以空格分隔,並以清單形式指定所有地址。例如:example-address-1 example-address-2 example-address-3
  • REGION:這項要求中的地區。
  • SUBNETWORK:這個內部 IPv4 位址所屬的子網路。

為確保流量在私有網路中正確路由,內部 IP 位址必須屬於叢集的預設子網路或額外網路子網路。

如要進一步瞭解外部和內部 IP 位址,或查看如何使用主控台預留位址,請參閱「預留靜態外部 IP 位址」和「預留靜態內部 IP 位址」。

步驟 2b:自備 IP 位址 (BYOIP)

您可以自備 IP 位址 (BYOIP),不必使用 Google 提供的 IP 位址。如果您需要特定 IP 位址供應用程式使用,或是要將現有系統移至 Google Cloud,BYOIP 就很有幫助。如要使用 BYOIP,Google 會驗證您是否擁有 IP 位址範圍,並在 IP 位址匯入 Google Cloud後,將這些位址指派為 GKE Pod 的持續性 IP 位址。詳情請參閱「使用自備 IP 位址」。

步驟 3:建立 Gateway 物件

閘道物件會保留 IP 位址,並定義哪些 Pod 有資格使用這些位址。如要控管如何將永久 IP 位址指派給 GKE Pod,請使用 Gateway 物件。

  1. 建立適當類別的 Kubernetes Gateway 物件:
    • gke-persistent-regional-external-managed,適用於外部 (公開) IP 位址。
    • gke-persistent-regional-internal-managed 內部 (僅限Google Cloud) IP 位址。
  2. 在閘道的地址部分中,列出這個閘道管理的持續性 IP 位址 (Google 提供或 BYOIP)。
  3. 使用 Listeners 區段,判斷哪些 Pod (和相關聯的 GKEIPRoute 物件) 可能會使用閘道的 IP 位址。Listeners 根據 GKEIPRoute 的命名空間做為篩選器,其中存在 GKEIPRoute 物件。

    您可以選擇下列 Kubernetes 命名空間選取選項:

    • 所有命名空間:叢集中的任何 GKEIPRoute
    • 選取器GKEIPRoute 在符合特定標籤的 GKEIPRoute 命名空間中。
    • 相同命名空間:只有與 Gateway 位於相同 GKEIPRoute 命名空間的 GKEIPRoutes

以下範例提供叢集範圍的外部永久 IP 位址存取權,允許任何 Pod 使用這些位址。

將下列範例資訊清單儲存為 allowed-pod-ips.yaml

kind: Gateway
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
  namespace: default
  name: allowed-pod-ips
spec:
  gatewayClassName: gke-persistent-regional-external-managed

  listeners:
    - name: default
      port: 443
      protocol: none
      allowedRoutes:
        namespaces:
          from: All

  addresses:
    - value: "34.123.10.1/32"
      type: "gke.networking.io/cidr"
    - value: "34.123.10.2/32"
      type: "gke.networking.io/cidr"

其中:

  • addresses:列出所有權限由特定閘道管理的 IP 位址。
  • listeners:用於識別 GKEIPRoute 物件可參照這個閘道的命名空間。

將資訊清單套用至叢集:

kubectl apply -f allowed-pod-ips.yaml

步驟 4:(選用) 建立或識別具有額外網路的工作負載,以取得永久 IP 位址

如果您打算將永久 IP 位址用於需要連線至多個網路的 Pod,可以設定多網路 Pod,並建立網路物件,指出永久 IP 位址所屬的網路。

步驟 5:為所選工作負載建立 GKEIPRoute 物件

如要將永久 IP 位址指派給所選 Pod,請建立 GKEIPRoute 物件。

將下列範例資訊清單儲存為 my-ip-route.yaml

kind: GKEIPRoute
apiVersion: networking.gke.io/v1
metadata:
  namespace: default
  name: my-ip-route
spec:
  parentRefs:
  - name: allowed-pod-ips
    namespace: default
  addresses:
  - value: "34.123.10.1/32"
    type: "gke.networking.io/cidr"
  network: default
  reactionMode: ReadyCondition
  podSelector: # Only one pod is selected.
    matchLabels:
      component: proxy

其中:

  • parentRefs:指向用於持續性 IP 位址的閘道。這個欄位無法變更。
  • addresses:列出所有路由至以 podSelector 識別的 Pod 的持續性 IP 位址。這個欄位可變更。如果是 IPv4,則僅支援 /32 位址。
  • podSelector:指定用於識別 Pod 的標籤,持續性 IP 位址會路由至該 Pod。這個欄位可變動,且適用於 GKEIPRoute 所在的相同命名空間。如果選取多個 Pod,系統會額外考量兩個因素:Pod 建立時間 (GKE 會選取最新的 Pod) 和 reactionMode 欄位的設定。
  • reactionMode:指定在建立或刪除特定 Pod (由 podSelector 選取) 時,這項功能的行為。這個欄位為選填,預設值為 ReadyConditionReadyCondition 欄位無法變更。您可以設定 reactionMode,控管在建立、刪除或更新 Pod 時,這項功能的運作方式。
  • 網路:指向 Pod 上的網路介面,持續性 IP 位址會路由至該介面。這個欄位無法變更。

將資訊清單套用至叢集:

kubectl apply -f my-ip-route.yaml

將永久 IP 位址指派給 StatefulSet Pod

如要將永久 IP 位址指派給 StatefulSet 中的特定多重網路 Pod,請使用 Pod 的可預測主機名稱和 Kubernetes 的自動標記功能,如下列範例所示:

將下列範例資訊清單儲存為 my-pod-ips.yaml

kind: GKEIPRoute
apiVersion: networking.gke.io/v1
metadata:
  namespace: proxy-ss-ns
  name: my-pod-ips
spec:
  parentRefs:
  - name: allowed-pod-ips
    namespace: default
  addresses:
  - value: "34.123.10.1/32"
    type: "gke.networking.io/cidr"
  - value: "34.123.10.2/32"
    type: "gke.networking.io/cidr"
  network: blue-network
  reactionMode: ReadyCondition
  podSelector:
    matchLabels:
      statefulset.kubernetes.io/pod-name: proxy-ss-1
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  namespace: proxy-ss-ns
  name: proxy-ss
spec:
  selector:
    matchLabels:
      component: proxy
  serviceName: "proxy"
  replicas: 3
  template:
    metadata:
      annotations:
        networking.gke.io/default-interface: 'eth0'
        networking.gke.io/interfaces: '[{"interfaceName":"eth0","network":"default"}, {"interfaceName":"eth1","network":"blue-network"}]'
      labels:
        component: proxy
    spec:
      containers:
      - name: hello-app
        image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0

將資訊清單套用至叢集 (請確認您有名為「blue-network」的網路):

kubectl apply -f my-pod-ips.yaml

將永久 IP 位址指派給 Deployment Pod

如要將永久 IP 位址指派給 Deployment 中最新的 Pod,請套用下列設定的 GKEIPRoute

將下列範例資訊清單儲存為 my-pod-ips.yaml

kind: GKEIPRoute
apiVersion: networking.gke.io/v1
metadata:
  namespace: proxy-deploy-ns
  name: my-pod-ips
spec:
  parentRefs:
  - name: allowed-pod-ips
    namespace: default
  addresses:
  - value: "34.123.10.1/32"
    type: "gke.networking.io/cidr"
  - value: "34.123.10.2/32"
    type: "gke.networking.io/cidr"
  network: blue-network # point to the right network if you intend to use persistent-ip on additional networks
  reactionMode: ReadyCondition
  podSelector:
    matchLabels:
      component: proxy
---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: proxy-deploy-ns
  name: proxy-deploy
spec:
  selector:
    matchLabels:
      component: proxy
  replicas: 4 # Latest Pod is used
  template:
    metadata:
      # annotations:  <- Remove these lines if the pods are not multi-nic pods
      #   networking.gke.io/default-interface: 'eth0'
      #   networking.gke.io/interfaces: '[{"interfaceName":"eth0","network":"default"}, {"interfaceName":"eth1","network":"blue-network"}]'
      labels:
        component: proxy
    spec:
      containers:
      - name: hello-app
        image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0

將資訊清單套用至叢集:

kubectl apply -f my-ip-route.yaml

如果您使用其他網路,請確認您有名為「blue-network」的網路。

步驟 6:在 Pod 內使用持續性 IP 位址

使用 GKEIPRoute 將永久 IP 位址指派給 GKE Pod 後,應用程式不會自動使用這些 IP 位址。持續性 IP 位址是在網路路由層級處理,但 Pod 的預設設定不會知道這件事。您必須設定應用程式的設定,才能辨識及使用 Pod 內的位址。如要達成這個目標,Pod 必須具備權限。

如要設定應用程式,請考慮下列選項:

  • net.ipv4.ip_nonlocal_bind:修改系統設定,允許應用程式使用未直接指派給介面的 IP 位址。
  • ip address add:在應用程式邏輯中使用這個指令,手動將永久 IP 位址新增至介面。
  • 原始通訊端:如要進一步控管,應用程式可以直接與網路堆疊互動 (進階)。
  • 使用者空間 IP 位址堆疊:在特殊情況下,Pod 內可能會執行個別應用程式來管理 IP 位址 (非常進階)。

步驟 7:為持續性 IP 位址啟用 ARP (僅限預設網路)

如要產生有效的位址解析通訊協定 (ARP) 要求和回應,並使用預設網路上的持續性 IP 位址建立與 Pod 的新連線,您必須設定 ARP_ANNOUNCE 變數。

如要設定 ARP_ANNOUNCE 變數,請在 Pod 上執行下列指令:

echo "2" > /proc/sys/net/ipv4/conf/eth0/ARP_ANNOUNCE

其中 ARP_ANNOUNCE 變數會控管 ARP 宣告的處理方式。設為「2」可確保系統會針對持續性 IP 位址發布 ARP 宣告,讓網路上的其他裝置瞭解新的關聯。

在 Pod 變更期間自訂永久 IP 位址行為

本節說明建立或刪除目標 Pod 時,GKE Pod 的持續性 IP 位址會如何運作。GKE 控制器會監控 Pod 和 GKEIPRoute 設定。偵測到更新時,系統會根據您選擇的 reactionMode,自動將持續性 IP 位址重新指派給合適的 Pod。

瞭解永久 IP 位址功能如何自動處理 Pod 變更,以及可用的設定選項:

  • GKEIPRoute 設定的 reactionMode 欄位中,決定要使用 ReadyConditionExists。請根據應用程式的需求,考量 IP 位址的指派速度,以及嚴格的準備就緒規定。
  • 如果您使用 ReadyCondition 確保就緒狀態,請確認 Pod 已正確實作 Kubernetes 就緒探測器。否則,持續性 IP 位址可能無法正常運作。
  • 建議您監控 Pod 的狀態和 GKEIPRoute 物件的 Conditions 欄位,確保系統運作正常。true Ready 條件的狀態表示系統運作正常。

排解與 Pod 持續性 IP 位址的通訊問題

本節說明如何解決 Pod 的永久 IP 位址相關問題。

NoPodsFound 找不到相符的 Pod 時

症狀

GKEIPRoute 物件會指定 podSelector (一組標籤),用來識別與持續性 IP 位址相關聯的 Pod。NoPodsFound 狀態表示目標 GKEIPRoute's 命名空間中沒有任何具有相符標籤的 Pod。

可能原因

  • 標籤不正確:您打算搭配使用永久 IP 位址的 Pod 可能標籤錯誤,或完全沒有標籤。
  • 沒有 Pod:如果 reactionMode == Exists,請檢查 pod.Spec.nodeName 欄位,確認 Pod 是否已指派給節點。GKEIPRoute's 命名空間中可能沒有任何符合選取器的 Pod 正在執行。
  • Pod 未就緒:如果 reactionMode == ReadyCondition,請檢查 Pod 狀態是否為 READY。即使有相符的 Pod,如果該 Pod 不處於 Ready 狀態,就無法處理流量,因此不會被選取。

解決方法

  1. 檢查標籤:再次確認 GKEIPRoute's podSelector 中的標籤是否與您套用至目標 Pod 的標籤相符。
  2. 確認 Pod 是否存在:確認具有正確標籤的 Pod 確實存在於 Gateway 的 Listeners 所指定的 GKEIPRoute's 命名空間中。如果 reactionMode == Exists,請檢查 pod.Spec.nodeName 欄位,確認 Pod 是否已指派給節點
  3. 確認 Pod 完備性:如果 reactionMode == ReadyCondition,請檢查 Pod 狀態是否為 READY。使用下列指令,確認 Pod 處於 Ready 狀態:

    kubectl get pods -n <namespace>
    

    系統不會選取處於其他狀態的 Pod (例如「Pending」或「Error」)。

  4. 設定 Pod,以便在指派的持續性 IP 位址上回應。

Mutated 找到相符的 Pod,且正在進行永久 IP 位址程式設計

症狀

GKEIPRoute 狀態會顯示「已變動」,表示系統正在為相符的 Pod 設定持續性 IP 位址。

可能原因:

設定期間,系統會為持續性 IP 位址設定 GKE 資料路徑和資源,因此狀態會顯示為「已變動」。 Google Cloud

解決方法:

  1. 等待並重試:在大多數情況下,設定程序會在短時間內自動完成。等待一段時間後,請檢查狀態。成功後會變更為 Ready
  2. 進一步調查 (如有必要):如果「已變動」狀態持續一段時間,可能表示設定有誤。檢查其他狀態條件:GKEIPRoute
    • 已接受:指出 GKEIPRoute 設定是否有效。
    • DPV2Ready:指出節點上的資料路徑是否已正確程式設計。
    • GCPReady:指出 Google Cloud 資源是否已按照預期設定。

請在這些情況下尋找錯誤訊息,協助排解問題。

後續步驟