本頁說明如何為 Google Kubernetes Engine (GKE) 叢集啟用 GKE Dataplane V2,以及如何排解相關問題。
在 1.22.7-gke.1500 以上版本和 1.23.4-gke.1500 以上版本中,新的 Autopilot 叢集會啟用 GKE Dataplane V2。如果使用 GKE Dataplane V2 時遇到問題,請跳到「疑難排解」。
使用 GKE Dataplane V2 建立 GKE 叢集
使用 gcloud CLI 或 GKE API 建立 GKE 1.20.6-gke.700 以上版本的新叢集時,可以啟用 GKE Dataplane V2。使用 GKE 1.17.9 以上版本建立新叢集時,您也可以在搶先版中啟用 GKE Dataplane V2
控制台
如要使用 GKE Dataplane V2 建立新叢集,請執行下列工作:
前往 Google Cloud 控制台的「Create a Kubernetes cluster」(建立 Kubernetes 叢集) 頁面。
在「Networking」(網路) 區段中,勾選「Enable Dataplane V2」(啟用 Dataplane V2) 核取方塊。選取「啟用 Dataplane V2」時,「啟用 Kubernetes 網路政策」選項會停用,因為 GKE Dataplane V2 內建網路政策強制執行功能。
點選「建立」。
gcloud
如要使用 GKE Dataplane V2 建立新叢集,請執行下列指令:
gcloud container clusters create CLUSTER_NAME \
--enable-dataplane-v2 \
--enable-ip-alias \
--release-channel CHANNEL_NAME \
--location COMPUTE_LOCATION
更改下列內容:
CLUSTER_NAME:新叢集的名稱。CHANNEL_NAME:包含 GKE 1.20.6-gke.700 以上版本的發布管道。如果您不想使用發布管道,也可以使用--cluster-version標記 (而非--release-channel),並指定 1.20.6-gke.700 以上版本。COMPUTE_LOCATION:新叢集的 Compute Engine 位置。
API
如要使用 GKE Dataplane V2 建立新叢集,請在叢集 create 要求中,指定 networkConfig 物件的 datapathProvider 欄位。
下列 JSON 程式碼片段顯示啟用 GKE Dataplane V2 時所需的設定:
"cluster":{
"initialClusterVersion":"VERSION",
"ipAllocationPolicy":{
"useIpAliases":true
},
"networkConfig":{
"datapathProvider":"ADVANCED_DATAPATH"
},
"releaseChannel":{
"channel":"CHANNEL_NAME"
}
}
更改下列內容:
- VERSION:叢集版本,必須為 GKE 1.20.6-gke.700 以上版本。
- CHANNEL_NAME:包含 GKE 1.20.6-gke.700 以上版本的發布管道。
排解 GKE Dataplane V2 問題
本節說明如何調查及解決 GKE Dataplane V2 的問題。
確認已啟用 GKE Dataplane V2:
kubectl -n kube-system get pods -l k8s-app=cilium -o wide如果 GKE Dataplane V2 正在執行,輸出內容會包含前置字元為
anetd-的 Pod。anetd 是 GKE Dataplane V2 的網路控制器。如果問題與服務或網路政策強制執行有關,請檢查
anetdPod 記錄。在 Cloud Logging 中使用下列記錄選取器:resource.type="k8s_container" labels."k8s-pod/k8s-app"="cilium" resource.labels.cluster_name="CLUSTER_NAME"如果 Pod 建立作業失敗,請查看 kubelet 記錄檔,尋找相關線索。在 Cloud Logging 中使用下列記錄選取器:
resource.type="k8s_node" log_name=~".*/logs/kubelet" resource.labels.cluster_name="CLUSTER_NAME"將
CLUSTER_NAME替換為叢集名稱,或完全移除,即可查看所有叢集的記錄。如果
anetdPod 未執行,請檢查 cilium-config ConfigMap 是否經過任何修改。請避免變更這個 ConfigMap 中的現有欄位,因為這類變更可能會導致叢集不穩定,並中斷anetd。 只有在新增欄位時,ConfigMap 才會修補回預設狀態。系統不會修補現有欄位的任何變更,因此建議不要變更或自訂 ConfigMap。
已知問題
使用 GKE Dataplane V2 時,可能會遇到下列已知問題。
尚未就緒的 Pod 連線逾時
如果 Pod 尚未就緒,連線至相關聯的服務可能會逾時。這是 GKE Dataplane V2 的預期行為,與 kube-proxy 不同,後者可以傳回速度較快的 connection refused 錯誤。
GKE Dataplane V2 叢集發生與 NodePort 範圍衝突相關的間歇性連線問題
在 GKE Dataplane V2 叢集中,經過偽裝的流量或使用暫時性連接埠時,可能會發生間歇性連線問題。這些問題是因可能與保留的 NodePort 範圍發生連接埠衝突所致,通常會在下列情況發生:
自訂
ip-masq-agent:如果您使用自訂ip-masq-agent(2.10 以上版本),且叢集具有NodePort或負載平衡器服務,可能會因為與NodePort範圍衝突而發生間歇性連線問題。自 2.10 以上版本起,ip-masq-agent預設會實作--random-fully引數。為減輕這類問題的影響,請在ip-masq-agent設定的引數中,明確設定--random-fully=false(適用於 2.11 以上版本)。如需設定詳細資料,請參閱「在標準叢集中設定 IP 偽裝代理程式」。暫時性通訊埠範圍重疊:如果 GKE 節點上
net.ipv4.ip_local_port_range定義的暫時性通訊埠範圍與NodePort範圍 (30000-32767) 重疊,也可能引發連線問題。為避免這個問題,請確保這兩個範圍不會重疊。
檢查 ip-masq-agent 設定和暫時性通訊埠範圍設定,確保這些設定不會與 NodePort 範圍衝突。如果遇到間歇性連線問題,請考慮下列可能原因,並據此調整設定。
GKE Dataplane V2 叢集中的 hostPort 連線問題
受影響的 GKE 版本:1.29 以上版本
在採用 GKE Dataplane V2 的叢集中,如果流量以節點的 IP:Port 為目標,且通訊埠是 Pod 上定義的 hostPort,您可能會遇到連線失敗的問題。這些問題主要有兩種情況:
位於直通式網路負載平衡器後方的節點 (含
hostPort):hostPort會將 Pod 繫結至特定節點的通訊埠,而直通網路負載平衡器則會在所有節點之間分配流量。使用hostPort和直通式網路負載平衡器將 Pod 公開至網際網路時,負載平衡器可能會將流量傳送到 Pod 未執行的節點,導致連線失敗。這是因為 GKE Dataplane V2 的已知限制,直通式網路負載平衡器流量不會穩定轉送至hostPortPod。解決方法:使用直通式網路負載平衡器公開節點上 Pod 的
hostPort時,請在 Pod 的hostIP欄位中指定網路負載平衡器的內部或外部 IP 位址。ports: - containerPort: 62000 hostPort: 62000 protocol: TCP hostIP: 35.232.62.64 - containerPort: 60000 hostPort: 60000 protocol: TCP hostIP: 35.232.62.64 # Assuming 35.232.62.64 is the external IP address of a passthrough Network Load Balancer.hostPort與保留的NodePort範圍衝突:如果 Pod 的
hostPort與保留的NodePort範圍 (30000-32767) 衝突,Cilium 可能無法將流量轉送至 Pod。在 1.29 以上版本的叢集中,Cilium 現在會管理hostPort功能,取代先前的 Portmap 方法,因此會出現這種行為。這是 Cilium 的預期行為,公開說明文件中也有提及。
我們不打算在後續版本中修正這些限制。這些問題的根本原因與 Cilium 的行為有關,且超出 GKE 的直接控管範圍。
建議:建議您遷移至 NodePort 服務,而非 hostPort,以提升可靠性。NodePort 兩項服務提供類似功能。
網路政策的連接埠範圍未生效
如果叢集已啟用 GKE Dataplane V2,則在叢集的網路政策中指定 endPort 欄位不會生效。
Kubernetes Network Policy API 可讓您指定要強制執行網路政策的連接埠範圍。這個 API 適用於使用 Calico 網路政策的叢集,但不適用於使用 GKE Dataplane V2 的叢集。
將 NetworkPolicy 物件寫入 API 伺服器後,您可以讀取這些物件,驗證其行為。如果物件仍包含 endPort 欄位,系統就會強制執行這項功能。如果缺少 endPort 欄位,系統就不會強制執行這項功能。在所有情況下,API 伺服器中儲存的物件都是網路政策的可靠來源。
詳情請參閱 KEP-2079:網路政策支援的連接埠範圍。
已修正的版本
如要修正這個問題,請將叢集升級至 GKE 1.32 以上版本。
網路政策因連線追蹤查詢錯誤而捨棄連線
當用戶端 Pod 使用服務或內部直通網路負載平衡器的虛擬 IP 位址連線至自身時,由於資料平面中的 conntrack 查閱作業不正確,回覆封包不會識別為現有連線的一部分。這表示系統對封包強制執行網路政策,錯誤地限制 Pod 的連入流量。
這個問題的影響取決於服務設定的 Pod 數量。舉例來說,如果服務有 1 個後端 Pod,連線一律會失敗。如果服務有 2 個後端 Pod,連線失敗的機率為 50%。
已修正的版本
如要修正這個問題,請將叢集升級至下列其中一個 GKE 版本:
- 1.28.3-gke.1090000 以上版本。
解決方法
如要解決這個問題,請在 Service 資訊清單中將 port 和 containerPort 設定為相同的值。
髮夾連線流程的封包捨棄
當 Pod 使用服務建立與自身的 TCP 連線時 (也就是 Pod 同時是連線的來源和目的地),GKE Dataplane V2 eBPF 連線追蹤功能會錯誤追蹤連線狀態,導致 conntrack 項目洩漏。
如果連線元組 (通訊協定、來源/目的地 IP 和來源/目的地通訊埠) 遭到洩漏,使用相同連線元組的新連線可能會導致回傳封包遭到捨棄。
已修正的版本
如要修正這個問題,請將叢集升級至下列其中一個 GKE 版本:
- 1.28.3-gke.1090000 以上版本
- 1.27.11-gke.1097000 以上版本
解決方法
請使用下列其中一種解決方法:
針對可能使用 Service 與自身通訊的 Pod 中執行的應用程式,啟用 TCP 重複使用 (保持連線)。這樣就不會發出 TCP FIN 標記,避免洩漏 conntrack 項目。
使用短期連線時,請使用 Proxy 負載平衡器 (例如 Gateway) 公開 Pod,以便公開 Service。這會導致連線要求目的地設為負載平衡器 IP 位址,防止 GKE Dataplane V2 對迴路 IP 位址執行 SNAT。
升級 GKE 控制層會導致 anetd Pod 死結
如果 GKE 叢集已啟用 GKE Dataplane V2 (進階資料路徑),從 1.27 版升級至 1.28 版時,可能會發生死結情況。由於無法終止舊 Pod 或排定 anetd 等必要元件,工作負載可能會中斷。
原因
叢集升級程序會增加 GKE Dataplane V2 元件的資源需求。這項增加可能會導致資源爭用,進而中斷 Cilium 容器網路介面 (CNI) 外掛程式與 Cilium Daemon 之間的通訊。
問題
您可能會看到下列症狀:
anetdPod 仍處於Pending狀態。- 工作負載 Pod 卡在
Terminating狀態。 - 指出 Cilium 通訊失敗的錯誤,例如
failed to connect to Cilium daemon。 清除 Pod 沙箱的網路資源時發生錯誤,例如:
1rpc error: code = Unknown desc = failed to destroy network for sandbox "[sandbox_id]": plugin type="cilium-cni" failed (delete): unable to connect to Cilium daemon... connection refused
解決方法
標準叢集:如要解決問題並排定 anetd Pod,請暫時增加受影響節點的可分配資源。
如要找出受影響的節點,並檢查其可分配的 CPU 和記憶體,請執行下列指令:
kubectl get nodes $NODE_NAME -o json | jq '.status.allocatable | {cpu, memory}'如要暫時增加可分配的 CPU 和記憶體,請執行下列指令:
kubectl patch node $NODE_NAME -p '{"status":{"allocatable":{"cpu":CPU_VALUE, "memory":MEMORY_VALUE}}}'
Autopilot 叢集:如要解決 Autopilot 叢集的死結問題,請強制刪除受影響的 Pod,藉此釋出資源:
kubectl delete pod POD_NAME -n NAMESPACE --grace-period=0 --force
更改下列內容:
POD_NAME:Pod 的名稱。NAMESPACE:Pod 的命名空間。
增加節點上可分配的資源後,當從 GKE 1.27 版升級至 1.28 版完成時,anetd Pod 會在新版上執行。
後續步驟
- 瞭解如何使用網路政策記錄功能。
- 瞭解如何使用網路政策控管 Pod 和服務之間的通訊。
- 進一步瞭解 GKE Dataplane V2。
- 進一步瞭解 GKE Dataplane V2 觀測功能。
- 瞭解如何設定 GKE Dataplane V2 觀測功能。