本文提供操作說明和診斷程序,協助您使用 GKE Dataplane V2 觀測功能、Hubble 和 Cloud Monitoring,診斷 Google Kubernetes Engine (GKE) 叢集中的網路問題。
如需架構總覽和概念最佳做法,請參閱「網路可觀測性最佳做法」。
疑難排解決策樹和核心概念
在查看程序之前,請先使用下列決策矩陣,找出可能導致問題的 GKE 網路堆疊層級,然後前往對應的章節。
| 症狀或診斷型問題 | 疑似層級 | 建議程序 |
|---|---|---|
Pod 無法解析外部網域或內部 Kubernetes 服務 (DNS 超時、NXDOMAIN、SERVFAIL)。 |
第 1 層:Pod 和服務 (DNS) | 診斷 DNS 解析失敗問題 |
| 服務無法通訊;Pod 之間的連線逾時或封包遭到捨棄。 | 第 1 層:Pod 和服務 (政策或封包捨棄) | 診斷封包丟棄和 NetworkPolicy 封鎖問題 |
工作負載副本的流量負載不均,或 Pod 記錄的 TCP 重設率 (RST) 偏高。 |
第 1 層:Pod 和服務 (負載平衡或傳輸) | 診斷流量失衡和 TCP 重設問題 |
| 一般延遲、間歇性逾時或節點間的 CNI 重新啟動。 | 第 2 層:節點和 CNI (核心) | 節點層級延遲和 CNI 瓶頸的分類 |
| Pod 無法連線至 GKE 外部的資源 (Cloud SQL、外部 API 或其他 VPC)。 | 第 3 層:虛擬私有雲和路由 | 區分 GKE 與虛擬私有雲或外部連線問題 |
| 需要自動路徑模擬,確認防火牆規則、路徑或 NetworkPolicy 是否會封鎖流量。 | 第 3 層:虛擬私有雲和路由 (模擬) | 使用 Connectivity Tests 診斷連線問題 |
| 您需要找出哪些工作負載會將流量傳送至網際網路,並進行 NAT。 | 第 4 級:外部閘道和費用 | 識別 NAT 流量 (輸出至網際網路) |
| 區域間資料移轉費用高昂,或需要顯示通話量最高的通話者,但不想編寫 SQL 查詢。 | 第 4 級:外部閘道和費用 | 使用 Flow Analyzer 分析叢集流量成本和效能 |
核心網路概念
如果您剛開始使用 Kubernetes 或 Google Cloud 網路,請記住下列核心概念:
- eBPF (擴充 Berkeley 封包篩選器):作業系統技術,可直接在 Linux 核心中執行安全監控和路由程式。GKE Dataplane V2 使用 eBPF 路由傳送封包,並強制執行 NetworkPolicy,效能負擔極低。
- 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 表格。如果節點處理的並行連線過多,這兩個追蹤表就會填滿 (連線追蹤耗盡),導致節點自動捨棄新封包。 - Hubble:GKE Dataplane V2 的觀測引擎。這項功能以 eBPF 為基礎,可即時掌握流量、封包丟棄情形和 NetworkPolicy 評估結果。
第 1 層:Pod 和服務 (應用程式) 可觀測性
Pod 和 Service 層級涵蓋 Pod、Service 和叢集 DNS 之間的網路通訊。這個層級的問題通常會導致應用程式連線逾時、名稱解析失敗或負載分配不均。
診斷 DNS 解析失敗問題
排解 DNS 問題前,請先查看診斷範圍和必要條件:
- 重點領域:Pod 與 CoreDNS 或 NodeLocal DNSCache 之間的通訊、DNS 延遲、上游 DNS 解析逾時,以及 FQDN NetworkPolicy 驗證。
- 必要條件:已啟用 GKE Dataplane V2 指標;
kubectl存取權。 - CNI 相容性:GKE Dataplane V2 (進階資料路徑) 和標準 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 為基礎的 NetworkPolicy (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 中公開內建 DNS 指標,並加上 kubernetes.io/networking/dns/ 前置字元。
如要在 Cloud Monitoring 中查看 DNS 指標,請按照下列步驟操作:
- 在 Google Cloud 控制台中,依序前往「Cloud Monitoring」>「資訊主頁」。
- 選取預先定義的 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 與服務物件之間的流量下降、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 記錄
網路政策記錄會匯出所有政策決策的結構化 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 服務路由無法平衡已建立的 HTTP/2 連線內的要求。
- ClientIP 工作階段相依性:確認服務是否已設定
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
步驟 4:修復和可執行的修正措施
請根據流量失衡或 TCP 重設的原因,採取下列補救措施:
- 應用程式層 (OSI 第 7 層) 或 gRPC 連線黏性:
- 部署 Cloud Service Mesh,啟用應用程式層 (OSI 第 7 層) 要求層級的負載平衡。
- 設定用戶端連線限制或 keep-alive 逾時 (例如 gRPC
MAX_CONNECTION_AGE和MAX_CONNECTION_AGE_GRACE),強制定期重新建立連線。
- 服務 IP 親和性:除非應用程式狀態嚴格要求,否則請移除
service.spec.sessionAffinity。 - 無標題服務 DNS 快取:確保應用程式執行階段 (例如 JVM
networkaddress.cache.ttl) 不會無限期快取 DNS 結果。 - 應用程式待處理佇列溢位:應用程式接聽佇列已滿時,Linux 核心會捨棄傳入的 SYN 封包,或傳送 TCP RST。水平擴展 Pod 副本,或增加應用程式接聽積壓工作 (
somaxconn)。
第 2 層:節點和 CNI (核心) 可觀測性
節點和 CNI 層包含主機 Linux 核心、eBPF 程式和節點網路介面。這個層級的瓶頸會影響在受影響節點上執行的所有工作負載。
系統完整性檢查:偵測未經授權的 anetd 修補程式
GKE Dataplane V2 會以代管式 DaemonSet (anetd) 的形式在 kube-system
命名空間中執行。在 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 代理程式飽和度、連線追蹤耗盡。
- 必要條件:已啟用 Compute Engine VM 指標;
kubectl存取權。 - CNI 相容性:GKE Dataplane V2 和標準 GKE CNI。
- 症狀:跨節點流量發生延遲尖峰或隨機下降情形,但節點內流量仍維持正常。
- 目標:區分主機 VM 網路節流、Linux 核心捨棄和 CNI 層級瓶頸。
步驟 1:區分 GKE 外部和內部問題
執行 Compute Engine VM 基準測試:在與 GKE 叢集節點相同的 VPC 子網路中,部署獨立的 Compute Engine VM。測試從 VM 到目標目的地的連線。
- 如果獨立 VM 發生相同的封包遺失或延遲情形:問題位於 GKE 外部 (VPC 防火牆、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 核心連線追蹤計數:檢查主機上的有效連線追蹤計數:
# 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 輸出頻寬限制)。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 層:虛擬私有雲和路由 (雲端網路) 可觀測性
VPC 和雲端路由層級會將 GKE 節點連線至其他 Google Cloud 服務、地端部署網路和網際網路。此處的失敗通常源自虛擬私有雲防火牆規則、自訂路徑或閘道設定。
區分 GKE 與虛擬私有雲或外部連線問題
請先查看診斷範圍和必要條件,再將叢集外部網路問題與叢集內部故障隔離:
- 重點領域:Kubernetes 內部路由與 VPC 雲端路由之間的邊界隔離。
- 必要條件:gcloud CLI;建立連線測試的權限。
- CNI 相容性:所有叢集。
- 症狀:Pod 無法連線至外部資源 (例如 Cloud SQL、地端部署 API 或第三方端點)。
- 目標:快速判斷封包是否在 GKE 節點內、 Google Cloud 虛擬私有雲或外部網路中遭到捨棄。
步驟 1:Compute Engine VM 基準測試
如要部署基準 VM 並評估問題是否仍存在於 GKE 以外的環境,請按照下列步驟操作:
在與 GKE 節點集區相同的 VPC 子網路和可用區中,部署臨時 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 無法連線:問題出在 VPC 或外部網路 (防火牆規則、路由表、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
在控制台中檢查結果 Google Cloud ,判斷是否有虛擬私有雲防火牆規則或路徑捨棄流量。
使用 Connectivity Tests 診斷連線問題
Connectivity Tests 會模擬 GKE 和 VPC 資源之間的封包路徑,不會傳送即時流量。這項模擬作業會評估 Service ClusterIP 到 Pod 的 DNAT 解析度、GKE Dataplane V2 NetworkPolicy 輸入和輸出規則,以及節點 IP 偽裝 (SNAT)。執行自動路徑模擬前,請先查看診斷範圍和先決條件:
- 重點領域:自動模擬 GKE Pod、服務、NetworkPolicy 和 VPC 路由的靜態路徑。
- 必要條件:啟用 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
在 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
模擬追蹤記錄會顯示:
- 虛擬私有雲路由相符。
- 允許虛擬私有雲防火牆輸出和輸入。
- 抵達 GKE 節點。
- Service DNAT 至後端 Pod IP 位址。
- 評估後端 Pod 的 Ingress 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檢查投遞地點:
- 在 NetworkPolicy 中遭到捨棄:Pod 缺少允許流量傳輸至
0.0.0.0/0的輸出 NetworkPolicy。 - 在 VPC 防火牆中捨棄:VPC 防火牆規則拒絕來自節點子網路的外送流量。
- 在 Cloud NAT 或路由中遭到捨棄:子網路缺少網際網路閘道的預設路由,或子網路未設定 Cloud NAT。
- 在 NetworkPolicy 中遭到捨棄:Pod 缺少允許流量傳輸至
第 4 層:外部閘道和成本 (網際網路和 NAT) 可觀測性
外部閘道層會透過 Cloud NAT 或外部閘道,管理前往公用網際網路目的地的輸出流量。這個層級的可觀測性有助於找出高輸出工作負載,並控管資料傳輸費用。
識別 NAT 流量 (輸出至網際網路)
分析對外網際網路和 NAT 流量前,請先查看診斷範圍和必要條件:
- 重點領域:網際網路傳出流量、Cloud NAT 連接埠用量、外部資料移轉費用。
- 必要條件:啟用 GKE Dataplane V2 流量觀測功能。
- CNI 相容性:GKE Dataplane V2。
- 症狀:Cloud NAT 連接埠耗盡錯誤,或非預期的高額網際網路輸出費用。
- 目標:找出將流量傳輸至外部網際網路端點的特定 GKE Pod 和 Service 物件。
步驟 1:瞭解 GKE Dataplane V2 中的「堆疊」和「世界」概念
在 GKE Dataplane V2 中:
world:代表 GKE 叢集和 VPC 以外的任何目的地 (公開網際網路)。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
如要找出最常對外通訊的 Pod,您也可以將 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 工作負載,並最佳化放置位置,不必查詢原始記錄。
必要條件
如要使用 GKE 適用的 Flow Analyzer,請按照下列步驟操作:
- 虛擬私有雲流量記錄:必須在叢集子網路上啟用,且
metadata="INCLUDE_ALL_METADATA"。 - 節點內瀏覽功能:必須在叢集上啟用,才能將 Pod 對 Pod 流量公開至 VPC 流量記錄管道。
- 記錄檔分析:Cloud Logging 中的
_Defaultbucket 必須升級,才能使用 Observability Analytics。
步驟 1:在 Flow Analyzer 中找出 GKE 流量最多的項目
如要在 Flow Analyzer 中查看高用量工作負載,請按照下列步驟操作:
- 前往 Google Cloud 控制台的「Flow Analyzer」頁面。
- 按一下「來源記錄檔 bucket」,然後選取包含流程記錄的記錄檔 bucket。除非您已將這些項目轉送至其他位置,否則這些項目會存放在「_Default」值區。
- 在「流量匯總」中,選取「來源 - 目的地」。
- 設定分析視窗的時間範圍。
- 在「依下列項目整理流程」下方,選取 GKE Pod 或工作負載欄位。
- 點按「執行新查詢」。「資料流量最高」圖表會顯示哪些工作負載移動的資料最多。
步驟 2:分析可用區間流量費用
跨可用區的流量會產生資料移轉費用。如要找出跨可用區傳輸的工作負載,請按照下列步驟操作:
- 在「Organize flows by」(依流量分類) 下方,選取來源可用區和目的地可用區欄位。
- 點按「執行新查詢」,然後閱讀「所有資料流量」表格。來源和目的地區域不同的資料列,就是跨區域流量。Flow Analyzer 篩選器會比對值,因此您無法篩選「不等於」的值;請改為比較結果中的區域配對。
- 展開高用量區域配對,即可查看基礎來源和目的地 GKE 工作負載。
補救措施:
- 實作 Kubernetes
topologySpreadConstraints或podAffinity,在同一個可用區內共置通訊服務。 - 在服務上啟用「拓撲感知路由」 (
service.kubernetes.io/topology-mode: Auto),將流量保留在來源區域內。
步驟 3:深入瞭解 Observability Analytics (適用於進階 SQL 查詢)
在 Flow Analyzer 中,按一下「在記錄檔分析中查看」,即可針對流程資料執行 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 輸出內容。