本文件提供操作說明和診斷程序,說明如何使用 GKE Dataplane V2 觀測能力、Hubble 和 Cloud Monitoring,診斷 Google Kubernetes Engine (GKE) 叢集中的網路問題。
如需架構總覽和概念最佳做法,請參閱「網路觀測能力最佳做法」。
疑難排解決策樹和核心概念
查看程序前,請先使用下列決策矩陣,找出可能導致問題的 GKE 網路堆疊層級,然後前往對應章節。
| 症狀或診斷型問題 | 疑似層級 | 建議程序 |
|---|---|---|
Pod 無法解析外部網域或內部 Kubernetes Service (DNS 逾時、NXDOMAIN、SERVFAIL)。 |
第 1 層:Pod 和 Service (DNS) | 診斷 DNS 解析失敗 |
| 服務無法通訊;Pod 之間連線逾時或封包遺失。 | 第 1 層:Pod 和 Service (政策或封包捨棄) | 診斷封包捨棄和 NetworkPolicy 封鎖問題 |
工作負載副本的流量負載不平均,或 Pod 記錄的 TCP 重設率偏高 (RST)。 |
第 1 層:Pod 和服務 (負載平衡或傳輸) | 診斷流量不平衡和 TCP 重設 |
| 一般延遲、間歇性逾時,或節點間 CNI 重新啟動。 | 第 2 層:節點和 CNI (核心) | 分類節點層級延遲和 CNI 瓶頸 |
| Pod 無法連上 GKE 以外的資源 (Cloud SQL、外部 API 或其他虛擬私有雲)。 | 第 3 級:虛擬私有雲和轉送 | 區隔 GKE 與虛擬私有雲或外部連線問題 |
| 需要自動路徑模擬,確認防火牆規則、路徑或 NetworkPolicies 是否會封鎖流量。 | 第 3 級:虛擬私有雲和轉送 (模擬) | 使用 Connectivity Tests 診斷連線能力 |
| 需要找出哪些工作負載會將流量傳送至網際網路,並進行網路位址轉譯 (NAT)。 | 第 4 級:對外閘道和費用 | 識別 NAT 流量 (輸出至網際網路) |
| 可用區間資料移轉費用高昂,或需要以圖表呈現主要通訊者,但不想編寫 SQL 查詢。 | 第 4 級:對外閘道和費用 | 使用 Flow Analyzer 分析叢集流量費用和效能 |
核心網路概念
如果您剛開始使用 Kubernetes 或 Google Cloud 網路,請牢記下列核心概念:
- eBPF (Extended Berkeley Packet Filter):一種作業系統技術,可直接在 Linux 核心中執行安全監控和轉送程式。GKE Dataplane V2 使用 eBPF 轉送封包及強制執行 NetworkPolicies,效能負擔極低。
- IP 偽裝 (SNAT):重寫封包來源 IP 位址的程序。當 GKE Pod (具有私人 IP 位址) 與網際網路或外部 VPC 資源通訊時,GKE 會將 Pod IP 位址偽裝 (重寫) 為節點 IP 位址,讓外部系統知道如何轉送回覆。
- 連線追蹤 (Conntrack):這項核心功能可追蹤所有有效的網路連線。在 GKE Dataplane V2 叢集中,這項追蹤作業會分散在兩個資料表之間:標準 Linux 核心 conntrack (由
ip-masq-agent使用),以及儲存在 eBPF 對應中的 Cilium 和 GKE Dataplane V2 代管 conntrack 資料表。如果節點處理過多並行連線,其中一個追蹤表格可能會填滿 (conntrack 耗盡),導致節點自動捨棄新封包。 - Hubble:GKE Dataplane V2 的觀測能力引擎。它在 eBPF 上執行,可即時掌握流量、封包捨棄和 NetworkPolicy 評估。
第 1 級:Pod 和 Service (應用程式) 觀測能力
Pod 和 Service 層涵蓋 Pod、Service 和叢集 DNS 之間的網路通訊。這個層級的問題通常會導致應用程式連線逾時、名稱解析失敗或負載分配不均。
診斷 DNS 解析失敗
排解 DNS 問題前,請先查看診斷範圍和必要條件:
- 重點領域:Pod 與 CoreDNS 或 NodeLocal DNSCache 之間的通訊、DNS 延遲時間、上游 DNS 解析逾時,以及 FQDN NetworkPolicy 驗證。
- 必要條件:啟用 GKE Dataplane V2 指標;具備
kubectl存取權。 - CNI 相容性:GKE Dataplane V2 (Advanced Datapath) 和標準 GKE CNI。
- 症狀:Pod 記錄
dial tcp: lookup <domain>: i/o timeout、NXDOMAIN,或傳出 API 呼叫間歇性延遲。 - 目標:判斷 DNS 失敗是否源自叢集內部 (
kube-dns或 NodeLocal DNSCache 飽和)、NetworkPolicy 封鎖 UDP 或 TCP 通訊埠 53,或上游網路效能降低。
步驟 1:基本連線能力檢查
排解 DNS 層問題前,請先確認是否能從受影響的 Pod 內,直接使用 IP 位址連上目的地:
# 1. Test raw IP reachability (bypasses DNS entirely)
kubectl exec -it my-pod -n default -- curl -v --connect-timeout 5 http://10.240.0.10:8080
# 2. Test domain resolution
kubectl exec -it my-pod -n default -- curl -v --connect-timeout 5 http://my-service.default.svc.cluster.local:8080
- 如果 IP 連線成功,但網域連線失敗:問題僅限於 DNS 解析層。繼續執行步驟 2。
- 如果兩者都失敗:問題出在網路層級轉送或政策強制執行。請參閱「診斷封包遺失和 NetworkPolicy 封鎖問題」一節。
檢查 FQDN NetworkPolicy DNS 預先填入
如果叢集使用以 FQDN 為基礎的 NetworkPolicies (FQDNNetworkPolicy),請確認網域名稱已明確允許。如果 Pod 查詢的外部網域未預先填入 GKE Dataplane V2 DNS Proxy 快取,或未經政策允許,GKE Dataplane V2 會封鎖傳送至解析 IP 位址的輸出流量:
# Verify whether UDP or TCP port 53 egress is permitted in the Pod's namespace
kubectl get networkpolicy -n default -o yaml | grep -A 5 -B 2 "port: 53"
步驟 2:在 Cloud Monitoring 中查看 DNS 指標
GKE 會在 Cloud Monitoring 中,以 kubernetes.io/networking/dns/ 前置字元公開內建 DNS 指標。
如要在 Cloud Monitoring 中查看 DNS 指標,請按照下列步驟操作:
- 在 Google Cloud 控制台,依序前往「Cloud Monitoring」>「Dashboards」(資訊主頁)。
- 選取預先定義的「GKE DNS Observability - Cluster View」資訊主頁 (或前往「Metrics Explorer」並篩選
kubernetes.io/networking/dns/)。 - 評估下列主要信號 (如果是 NodeLocal DNSCache,請將指標路徑中的
kubedns替換為node_local_dns):
| 指標名稱 | 警告性問題門檻 | 根本原因 |
|---|---|---|
kubernetes.io/networking/dns/kubedns/max_concurrent_rejected_request_count |
> 0 | 已達並行查詢數量上限。kube-dns 或 NodeLocal DNSCache 正在捨棄查詢。 |
kubernetes.io/networking/dns/kubedns/dns_request_latencies |
p99 > 100 毫秒 | kube-dns 或 NodeLocal DNSCache 的端對端 DNS 解析延遲時間過長。 |
kubernetes.io/networking/dns/kubedns/forwarding_request_latencies |
p99 > 100 毫秒 | 上游 DNS 伺服器延遲或飽和。 |
DNS 效能和逾時分類序列
請按照下列分類順序,診斷 DNS 延遲、快取失敗和上游逾時問題:
- 查看快取命中率:依
cache_status標籤分組的查詢kubernetes.io/networking/dns/kubedns/dns_cache_request_count(或node_local_dns/dns_cache_request_count)。如果cache_status="hit"偏低,而cache_status="miss"偏高,應用程式可能會發出非 FQDN 查詢 (例如my-service,而非my-service.default.svc.cluster.local),導致搜尋路徑周遊/etc/resolv.conf中的所有項目。 - 評估上游延遲時間:如果
forwarding_request_latencies偏高,表示上游 DNS 伺服器有問題 (例如透過 Cloud Interconnect 或 Cloud VPN 存取企業地端部署 DNS,或 Cloud DNS 限制)。 稽核自訂 DNS 覆寫:檢查自訂
kube-dnsConfigMap,確認虛設常式或上游轉送設定是否正確:kubectl get configmap kube-dns -n kube-system -o yaml
步驟 3:使用 Hubble CLI 串流即時 DNS 流量
使用 Hubble CLI 輔助別名,檢查從節點核心串流傳輸的即時 DNS 要求和回應:
# 1. Ensure the helper alias is set in your terminal session
alias gke-hubble="kubectl exec -it -n gke-managed-dpv2-observability deployment/hubble-relay -c hubble-cli -- hubble"
# 2. Observe live DNS (Port 53) traffic for a specific Pod
gke-hubble observe --pod default/my-pod --port 53
步驟 4:驗證修正結果
如果發生並行查詢遭拒的情況,請套用 NodeLocal DNSCache,直接在節點上吸收高頻率的 DNS 查詢,而不觸發叢集層級的 kube-dns 限制:
# Verify NodeLocal DNSCache DaemonSet is running
kubectl get daemonset node-local-dns -n kube-system
診斷封包遺失和 NetworkPolicy 封鎖問題
調查封包遺失和政策拒絕問題前,請先詳閱診斷範圍和必要條件:
- 重點領域:Pod 物件之間或 Pod 與 Service 物件之間的流量捨棄、NetworkPolicy 強制執行、核心 eBPF 捨棄原因。
- 必要條件:啟用 GKE Dataplane V2 流量觀測功能;設定 NetworkPolicy 記錄。
- CNI 相容性:僅限 GKE Dataplane V2。
- 症狀:應用程式連線嘗試失敗,並顯示
Connection timed out或Connection reset by peer。 - 目標:找出封包遭到捨棄的確切 NetworkPolicy 或 eBPF 原因,不必反覆嘗試變更安全性政策。
步驟 1:監控 Hubble 掉線指標
GKE Dataplane V2 捨棄封包時,會發出指標 hubble_drop_total,並標記捨棄原因、來源和目的地中繼資料。如要監控 Hubble 捨棄指標,請按照下列步驟操作:
如果尚未設定,請部署 Google Cloud Managed Service for Prometheus
PodMonitoring資源,以便抓取 Hubble 指標:apiVersion: monitoring.googleapis.com/v1 kind: PodMonitoring metadata: name: hubble-metrics namespace: gke-managed-dpv2-observability spec: selector: matchLabels: k8s-app: cilium endpoints: - port: hubble-metrics interval: 30s在「Cloud Monitoring」>「Metrics Explorer」中執行下列查詢,依原因查看捨棄情形:
sum by (reason) (rate(hubble_drop_total[5m])) > 0解讀常見的
reason代碼:Policy denied:Kubernetes NetworkPolicy 明確或隱含地封鎖連線。CT: Map insertion failed:連線追蹤 (conntrack) 表格已用盡。Unsupported L3 protocol:非 IPv4 或 IPv6 封包,或標頭損毀。
步驟 2:在 Cloud Logging 查看 NetworkPolicy 記錄
NetworkPolicy 記錄會匯出所有政策決策的結構化 JSON 記錄。如要在 Cloud Logging 中查詢 NetworkPolicy 記錄,請按照下列步驟操作:
- 在 Google Cloud 控制台中,依序前往「Cloud Logging」>「Logs Explorer」。
執行以下查詢:
resource.type="k8s_node" log_name:"projects/PROJECT_ID/logs/events" jsonPayload.connection.verdict="DENY" jsonPayload.src.pod_name="my-source-pod"檢查 JSON 酬載:
jsonPayload.drop_reason::顯示封包遭到捨棄的原因。jsonPayload.policies:列出已評估的 NetworkPolicy。如果傳回空白清單且判定結果為DENY,則命名空間會以預設拒絕模式運作,且沒有任何政策允許流量。
如果沒有顯示任何 NetworkPolicy 記錄,請確認叢集的 NetworkLogging 自訂資源已啟用記錄功能。例如,確認 spec.cluster.deny.log 欄位是否設為 true:
kubectl get networklogging default -o yaml
步驟 3:使用 Hubble CLI 追蹤即時丟棄
使用 Hubble CLI 檢查即時封包,直接串流即時捨棄作業:
gke-hubble observe --verdict DROPPED --namespace default --follow
輸出內容範例:
TIMESTAMP SOURCE DESTINATION TYPE VERDICT
10:14:22.102 default/frontend default/backend:80 to-stack DROPPED (Policy denied by NetworkPolicy: backend-deny-all)
輸出內容會指出封鎖流量的確切 NetworkPolicy (backend-deny-all)。
步驟 4:檢查 conntrack 是否耗盡
如果捨棄原因顯示 CT: Map insertion failed:
檢查 GKE Dataplane V2 代理記錄,確認 conntrack 資料表是否飽和:
kubectl logs -n kube-system daemonset/anetd -c cilium-agent --tail=100 | grep "Conntrack table full"檢查受影響節點上 conntrack 資料表的大小上限:
kubectl exec -it -n kube-system daemonset/anetd -c cilium-agent -- cilium status --all-controllers | grep -i conntrack如果 conntrack 資料表已滿,請將工作負載水平擴展至更多節點,或降低用戶端 Pod 的連線速率。
診斷流量不平衡和 TCP 重設
排解流量不平衡和連線重設問題前,請先查看診斷範圍和必要條件:
- 重點領域:負載平衡不均、TCP 握手失敗、連線突然終止。
- 必要條件:已啟用 GKE Dataplane V2 指標。
- CNI 相容性:GKE Dataplane V2。
- 症狀:特定 Pod 副本接收過多流量,其他副本則保持閒置;用戶端應用程式記錄
connection reset by peer或broken pipe。 - 目標:判斷流量不平衡的原因,是傳輸層 (OSI 第 4 層,TCP) 還是應用程式層 (OSI 第 7 層,HTTP/2 或 gRPC) 的連線黏性,並找出 TCP RST 封包的來源。
步驟 1:比較 Pod 層級流量
如要判斷流量是否平均分配給各個副本,請按照下列步驟操作:
在 Cloud Monitoring 中,查詢 Deployment 中所有 Pod 的輸入流量:
sum by (pod) (rate(pod_flow_ingress_flows_count{destination_workload="my-service"}[5m]))評估 Pod 之間的流量分配。如果單一 Pod 接收大部分流量,請調查連線重複使用或黏性工作階段:
- gRPC 或 HTTP/2:長期 TCP 連線會導致所有要求周遊單一 TCP 串流,傳送至一個後端 Pod。傳輸層 (OSI 第 4 層,TCP) Kubernetes Service 路由無法平衡已建立 HTTP/2 連線內的要求。
- ClientIP 工作階段相依性:確認 Service 是否已設定
sessionAffinity: ClientIP。 - 無頭服務:用戶端可能會解析 DNS 一次,並永久快取單一 IP 位址。
步驟 2:分析 TCP 重設指標
TCP 重設 (RST) 會立即終止連線。當端點收到未知通訊埠的封包,或應用程式關閉緩衝區中含有未讀取資料的連線時,作業系統核心就會發出這些封包。
在 Cloud Monitoring 中執行下列 MQL 查詢:
fetch prometheus_target
| metric 'prometheus.googleapis.com/hubble_tcp_flags_total/counter'
| filter (metric.flag == 'RST')
| align rate(1m)
| every 1m
| group_by [metric.source, metric.destination, metric.traffic_direction], sum(val())
查看查詢結果,判斷重設來源:
- 傳出 RST (traffic_direction=
egress):本機 Pod 正在產生重設。檢查 Pod 應用程式是否當機、達到連線限制,或主動拒絕連線。 - 傳入 RST (traffic_direction=
ingress):遠端對等互連 (外部資料庫、API 或遠端 Pod) 傳送重設。檢查目的地伺服器健康狀態和防火牆狀態。
步驟 3:即時串流 TCP 重設
使用 Hubble CLI 擷取即時重設交握:
gke-hubble observe --type trace --verdict FORWARDED --tcp-flags RST --namespace default
Step 4: Remediation and actionable fixes
請根據流量不平衡或 TCP 重設的原因,採取下列補救措施:
- 應用程式層 (OSI 第 7 層) 或 gRPC 連線黏性:
- 部署 Cloud Service Mesh,啟用應用程式層 (OSI 第 7 層) 要求層級負載平衡。
- 設定用戶端連線限制或 Keep-Alive 逾時 (例如 gRPC
MAX_CONNECTION_AGE和MAX_CONNECTION_AGE_GRACE),強制定期重新建立連線。
- 服務 IP 相似度:除非應用程式狀態嚴格要求,否則請移除
service.spec.sessionAffinity。 - 針對無頭 Service DNS 快取:確保應用程式執行階段 (例如 JVM
networkaddress.cache.ttl) 不會無限期快取 DNS 結果。 - 應用程式待處理佇列溢位:當應用程式監聽佇列已滿時,Linux 核心會捨棄傳入的 SYN 封包或傳送 TCP RST。水平擴展 Pod 副本,或增加應用程式監聽待處理項目 (
somaxconn)。
第 2 級:節點和 CNI (核心) 觀測能力
節點和 CNI 層包含主機 Linux 核心、eBPF 程式和節點網路介面。這個層級的瓶頸會影響在受影響節點上執行的所有工作負載。
系統完整性檢查:偵測 anetd 是否有未經授權的修補
GKE Dataplane V2 會在 kube-system 命名空間中,以代管 DaemonSet (anetd) 的形式執行。在 Cloud Logging 中,您可以查詢 Kubernetes 稽核記錄,偵測未經授權的使用者或自動化指令碼是否已修補或重新啟動 anetd:
protoPayload.methodName="io.k8s.core.v1.daemonsets.patch" OR
protoPayload.methodName="io.k8s.core.v1.daemonsets.update"
protoPayload.resourceName="namespaces/kube-system/daemonsets/anetd"
如果偵測到未經授權的修補,請將 DaemonSet 還原為預設設定,或觸發節點集區重新建立作業,以還原代管狀態。
分類節點層級延遲時間和 CNI 瓶頸
診斷節點層級延遲時間和核心瓶頸前,請先詳閱診斷範圍和必要條件:
- 重點領域:主機核心延遲時間、VM 介面封包遺失、GKE Dataplane V2 eBPF 代理程式飽和、conntrack 耗盡。
- 必要條件:已啟用 Compute Engine VM 指標;具備
kubectl存取權。 - CNI 相容性:GKE Dataplane V2 和標準 GKE CNI。
- 症狀:跨節點流量的延遲時間大幅增加或隨機下降,而節點內流量則維持正常。
- 目標:區分主機 VM 網路節流、Linux 核心捨棄和 CNI 層級瓶頸。
步驟 1:區分 GKE 內外的問題
執行 Compute Engine VM 基準測試:在與 GKE 叢集節點相同的虛擬私有雲子網路中,部署獨立 Compute Engine VM。測試從 VM 到目標目的地的連線。
- 如果獨立 VM 發生相同的封包遺失或延遲問題:問題位於 GKE 外部 (虛擬私有雲防火牆、Cloud NAT、Cloud Interconnect 或外部伺服器)。請繼續參閱「區分 GKE 與虛擬私有雲或外部連線問題」。
- 如果獨立 VM 正常通訊,但 GKE Pod 失敗:問題出在 GKE 內部 (節點層級 eBPF、conntrack 或 CNI)。繼續執行步驟 2。
步驟 2:區分應用程式問題與節點和 CNI 層級問題
如要判斷延遲時間是源自應用程式,還是節點和 CNI 層,請按照下列步驟操作:
檢查應用程式資源飽和度:確認節點未發生 CPU 節流或記憶體壓力,導致使用者空間中的封包處理作業延遲:
kubectl top nodes kubectl top pods -n default檢查 Linux 核心 conntrack 計數:查看主機上的有效 conntrack 計數:
# On a node where you have debugging access cat /proc/sys/net/netfilter/nf_conntrack_count cat /proc/sys/net/netfilter/nf_conntrack_max如果
nf_conntrack_count接近nf_conntrack_max,主機核心會捨棄新的 TCP SYN 封包。
步驟 3:使用 Compute Engine 遙測功能,驗證 VM 層級封包捨棄情形
Google Cloud Compute Engine 會將 VM 層級的網路介面指標匯出至 Cloud Monitoring。
在 Cloud Monitoring > Metrics Explorer 中,查詢:
sum by (drop_reason) (rate(compute_googleapis_com:instance_network_dropped_packets_count[5m]))
FQ_CODEL_DROP:因公平佇列或 CoDel 佇列飽和而捨棄封包 (超出 VM egress 頻寬限制)。FIREWALL_RULE_DROP:封包遭虛擬私有雲防火牆規則捨棄。RATE_LIMIT_DROP:封包遭到捨棄,因為 VM 超過網路介面的每秒封包數 (PPS) 上限配額。
步驟 4:使用 eBPF 調查核心層級捨棄
如果 VM 層級指標顯示零捨棄,但 GKE Pod 仍捨棄封包,請檢查 GKE Dataplane V2 代理程式 (anetd) 是否有 eBPF 對應捨棄:
kubectl logs -n kube-system daemonset/anetd -c cilium-agent --tail=200 | grep -i "drop"
尋找 ct-map-insertion-failed 或 fib-lookup-failed。
第 3 級:虛擬私有雲和路由 (雲端網路) 觀測能力
虛擬私有雲和 Cloud Router 層會將 GKE 節點連結至其他 Google Cloud 服務、地端部署網路和網際網路。這裡的失敗通常源自虛擬私有雲防火牆規則、自訂路由或閘道設定。
區分 GKE 與虛擬私有雲或外部連線問題
請先查看診斷範圍和必要條件,再區分外部網路問題和叢集內故障:
- 重點領域:Kubernetes 內部轉送和虛擬私有雲雲端轉送之間的邊界隔離。
- 必要條件:gcloud CLI;建立 Connectivity Tests 的權限。
- CNI 相容性:所有叢集。
- 症狀:Pod 無法連線至外部資源 (例如 Cloud SQL、地端部署 API 或第三方端點)。
- 目標:快速判斷封包遺失是發生在 GKE 節點內,還是 Google Cloud 虛擬私有雲或外部網路內。
步驟 1:Compute Engine VM 基準測試
如要部署基準 VM,並評估問題是否在 GKE 以外持續發生,請按照下列步驟操作:
在與 GKE 節點集區相同的虛擬私有雲子網路和可用區中,部署臨時 Compute Engine VM 執行個體:
gcloud compute instances create gke-baseline-tester \ --zone=us-central1-a \ --subnet=gke-subnet \ --machine-type=e2-micro使用 SSH 連線至執行個體,並測試與目的地的連線能力:
curl -v --connect-timeout 5 https://api.example.com評估結果:
- 如果 Compute Engine VM 無法連線:問題出在虛擬私有雲或外部網路 (防火牆規則、轉送表、Cloud NAT IP 耗盡或外部 IP 許可清單)。
- 如果 Compute Engine VM 連線成功:問題出在 GKE 內部 (NetworkPolicy 封鎖輸出、非偽裝 Pod CIDR 或容器層級 DNS)。
步驟 2:執行 Connectivity Tests 隨選測試
從節點 VM 執行 Google Cloud Connectivity Tests 測試,連至目的地:
gcloud network-management connectivity-tests create test-node-to-dest \
--source-instance=projects/PROJECT_ID/zones/us-central1-a/instances/gke-baseline-tester \
--destination-ip-address=203.0.113.10 \
--destination-port=443 \
--protocol=TCP \
--round-trip
在 Google Cloud 控制台中查看結果,確認是否有虛擬私有雲防火牆規則或路徑捨棄流量。
使用 Connectivity Tests 診斷連線
Connectivity Tests 會模擬 GKE 和虛擬私有雲資源之間的封包路徑,不會傳送實際流量。這項模擬會評估 Service ClusterIP 到 Pod DNAT 解析、GKE Dataplane V2 NetworkPolicy 輸入和輸出規則,以及節點 IP 偽裝 (SNAT)。執行自動化路徑模擬前,請先查看診斷範圍和必要條件:
- 重點領域:GKE Pod、Service、NetworkPolicy 和虛擬私有雲路徑的自動化靜態路徑模擬。
- 必要條件:已啟用 Network Intelligence Center 和 Network Management API。
- CNI 相容性:GKE Dataplane V2 (強化分析)。
- 症狀:連線無故中斷,但手動檢查時所有設定都正常。
- 目標:靜態模擬及追蹤從 Pod 來源到目的地的完整封包路徑,找出導致捨棄的確切政策行。
情境 A:確認 GKE NetworkPolicy 是否封鎖指標收集作業
從安全命名空間中的 Pod 抓取指標時,Google Cloud Managed Service for Prometheus 收集器可能會遭到預設拒絕的 NetworkPolicy 封鎖:
gcloud network-management connectivity-tests create test-gmp-to-pod \
--source-ip-address=10.0.0.15 \
--destination-gke-pod=projects/PROJECT_ID/locations/LOCATION/clusters/CLUSTER_NAME/k8s/namespaces/prod/pods/backend-pod \
--destination-port=8080 \
--protocol=TCP \
--round-trip
在 Google Cloud 控制台中檢查測試追蹤記錄。如果測試在 GKE Network Policy evaluation 步驟終止,並顯示 DROP,則必須新增輸入規則,允許來自收集器 Pod 的流量。
情境 B:驗證 GKE 服務的可連性
模擬從用戶端 VM 到內部 Kubernetes 服務的可連性:
gcloud network-management connectivity-tests create test-vm-to-service \
--source-instance=projects/PROJECT_ID/zones/us-central1-a/instances/client-vm \
--destination-ip-address=10.96.0.100 \
--destination-port=80 \
--protocol=TCP \
--round-trip
模擬追蹤記錄會顯示:
- 虛擬私有雲路由比對。
- 虛擬私有雲防火牆輸出和輸入允許。
- 抵達 GKE 節點。
- Service DNAT 至後端 Pod IP 位址。
- 評估後端 Pod 的輸入 NetworkPolicy。
情境 C:診斷 Pod 至網際網路的輸出問題
如果 Pod 無法連上網際網路上的外部 API:
建立從 Pod 到外部公開 IP 位址 (例如
8.8.8.8) 的測試:gcloud network-management connectivity-tests create test-pod-to-internet \ --source-gke-pod=projects/PROJECT_ID/locations/LOCATION/clusters/CLUSTER_NAME/k8s/namespaces/prod/pods/app-pod \ --destination-ip-address=8.8.8.8 \ --destination-port=53 \ --protocol=UDP \ --round-trip檢查 drop point:
- 在 NetworkPolicy 遭到捨棄:Pod 缺少允許流量傳送至
0.0.0.0/0的輸出 NetworkPolicy。 - 在虛擬私有雲防火牆遭到捨棄:虛擬私有雲防火牆規則拒絕節點子網路的傳出流量。
- 在 Cloud NAT 或路由中遭到捨棄:子網路缺少通往網際網路閘道的預設路由,或未設定 Cloud NAT。
- 在 NetworkPolicy 遭到捨棄:Pod 缺少允許流量傳送至
第 4 級:外部閘道和費用 (網際網路和網路位址轉譯) 觀測能力
外部閘道層級會透過 Cloud NAT 或外部閘道,管理傳送至公開網際網路目的地的傳出流量。這個層級的觀測能力有助於找出高輸出工作負載,並控管資料移轉費用。
識別 NAT 流量 (輸出至網際網路)
分析傳出網際網路和 NAT 流量前,請先詳閱診斷範圍和必要條件:
- 重點領域:傳出網際網路流量、Cloud NAT 通訊埠使用率、外部資料移轉費用。
- 必要條件:已啟用 GKE Dataplane V2 流量觀測功能。
- CNI 相容性:GKE Dataplane V2。
- 症狀:Cloud NAT 通訊埠耗盡錯誤,或傳出至網際網路的輸出費用異常高昂。
- 目標:找出哪些 GKE Pod 和 Service 物件正在將流量傳輸至外部網際網路端點。
步驟 1:瞭解 GKE Dataplane V2 的「to-stack」和「world」概念
在 GKE Dataplane V2 中:
world:代表 GKE 叢集和虛擬私有雲 (公開網際網路) 以外的任何目的地。to-stack:代表封包從 eBPF 容器 veth 介面轉換至主機 Linux 網路堆疊,在到達 Cloud NAT 之前進行 IP 偽裝 (SNAT)。
步驟 2:使用 Hubble CLI 串流及篩選 NAT 流量
串流傳輸源自叢集的傳出網際網路流量:
# Stream egress flows heading to external internet ("world")
gke-hubble observe \
--traffic-direction egress \
--verdict FORWARDED \
--to-identity world \
--follow
輸出內容範例:
TIMESTAMP SOURCE DESTINATION TYPE VERDICT
10:25:01.120 default/worker-pod 142.250.190.46:443 to-stack FORWARDED
如要找出傳出流量最多的通訊者,您也可以將 Hubble JSON 輸出內容傳送至 jq,依 Pod 計算外部輸出流量:
timeout 60s gke-hubble observe \
--traffic-direction egress \
--verdict FORWARDED \
--to-identity world \
-o json | jq -r '.flow.source.namespace + "/" + .flow.source.pod_name' | sort | uniq -c | sort -nr | head -n 10
步驟 3:使用指標監控外部流量
在 Cloud Monitoring 中,追蹤外部流量:
fetch prometheus_target
| metric 'prometheus.googleapis.com/pod_flow_egress_flows_count/counter'
| filter (metric.destination_identity == 'world')
| align rate(1m)
| every 1m
| group_by [metric.source_workload, metric.source_namespace], sum(val())
使用 Flow Analyzer 分析叢集流量成本和效能
請先查看診斷範圍和必要條件,再以圖表呈現流量和跨可用區費用:
- 重點領域:跨可用區資料移轉費用、主要通訊者、節點間流量,不需使用 SQL 查詢。
- 必要條件:虛擬私有雲流量記錄已啟用
INCLUDE_ALL_METADATA;節點內瀏覽權限已啟用;記錄檔 bucket 已啟用 Observability Analytics。 - CNI 相容性:所有叢集。
- 症狀:每月Google Cloud 帳單的跨可用區資料移轉費用增加。
- 目標:以視覺化方式找出產生跨可用區流量的 GKE 工作負載,並最佳化位置,不必查詢原始記錄。
必要條件
如要使用 Flow Analyzer for GKE,請按照下列步驟操作:
- 虛擬私有雲流量記錄:必須在叢集子網路上啟用
metadata="INCLUDE_ALL_METADATA"。 - 節點內瀏覽權限:必須在叢集上啟用,Pod 對 Pod 流量才會公開至虛擬私有雲流程記錄管道。
- 記錄分析:Cloud Logging 中的
_Defaultbucket 必須升級,才能使用 Observability Analytics。
步驟 1:在 Flow Analyzer 中找出 GKE 流量最多的項目
如要在 Flow Analyzer 中查看高流量工作負載,請按照下列步驟操作:
- 前往 Google Cloud 控制台的「Flow Analyzer」頁面。
- 按一下「Source bucket」(來源 bucket),然後選取存放流程記錄檔的記錄檔 bucket。除非您將記錄檔轉送至其他位置,否則系統會將記錄檔儲存至 _Default bucket。
- 在「流量匯總」中,選取「來源 - 目的地」。
- 設定分析日期範圍。
- 在「Organize flows by」(流程整理依據) 下方,選取 GKE Pod 或工作負載欄位。
- 點按「執行新查詢」。「Highest data flows」(最高資料流量) 圖表會顯示哪些工作負載移動的資料量最多。
步驟 2:分析可用區間流量費用
跨可用區流量會產生資料移轉費用。如要找出跨可用區傳輸的工作負載,請按照下列步驟操作:
- 在「Organize flows by」(流量分類依據) 下方,選取來源可用區和目的地可用區欄位。
- 點選「執行新查詢」,然後查看「所有資料流量」表格。來源和目的地可用區不同的資料列,就是跨可用區流量。Flow Analyzer 篩選器會比對值,因此無法篩選「不等於」的值,請改為比較結果中的可用區配對。
- 展開高流量可用區配對,即可查看基礎來源和目的地 GKE 工作負載。
修復:
- 實作 Kubernetes
topologySpreadConstraints或podAffinity,將通訊服務集中在同一個可用區。 - 在 Service 啟用拓撲感知轉送 (
service.kubernetes.io/topology-mode: Auto),將流量保留在來源可用區。
步驟 3:深入探索 Observability Analytics (適用於進階 SQL 查詢)
在 Flow Analyzer 中,按一下「View in Log Analytics」(在記錄檔分析中查看),即可對流量資料執行 SQL 查詢。
下列 SQL 查詢會計算跨可用區 Pod 的前幾名通訊者:
SELECT
JSON_VALUE(json_payload.src_gke_details.pod.workload.workload_name) AS src_workload,
JSON_VALUE(json_payload.dest_gke_details.pod.workload.workload_name) AS dest_workload,
JSON_VALUE(json_payload.src_instance.zone) AS src_zone,
JSON_VALUE(json_payload.dest_instance.zone) AS dest_zone,
SUM(CAST(JSON_VALUE(json_payload.bytes_sent) AS INT64)) / 1024 / 1024 / 1024 AS total_gb_sent
FROM
`PROJECT_ID.global._Default._AllLogs`
WHERE
log_name LIKE '%vpc_flows%'
AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
AND JSON_VALUE(json_payload.src_instance.zone) != JSON_VALUE(json_payload.dest_instance.zone)
GROUP BY
1, 2, 3, 4
ORDER BY
total_gb_sent DESC
LIMIT 20;
Hubble CLI 參考資料和查詢速查表
Hubble CLI 會直接從 GKE Dataplane V2 核心環形緩衝區,串流及篩選即時網路流量資料。
設定:建立輔助別名
Hubble 會在叢集控制層內執行,因此請設定殼層別名,以便執行 Hubble 指令,而不必部署本機二進位檔:
alias gke-hubble="kubectl exec -it -n gke-managed-dpv2-observability deployment/hubble-relay -c hubble-cli -- hubble"
常見篩選配方
| 疑難排解目標 | Hubble CLI 指令 |
|---|---|
| 即時觀察整個叢集中所有遭捨棄的封包 | gke-hubble observe --verdict DROPPED --follow |
| 串流傳輸任何命名空間中特定 Pod 的所有流量 | gke-hubble observe --pod default/my-pod --follow |
| 篩選兩個特定命名空間之間的流量 | gke-hubble observe --from-namespace frontend --to-namespace backend |
| 隔離特定通訊埠 (例如通訊埠 80) 的流量 | gke-hubble observe --port 80 |
| 檢查即時 DNS 查詢和答案 | gke-hubble observe --port 53 |
| 查看即時 TCP 重設 (RST 封包) | gke-hubble observe --type trace --verdict FORWARDED --tcp-flags RST |
| 串流傳送所有傳至公開網際網路的傳出流量 | gke-hubble observe --traffic-direction egress --to-identity world |
| 檢查 HTTP 應用程式層 (OSI 第 7 層) 流量 | gke-hubble observe --protocol http |
使用否定條件進行進階篩選 (--not)
您可以排除已知的高流量或正常流量,專注於異常流量:
# Observe drops, but exclude internal kube-system health probes and DNS
gke-hubble observe \
--verdict DROPPED \
--not --namespace kube-system \
--not --port 53
輸出格式設定和 jq 整合
如要以程式輔助方式處理流量記錄,請以 JSON 格式輸出:
# Extract only source, destination, and drop reason from the last 100 flows
gke-hubble observe --verdict DROPPED -o json --last 100 | \
jq -r '[.time, .flow.source.pod_name, .flow.destination.pod_name, .flow.drop_reason_desc] | @tsv'
限制
使用 Hubble CLI 進行即時疑難排解時,請注意下列技術限制:
- 暫時性節點本機環狀緩衝區:Hubble 流量會儲存在每個節點的記憶體內環狀緩衝區中。在高流量事件期間,舊的流量記錄會在幾秒內遭到覆寫。如要進行歷來分析,請使用 Cloud Logging 中的 NetworkPolicy 記錄和虛擬私有雲流量記錄。
- 沒有內建邏輯 OR:Hubble CLI 旗標會使用邏輯 AND 評估多個引數。如要搜尋多個條件 (例如通訊埠 80 或通訊埠 443),請執行個別指令,或使用
jq篩選 JSON 輸出內容。