本頁面說明如何在 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指令,取得最新版本。較舊的 gcloud CLI 版本可能不支援執行本文件中的指令。
為 GKE Pod 實作永久 IP 位址
GKE 中的永久 IP 位址可為 Pod 提供穩定的網路身分,即使 Pod 本身更新或移動,也不會受到影響。
本節會概述為 GKE Pod 導入永久 IP 位址的流程:
- 建立叢集:建立具有 Gateway API 和 GKE Dataplane V2 的叢集。
- 預留 IP 位址:決定您需要外部 (可公開存取) 或內部 (僅限 Google Cloud) IP 位址,並預留該位址。選擇與 GKE 叢集相同的區域。
- 建立閘道:設定 Kubernetes 閘道物件,其中包含預留的永久 IP 位址,並可建立規則 (
GKEIPRoutes),指定叢集中的哪些 Pod 可使用這些永久 IP 位址。 - 建立或識別永久 IP 位址的工作負載:如果您在額外網路上使用永久 IP 位址,請啟用多個網路介面並定義永久 IP 位址所在的網路,準備讓 Pod 使用永久 IP 位址。
- 為所選工作負載建立
GKEIPRoute物件:設定GKEIPRoute,將永久 IP 位址指派給特定 Pod。您可以使用標籤指定正確的 Pod,並視需要設定路由對 Pod 變更的反應方式。 - 設定 Application Awareness:在 Pod 中設定應用程式,主動使用持續性 IP 位址。
- 監控:追蹤閘道和
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-3REGION:這項要求適用的區域。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 物件。
- 建立適當類別的 Kubernetes Gateway 物件:
gke-persistent-regional-external-managed:外部 (公開) IP 位址。gke-persistent-regional-internal-managed,適用於內部 (僅限Google Cloud) IP 位址。gke-persistent-fast-regional-external-managed:適用於具備快速容錯移轉功能的外部 IP 位址。gke-persistent-fast-regional-internal-managed,適用於內部 (僅限 Google Cloud) IP 位址,並提供快速容錯移轉功能。
- 在閘道的地址部分,列出這個閘道管理的持續性 IP 位址 (Google 提供或 BYOIP)。
使用「
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/v1
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:
matchLabels:
component: proxy
nodeSelector: # Can only be specified when using fast failover Gateway Classes.
matchLabels:
component: proxy
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: default
name: proxy-deployment
spec:
replicas: 1
selector:
matchLabels:
component: proxy
template:
metadata:
# annotations: <- Include these lines if the pods are 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
其中:
- parentRefs:指向使用永久 IP 位址的閘道。這個欄位無法變更。
- addresses:列出所有轉送至
podSelector識別 Pod 的永久 IP 位址。這個欄位可以變更。IPv4 僅支援 /32 位址。 - podSelector:指定標籤,用於識別永久 IP 位址轉送至的 Pod。這個欄位可變動,且適用於
GKEIPRoute所在的相同命名空間。如果選取多個 Pod,系統會考量另外兩個因素:Pod 建立時間 (GKE 會選取最新的 Pod) 和reactionMode欄位的設定。 - reactionMode:指定建立或刪除特定 Pod (由
podSelector選取) 時,這項功能的行為。這個欄位為選填,預設值為ReadyCondition。ReadyCondition欄位無法變更。您可以設定reactionMode,控管這項功能在建立、刪除或更新 Pod 時的行為。 - network:指向 Pod 上的網路介面,永久 IP 位址會轉送至該介面。這個欄位為選填,預設值為
default。請注意,如果使用預設網路,network必須設為default。如果您使用其他網路,請將網路設為先前建立的網路物件名稱。這個欄位無法變更。 - nodeSelector:指定要預先設定的節點標籤,以便快速容錯移轉。使用快速容錯移轉閘道類別時,必須設定這個欄位,最多可選取 64 個節點。您必須確保具有永久 IP 位址的 Pod 已排定在這些節點上,通常是使用 Pod 的
nodeSelector。
將資訊清單套用至叢集:
kubectl apply -f my-ip-route.yaml
為 StatefulSet Pod 指派永久 IP 位址
如要將永久 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: <- Include these lines if the pods are 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
將資訊清單套用至叢集 (請確認您有名為「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: <- Include these lines if the pods are 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 內的位址。如要達成這個目標,Pod 必須具備權限。
你可以使用下列任一選項設定 Pod 規格:
修改
net.ipv4.ip_nonlocal_bindsysctl您可以修改系統設定,允許應用程式使用未直接指派給介面的 IP 位址,方法是在 Pod
securityContext中設定net.ipv4.ip_nonlocal_bindsysctl。如果應用程式可以繫結至不在介面上的 IP 位址,這個選項就很有用。在 Deployment 或 StatefulSet YAML 規格的
spec.template.spec下方,加入下列內容:securityContext: sysctls: - name: net.ipv4.ip_nonlocal_bind value: "1"將指派的 IP 位址新增至 Pod 介面
您可以使用 init 容器,手動將 GKEIPRoute 物件聲明的 IP 位址新增至其中一個 Pod 介面。這會讓 Pod 看到 IP 位址,彷彿是直接指派的位址。這需要
NET_ADMIN功能。在 Deployment 或 StatefulSet YAML 規格的
spec.template.spec下方,新增下列內容:initContainers: - name: configure-ips image: gcr.io/google.com/cloudsdktool/cloud-sdk:slim command: ['sh', '-c', 'ip address add ASSIGNED_IP/32 dev eth0'] securityContext: capabilities: add: - NET_ADMIN將
ASSIGNED_IP替換為指派給 GKEIPRoute 物件的其中一個 IP 位址。原始通訊端:如要進一步控管,應用程式可以直接與網路堆疊互動 (進階)。
使用者空間 IP 位址堆疊:在特殊情況下,Pod 內可能會執行獨立應用程式來管理 IP 位址 (非常進階)。
步驟 7:為指派的 IP 位址啟用 ARP (僅限預設網路)
如要產生有效的位址解析協定 (ARP) 要求和回應,並使用預設網路上 GKEIPRoute 物件指派的 IP 位址建立與 Pod 的新連線,您必須設定 arp_announce 變數。
如要設定 arp_announce 變數,請在 Pod 上執行下列指令:
echo "2" > /proc/sys/net/ipv4/conf/eth0/arp_announce
其中 arp_announce 變數控制 ARP 公告的處理方式。設為「2」可確保系統針對永久 IP 位址發出 ARP 公告,讓網路上的其他裝置得知新的關聯。
步驟 8:使用快速容錯移轉
如果使用具備快速容錯移轉功能的永久 IP 位址,可以從 Pod 發出 Gratuitous ARP (GARP),暫時將流量導向該 Pod。Google Cloud 會尊重該 GARP 約 20 分鐘。在這段期間,您必須更新叢集設定。如要執行這項操作,請在 GKEIPRoute 的 spec.podSelector 欄位中,將舊 Pod 的標籤替換為新 Pod 的標籤。
自訂 Pod 變更期間的永久 IP 位址行為
本節說明建立或刪除目標 Pod 時,GKE Pod 的持續性 IP 位址行為。GKE 控制器會監控 Pod 和 GKEIPRoute 設定。偵測到更新時,系統會根據您選擇的 reactionMode,自動將持續性 IP 位址重新指派給合適的 Pod。
瞭解持續性 IP 位址功能如何自動處理 Pod 變更,以及可用的設定選項:
- 在
GKEIPRoute設定的 reactionMode 欄位中,決定要使用 ReadyCondition 或 Exists。請考量應用程式的需求,例如 IP 位址的指派速度,以及嚴格的準備就緒規定。 - 如果您使用
ReadyCondition確保 readiness,請確認 Pod 已正確導入 Kubernetes 就緒探測。否則持續性 IP 位址可能無法正常運作。 - 建議您監控 Pod 的狀態和
GKEIPRoute物件的Conditions欄位,確保系統運作正常。「true」狀態表示「Ready」條件,代表系統運作正常。
排解 Pod 永久 IP 位址的通訊問題
本節說明如何解決 Pod 永久 IP 位址的相關問題。
NoPodsFound 找不到相符的 Pod 時
症狀
GKEIPRoute 物件會指定 podSelector (一組標籤),以識別哪些 Pod 與永久 IP 位址相關聯。NoPodsFound 狀態表示目標 GKEIPRoute's 命名空間中沒有具有相符標籤的 Pod。
可能原因
- 標籤不正確:您要使用永久 IP 位址的 Pod 可能標籤有誤,或根本沒有標籤。
- 沒有 Pod:如果
reactionMode == Exists,請檢查pod.Spec.nodeName欄位,確認 Pod 是否已指派給節點。GKEIPRoute's命名空間中可能沒有任何符合選取器的 Pod 正在執行。 - Pod 未就緒:如果
reactionMode == ReadyCondition,請檢查 Pod 狀態是否為READY。即使有相符的 Pod,如果不在Ready狀態,就無法放送流量,因此不會選取。
解決方法
- 檢查標籤:再次確認
GKEIPRoutepodSelector中的標籤是否與您套用至預期 Pod 的標籤相符。 - 確認 Pod 是否存在:確認具有正確標籤的 Pod 確實存在於 Gateway
Listeners指定的GKEIPRoute命名空間中。如果reactionMode == Exists為 0,請檢查pod.Spec.nodeName欄位,確認 Pod 是否已指派給節點 確認 Pod 準備就緒:如果顯示
reactionMode == ReadyCondition,請檢查 Pod 狀態是否為READY。使用下列指令,確認 Pod 處於Ready狀態:kubectl get pods -n <namespace>系統不會選取處於其他狀態的 Pod (例如「待處理」、「錯誤」)。
設定 Pod,在指派的持續性 IP 位址上回應。
Mutated 找到相符的 Pod,且正在進行持續性 IP 位址程式設計
症狀
GKEIPRoute 狀態會顯示「已變動」,表示系統正在為相符的 Pod 設定持續性 IP 位址。
可能原因:
設定期間,系統會為永久 IP 位址設定 GKE 資料路徑和 Google Cloud 資源,因此狀態會顯示「已變動」。
解決方法:
- 等待並重試:在大多數情況下,設定程序會在短時間內自動完成。請稍後再查看狀態。成功後會變更為
Ready。 - 進一步調查 (如有必要):如果「Mutated」狀態持續一段時間,可能表示設定有誤。檢查其他狀態條件:
GKEIPRoute- 已接受:指出
GKEIPRoute設定是否有效。 - DPV2Ready:指出節點上的資料路徑是否已正確程式設計。
- GCPReady:指出 Google Cloud 資源是否已按照預期設定。
- 已接受:指出
請在這些情況下尋找錯誤訊息,協助排解問題。
已傳送 GARP,但 Pod 未收到流量
症狀
您已從新的 Pod 傳送 GARP,但流量仍未改變。GKEIPRoute 狀態仍為「就緒」,且未顯示錯誤。
可能原因
Pod 所在的節點不符合 GKEIPRoute 中的 nodeSelector。GARP 使用的 IP 位址與 GKEIPRoute 無關。
解析度
- 驗證 Pod 的節點:確認 Pod 在符合
GKEIPRoute設定中nodeSelector的節點上執行。如果 Pod 不在相符的節點上,則該節點可能未針對GKEIPRoute進行程式設計。 - 驗證 GARP 的 IP 位址:確認 GARP 中的 IP 位址是
GKEIPRoute的位址欄位中指定的 IP 位址之一。如果 IP 位址未與GKEIPRoute建立關聯,快速容錯移轉機制就不會觸發。
後續步驟
- 請參閱「關於 GKE Pod 的永久 IP 位址」一文
- 請參閱「為 Pod 設定多網路支援功能」一文。