במאמר הזה מפורטות הוראות ופרוצדורות לאבחון בעיות ברשת באשכולות של Google Kubernetes Engine (GKE) באמצעות יכולות התצפית של GKE Dataplane V2, Hubble ו-Cloud Monitoring.
סקירה כללית של הארכיטקטורה ושיטות מומלצות קונספטואליות זמינות במאמר שיטות מומלצות לניטור רשת.
פתרון בעיות בעץ ההחלטות ובמושגי ליבה
לפני שמעיינים בהליכים, כדאי להשתמש במטריצת ההחלטות הבאה כדי לזהות את השכבה במערך של GKE Networking שסביר להניח שגורמת לבעיה, ולעבור לקטע המתאים.
| סימפטום או שאלת אבחון | רמת מינוי חשודה | הליך מומלץ |
|---|---|---|
ה-Pods לא מצליחים לפתור דומיינים חיצוניים או שירותי Kubernetes פנימיים (פסק זמן של DNS, NXDOMAIN, SERVFAIL). |
רמה 1: פוד ושירות (DNS) | אבחון של כשלים בפענוח DNS |
| השירותים לא יכולים לתקשר; פסק זמן לחיבור או מנות שהושמטו בין Pods. | רמה 1: פוד ושירות (מדיניות או השמטת מנות) | אבחון של השמטת חבילות וחסימות של NetworkPolicy |
עומס התנועה בעותקים של עומס העבודה לא אחיד, או שקצב האיפוסים של TCP (RST) ב-Pods גבוה. |
רמה 1: פוד ושירות (איזון עומסים או העברה) | אבחון חוסר איזון בתנועה ואיפוסים של TCP |
| חביון כללי, פסק זמן לסירוגין או הפעלה מחדש של CNI בצמתים. | רמה 2: צומת ו-CNI (ליבה) | מיון של בעיות שקשורות לזמן האחזור ברמת הצומת ולצווארי בקבוק ב-CNI |
| לפודים אין גישה למשאבים מחוץ ל-GKE (Cloud SQL, ממשקי API חיצוניים או רשתות VPC אחרות). | רמה 3: VPC וניתוב | בידוד בעיות ב-GKE לעומת בעיות ב-VPC או בקישוריות חיצונית |
| צריך סימולציה אוטומטית של נתיב כדי לוודא שכללי חומת האש, המסלולים או NetworkPolicies לא חוסמים את התנועה. | רמה 3: VPC וניתוב (סימולציה) | אבחון הקישוריות באמצעות בדיקות קישוריות |
| צריך לזהות אילו עומסי עבודה שולחים תנועה לאינטרנט ועוברים NAT. | רמה 4: שער חיצוני ועלות | זיהוי תעבורת נתונים של NAT (תעבורת נתונים יוצאת לאינטרנט) |
| עלויות גבוהות של העברת נתונים בין אזורים או צורך בהצגה חזותית של המשתמשים הכי פעילים בלי לכתוב שאילתות SQL. | רמה 4: שער חיצוני ועלות | ניתוח העלויות והביצועים של תנועת הגולשים באשכול באמצעות Flow Analyzer |
מושגים מרכזיים בנושא רישות
אם אין לכם ניסיון ב-Kubernetes או ב Google Cloud רשתות, כדאי לזכור את המושגים הבסיסיים האלה:
- eBPF (Extended Berkeley Packet Filter): טכנולוגיה של מערכת הפעלה שמאפשרת להריץ תוכניות ניטור וניתוב מאובטחות ישירות בתוך ליבת Linux. GKE Dataplane V2 משתמש ב-eBPF כדי לנתב מנות ולאכוף את NetworkPolicies עם תקורה מינימלית של ביצועים.
- הסוואת כתובת IP (SNAT): תהליך של כתיבה מחדש של כתובת ה-IP של המקור של חבילת נתונים. כש-Pod של GKE (שיש לו כתובת IP פרטית) מתקשר עם האינטרנט או עם משאבי VPC חיצוניים, GKE מבצע מיסוך (שכתוב) של כתובת ה-IP של ה-Pod לכתובת ה-IP של הצומת, כדי שמערכות חיצוניות יידעו איך לנתב את התשובה.
- מעקב אחר חיבורים (Conntrack): תכונה של ליבת מערכת ההפעלה שעוקבת אחרי כל החיבורים הפעילים לרשת. באשכולות GKE Dataplane V2, המעקב הזה מתבצע בשתי טבלאות: conntrack של ליבת Linux רגילה (שמשמשת את
ip-masq-agent) וטבלת conntrack שמנוהלת על ידי Cilium ו-GKE Dataplane V2, שמאוחסנת במפת eBPF. אם צומת מטפל ביותר מדי חיבורים בו-זמניים, יכול להיות שאחד משני טבלאות המעקב האלה יתמלא (conntrack exhaustion), מה שיגרום לצומת להשליך בשקט חבילות חדשות. - Hubble: מנוע היכולת להתבוננות ב-GKE Dataplane V2. הוא פועל על גבי eBPF ומספק נראות בזמן אמת של זרימות תנועה, נפילות מנות והערכה של NetworkPolicy.
רמה 1: יכולת צפייה ב-Pod ובשירות (באפליקציה)
רמת ה-Pod והשירות כוללת תקשורת ברשת בין Pods, שירותים ו-DNS של אשכול. בעיות ברמה הזו בדרך כלל מתבטאות כפסק זמן לחיבור לאפליקציה, ככשלים בפתרון שמות או כחלוקת עומס לא אחידה.
אבחון של שגיאות בפענוח DNS
לפני שפותרים בעיות ב-DNS, כדאי לעיין בהיקף האבחון ובתנאים המוקדמים:
- תחום המיקוד: תקשורת בין Pods לבין CoreDNS או NodeLocal DNSCache, חביון DNS, פסק זמן של פענוח DNS במעלה הזרם ואימות של FQDN NetworkPolicy.
- דרישות מוקדמות: מדדים של GKE Dataplane V2 מופעלים; גישה ל-
kubectl. - תאימות ל-CNI: GKE Dataplane V2 (Advanced Datapath) ו-CNI רגיל של GKE.
- הסימפטום: ביומני ה-Pods מופיע
dial tcp: lookup <domain>: i/o timeout,NXDOMAINאו חביון לסירוגין בקריאות ל-API יוצאות. - המטרה: לקבוע אם כשל ה-DNS נובע מתוך האשכול (
kube-dnsאו רוויה של NodeLocal DNSCache), מ-NetworkPolicy שחוסם UDP או TCP port 53, או מירידה בביצועים של הרשת במעלה הזרם.
שלב 1: בדיקה בסיסית של הנגישות
לפני שמנסים לפתור בעיות בשכבות DNS, צריך לוודא שאפשר להגיע ליעד ישירות באמצעות כתובת ה-IP שלו מתוך ה-Pod המושפע:
# 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.
בדיקה של מילוי מראש של DNS ב-NetworkPolicy FQDN
אם באשכול שלכם נעשה שימוש ב-NetworkPolicies שמבוססות על FQDN (FQDNNetworkPolicy), צריך לוודא ששם הדומיין מותר באופן מפורש. אם Pod שולח שאילתה לדומיין חיצוני שלא מאוכלס מראש במטמון של שרת ה-proxy של DNS ב-GKE Dataplane V2 או שלא מותר לפי המדיניות, 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: בדיקת מדדי DNS ב-Cloud Monitoring
GKE חושף מדדי DNS מובנים ב-Cloud Monitoring עם הקידומת kubernetes.io/networking/dns/.
כדי לבדוק את מדדי ה-DNS ב-Cloud Monitoring:
- במסוף 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 > 100ms | זמן טעינה ארוך של פענוח DNS מקצה לקצה ב-kube-dns או ב-NodeLocal DNSCache. |
kubernetes.io/networking/dns/kubedns/forwarding_request_latencies |
p99 > 100ms | זמן האחזור או העומס של שרת ה-DNS במעלה הזרם. |
רצף טריאז' של ביצועי DNS וחלף הזמן הקצוב לתפוגה
כדי לאבחן את זמן האחזור של DNS, את החמצות המטמון ואת פסק הזמן של השרתים במעלה הזרם, פועלים לפי רצף השלבים הבא:
- בדיקת שיעור מציאות במטמון (cache hit): שאילתה
kubernetes.io/networking/dns/kubedns/dns_cache_request_count(אוnode_local_dns/dns_cache_request_count) מקובצת לפי התוויתcache_status. אם הערך שלcache_status="hit"נמוך והערך שלcache_status="miss"גבוה, יכול להיות שאפליקציות שולחות שאילתות שאינן FQDN (כמוmy-serviceבמקוםmy-service.default.svc.cluster.local), מה שגורם ל-Path traversal בכל הרשומות ב-/etc/resolv.conf. - הערכת זמן האחזור של השרתים במעלה הזרם: ערך גבוה
forwarding_request_latenciesמצביע על בעיות בשרת ה-DNS במעלה הזרם (לדוגמה, DNS מקומי של חברה שאליו מגיעים דרך Cloud Interconnect או Cloud VPN, או מגבלות של Cloud DNS). בדיקת ביטולים מותאמים אישית של DNS: בדיקת
kube-dnsConfigMaps מותאמים אישית כדי לזהות stubs או הפניות קדימה (upstream forwards) שהוגדרו בצורה שגויה:kubectl get configmap kube-dns -n kube-system -o yaml
שלב 3: הזרמת תנועת DNS בזמן אמת באמצעות Hubble CLI
אפשר להשתמש בכינוי של העוזר 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 ל-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 חוסמת את החיבור באופן מפורש או מרומז. -
CT: Map insertion failed: הטבלה של מעקב אחר חיבורים (conntrack) מלאה. -
Unsupported L3 protocol: חבילת נתונים שאינה IPv4 או IPv6, או כותרת פגומה.
-
שלב 2: בדיקת יומנים של NetworkPolicy ב-Cloud Logging
יומן הרישום של NetworkPolicy מייצא יומנים מובְנים בפורמט JSON לכל החלטות המדיניות. כדי לשלוח שאילתות ליומנים של NetworkPolicy ב-Cloud Logging:
- במסוף 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: רשימה של מדיניות הרשת שנבדקה. אם מוחזרת רשימה ריקה עם פסק דין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: בדיקה אם יש חוסר במעקב אחר חיבורים
אם הסיבה לירידה היא 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 מלאה, צריך להרחיב את עומסי העבודה ליותר צמתים או לצמצם את קצב החיבור מ-Pods של לקוחות.
אבחון חוסר איזון בתנועה ואיפוסים של 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, מריצים שאילתה לגבי מספר תנועת הכניסה בכל ה-Pods בפריסה:
sum by (pod) (rate(pod_flow_ingress_flows_count{destination_workload="my-service"}[5m]))הערכת חלוקת התנועה בין ה-Pods. אם פוד אחד מקבל את רוב התנועה, כדאי לבדוק את השימוש החוזר בחיבורים או בסשנים קבועים:
- gRPC או HTTP/2: חיבורי TCP לטווח ארוך גורמים לכל הבקשות לעבור דרך זרם TCP יחיד אל Pod אחד בקצה העורפי. ניתוב של שירות Kubernetes בשכבת התעבורה (OSI שכבה 4, TCP) לא יכול לאזן בקשות בתוך חיבור HTTP/2 קיים.
- ClientIP Session Affinity: מוודאים שהשירות מוגדר עם
sessionAffinity: ClientIP. - שירותים ללא ממשק משתמש: יכול להיות שהלקוחות יפענחו את ה-DNS פעם אחת וישמרו במטמון את כתובת ה-IP היחידה באופן קבוע.
שלב 2: ניתוח מדדי איפוס TCP
איפוס TCP (RST) מסיים את החיבורים באופן מיידי. הן נוצרות על ידי ליבת מערכת ההפעלה כשנקודת קצה מקבלת חבילה עבור יציאה לא ידועה, או כשיישום סוגר חיבור עם נתונים לא קריאים במאגר.
מריצים את שאילתת MQL הבאה ב-Cloud Monitoring:
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 קורסת, מגיעה למגבלת החיבור או דוחה את החיבור באופן פעיל. - 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 Layer 7) או חיבורי gRPC:
- פורסים את Cloud Service Mesh כדי להפעיל איזון עומסים ברמת הבקשה (שכבה 7 של OSI) בשכבת האפליקציה.
- מגדירים מגבלות חיבור בצד הלקוח או פסק זמן של הודעת keep-alive (לדוגמה, gRPC
MAX_CONNECTION_AGEו-MAX_CONNECTION_AGE_GRACE) כדי לאלץ חיבור מחדש תקופתי.
- לזיקה לכתובת IP של שירות: מסירים את
service.spec.sessionAffinityאלא אם מצב האפליקציה מחייב זאת. - לגבי שמירת DNS של שירותים ללא ראש (headless): מוודאים שזמני הריצה של האפליקציות (כמו JVM
networkaddress.cache.ttl) לא שומרים תוצאות DNS במטמון ללא הגבלת זמן. - במקרה של הצפת תור של בקשות ממתינות באפליקציה: כשתור ההמתנה של האפליקציה מלא, ליבת Linux משמיטה מנות SYN נכנסות או שולחת TCP RST. הרחבת העותקים של ה-Pod או הגדלת ה-backlog של האזנה לאפליקציה
(
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
לפני שמבצעים אבחון של זמן האחזור ברמת הצומת וצווארי בקבוק בקרנל, חשוב לעיין בהיקף האבחון ובתנאים המוקדמים:
- תחום ההתמקדות: חביון של ליבת המארח, השמטת מנות בממשק של המכונה הווירטואלית, רוויה של סוכן eBPF של GKE Dataplane V2, מיצוי של conntrack.
- דרישות מוקדמות: מדדים של מכונות וירטואליות של Compute Engine מופעלים; גישה ל-
kubectl. - תאימות CNI: GKE Dataplane V2 ו-CNI רגיל של GKE.
- סימפטום: השהיות חדות או ירידות אקראיות בתנועת הנתונים בין הצמתים, בזמן שתנועת הנתונים בתוך הצומת תקינה.
- המטרה: להבדיל בין הגבלת רוחב פס ברשת של מכונת VM מארחת, בין השמטות של ליבת Linux ובין צווארי בקבוק ברמת CNI.
שלב 1: הבחנה בין בעיות מחוץ ל-GKE לבין בעיות בתוך GKE
מריצים את בדיקת הבסיס של מכונת Compute Engine וירטואלית: פורסים מכונת Compute Engine וירטואלית עצמאית באותה תת-רשת של VPC כמו הצמתים של אשכול GKE. בודקים את הקישוריות מהמכונה הווירטואלית ליעד.
- אם במכונה הווירטואלית העצמאית יש את אותן בעיות של השמטת חבילות או זמן אחזור: הבעיה נמצאת מחוץ ל-GKE (חומות אש של VPC, Cloud NAT, Cloud Interconnect או השרת החיצוני). ממשיכים אל בידוד בעיות ב-GKE לעומת בעיות ב-VPC או בקישוריות חיצונית.
- אם המכונה הווירטואלית העצמאית מתקשרת בצורה תקינה, אבל הפודים של GKE נכשלים: הבעיה היא בתוך GKE (eBPF ברמת הצומת, conntrack או CNI). עוברים לשלב 2.
שלב 2: הבחנה בין בעיות באפליקציה לבין בעיות ברמת הצומת וה-CNI
כדי לקבוע אם זמן האחזור נובע מהאפליקציה או מהצומת ומרמת ה-CNI, מבצעים את הפעולות הבאות:
בודקים את רמת הניצול של משאבי האפליקציה: מוודאים שלא מתבצעת הגבלת מהירות של המעבד (CPU) או שאין עומס על הזיכרון בצומת, כי זה עלול לגרום לעיכוב בעיבוד המנות במרחב המשתמש:
kubectl top nodes kubectl top pods -n defaultבדיקת מספר מעקב החיבורים (conntrack) של ליבת 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
Google Cloud Compute Engine מייצא מדדים של ממשק רשת ברמת המכונה הווירטואלית אל Cloud Monitoring.
ב-Cloud Monitoring > Metrics Explorer, שולחים שאילתה:
sum by (drop_reason) (rate(compute_googleapis_com:instance_network_dropped_packets_count[5m]))
-
FQ_CODEL_DROP: חבילת נתונים שהוסרה בגלל Fair Queuing או CoDel queue saturation (חריגה ממגבלת רוחב הפס של תעבורת נתונים יוצאת של מכונה וירטואלית). -
FIREWALL_RULE_DROP: מנות שהופלו על ידי כלל חומת אש ב-VPC. -
RATE_LIMIT_DROP: המערכת הפילה את המנה כי המכונה הווירטואלית חרגה מהמכסה המקסימלית של מנות לשנייה (PPS) של ממשק הרשת שלה.
שלב 4: חקירת השמטות ברמת ליבת המערכת באמצעות eBPF
אם מדדים ברמת המכונה הווירטואלית מראים אפס השמטות, אבל מנות של 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: ניראות (observability) של VPC ותכנון מסלול (רשת ענן)
רמת הניתוב של VPC וענן מחברת בין צמתים של GKE לבין שירותים Google Cloud אחרים, רשתות מקומיות והאינטרנט. כשלים כאן נובעים בדרך כלל מכללי חומת אש של VPC, מנתיבים מותאמים אישית או מהגדרות של שערים.
בידוד בעיות ב-GKE לעומת בעיות ב-VPC או בקישוריות חיצונית
לפני שמבדילים בין בעיות ברשת חיצונית לבין כשלים בתוך האשכול, כדאי לעיין בהיקף האבחון ובתנאים המוקדמים:
- תחום ההתמקדות: בידוד הגבולות בין ניתוב פנימי של Kubernetes לבין ניתוב בענן של VPC.
- דרישות מוקדמות: ה-CLI של gcloud; הרשאה ליצירת בדיקות קישוריות.
- תאימות ל-CNI: כל האשכולות.
- תסמין: הפודים לא מצליחים להתחבר למשאב חיצוני (לדוגמה, Cloud SQL, API מקומי או נקודת קצה של צד שלישי).
- המטרה: לקבוע במהירות אם הירידה מתרחשת בצומת GKE או בתוך Google Cloud רשת ה-VPC או הרשת החיצונית.
שלב 1: בדיקת הבסיס של מכונה וירטואלית ב-Compute Engine
כדי לפרוס מכונה וירטואלית בסיסית ולבדוק אם הבעיה נמשכת מחוץ ל-GKE:
פריסת מכונה וירטואלית זמנית של Compute Engine באותה תת-רשת של VPC ואותו תחום (zone) שבהם נמצא מאגר הצמתים של GKE:
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 לא מצליחה להתחבר: הבעיה היא ב-VPC או ברשת החיצונית (כללי חומת אש, טבלאות ניתוב, מיצוי של כתובות IP ב-Cloud NAT או הוספה לרשימת ההיתרים של כתובות IP חיצוניות).
- אם המכונה הווירטואלית ב-Compute Engine מתחברת בהצלחה: הבעיה היא ב-GKE (יציאה חסומה של NetworkPolicy, Pod CIDR לא מוסווה או DNS ברמת הקונטיינר).
שלב 2: הרצת בדיקה של בדיקות קישוריות לפי דרישה
מריצים Google Cloud בדיקת קישוריות מהמכונה הווירטואלית של הצומת ל יעד:
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 כדי לזהות אם כלל של חומת אש ב-VPC או מסלול גורמים לירידה בנפח התנועה.
אבחון הקישוריות באמצעות בדיקות קישוריות
בדיקות הקישוריות מדמות נתיבי מנות בין משאבי GKE ו-VPC בלי לשלוח תעבורת נתונים פעילה. הסימולציה הזו בודקת את ההמרה של כתובת רשת (NAT) של שירות ClusterIP לפתרון DNS של Pod, את כללי הכניסה והיציאה של NetworkPolicy ב-GKE Dataplane V2 ואת הסתרת כתובת ה-IP של הצומת (SNAT). לפני שמריצים סימולציות אוטומטיות של נתיבים, חשוב לעיין בהיקף האבחון ובדרישות המוקדמות:
- תחום התמקדות: סימולציה אוטומטית של נתיב סטטי עבור GKE Pods, Services, NetworkPolicies ו-VPC routes.
- דרישות מוקדמות: הפעלת Network Intelligence Center והפעלת Network Management API.
- תאימות ל-CNI: GKE Dataplane V2 (ניתוח משופר).
- תסמין: נפילות לא מוסברות בקישוריות, כשכל ההגדרות נראות תקינות בבדיקה ידנית.
- המטרה: הדמיה סטטית ומעקב אחרי כל נתיב החבילה ממקור Pod ליעד, וזיהוי השורה המדויקת במדיניות שגורמת להשמטה.
תרחיש א': בדיקה אם מדיניות NetworkPolicy של GKE חוסמת איסוף מדדים
כשמבצעים גירוד של מדדים מ-Pods במרחב שמות מאובטח, יכול להיות שהאיסוף של השירות המנוהל של Google Cloud ל-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, צריך להוסיף כלל כניסה כדי לאפשר תנועה מ-Pods של איסוף.
תרחיש ב': אימות הנגישות לשירות GKE
סימולציה של נגישות ממכונה וירטואלית של לקוח לשירות 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
המעקב המדומה מראה:
- התאמה של מסלול VPC.
- אפשרות יציאה וכניסה של חומת אש ב-VPC.
- הגעה לצומת GKE.
- שירות DNAT לכתובת ה-IP של ה-Pod בקצה העורפי.
- הערכה של Ingress NetworkPolicy בתרמיל ה-backend.
תרחיש ג': אבחון בעיות ביציאה מ-Pod לאינטרנט
אם ל-Pods אין גישה ל-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בודקים את נקודת ההעברה:
- Dropped at NetworkPolicy: לקבוצת ה-Pod חסר egress NetworkPolicy שמאפשר תעבורה אל
0.0.0.0/0. - Dropped at VPC Firewall: כלל חומת אש ב-VPC דוחה תעבורה יוצאת מתת-הרשת של הצומת.
- החבילה נפסלה ב-Cloud NAT או בנתיב: לתת-הרשת חסר נתיב ברירת מחדל לשער האינטרנט או ש-Cloud NAT לא מוגדר לתת-הרשת.
- Dropped at NetworkPolicy: לקבוצת ה-Pod חסר egress NetworkPolicy שמאפשר תעבורה אל
רמה 4: ניראות של שער חיצוני ועלות (אינטרנט ו-NAT)
שער חיצוני מנהל תנועה יוצאת ליעדים באינטרנט הציבורי דרך Cloud NAT או שערים חיצוניים. היכולת לראות את המערכת בשכבה הזו עוזרת לזהות עומסי עבודה עם יציאה גבוהה ולשלוט בעלויות של העברת נתונים.
זיהוי תעבורת נתונים של NAT (תעבורת נתונים יוצאת לאינטרנט)
לפני שמנתחים תנועה יוצאת באינטרנט ותנועת NAT, כדאי לעיין בהיקף האבחון ובתנאים המוקדמים:
- תחום התמקדות: תעבורת נתונים יוצאת באינטרנט, ניצול יציאות של Cloud NAT, עלויות של העברת נתונים חיצוניים.
- דרישות מוקדמות: צריך להפעיל את התכונה 'יכולת צפייה בזרימת נתונים ב-GKE Dataplane V2'.
- תאימות ל-CNI: GKE Dataplane V2.
- תסמין: שגיאות של מיצוי יציאות ב-Cloud NAT או עלויות גבוהות באופן לא צפוי של תעבורת נתונים יוצאת (egress) באינטרנט.
- המטרה: לזהות אילו אובייקטים ספציפיים של GKE Pod ו-Service מעבירים תנועה לנקודות קצה חיצוניות באינטרנט.
שלב 1: הסבר על המושגים 'to-stack' ו-'world' ב-GKE Dataplane V2
ב-GKE Dataplane V2:
-
world: מייצג כל יעד מחוץ לאשכול GKE ומחוץ ל-VPC (האינטרנט הציבורי). -
to-stack: מייצג מנות שעוברות מהממשק veth של מאגר eBPF אל מחסנית הרשת של Linux במארח, כדי לעבור הסוואת IP (SNAT) לפני שהן מגיעות אל Cloud NAT.
שלב 2: הזרמה וסינון של תנועת NAT באמצעות Hubble CLI
הזרמת תנועה יוצאת באינטרנט שמקורה באשכול:
# 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
כדי לזהות את המקורות העיקריים של תעבורה יוצאת, אפשר גם להעביר את פלט ה-JSON של Hubble ל-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.
- דרישות מוקדמות: צריך להפעיל את VPC Flow Logs עם
INCLUDE_ALL_METADATA, להפעיל את Intranode Visibility ולהפעיל את Observability Analytics בקטגוריית היומן. - תאימות ל-CNI: כל האשכולות.
- הסימפטום: חיובים גבוהים על העברת נתונים בין אזורים בחשבונות חודשיים ב-Google Cloud .
- המטרה: לזהות באופן חזותי אילו עומסי עבודה ב-GKE יוצרים תנועה בין אזורים ולבצע אופטימיזציה של המיקום בלי לשלוח שאילתות ליומנים לא מעובדים.
דרישות מוקדמות
כדי להשתמש ב-Flow Analyzer ב-GKE:
- יומני זרימה של VPC: צריך להפעיל אותם ברשת המשנה של האשכול באמצעות
metadata="INCLUDE_ALL_METADATA". - חשיפה בתוך הצומת: צריך להפעיל את האפשרות הזו באשכול כדי שתנועה בין פודים תיחשף לצינור של רישום זרימת ה-VPC.
- ניתוח נתוני יומנים: צריך לשדרג את קטגוריית
_Defaultב-Cloud Logging כדי להשתמש ב-Observability Analytics.
שלב 1: זיהוי של 'המשתמשים הכי פעילים' ב-GKE ב-Flow Analyzer
כדי לראות עומסי עבודה גדולים ב-Flow Analyzer, צריך לבצע את הפעולות הבאות:
- נכנסים לדף Flow Analyzer במסוף Google Cloud .
- לוחצים על Source bucket (קטגוריית מקור) ובוחרים את קטגוריית היומן שמכילה את יומני התנועה. אלא אם ניתבתם אותם למקום אחר, זו קטגוריית _Default.
- בקטע צבירת תנועה, בוחרים באפשרות מקור – יעד.
- מגדירים את טווח הזמן של חלון הניתוח.
- בקטע ארגון התהליכים לפי, בוחרים את השדות של GKE Pod או של עומס העבודה.
- לוחצים על Run new query. בתרשים Highest data flows (זרימות הנתונים הגבוהות ביותר) מוצגות עומסי העבודה שמעבירים הכי הרבה נתונים.
שלב 2: ניתוח עלויות התנועה בין אזורים
תעבורת נתונים בין אזורים כרוכה בחיובים על העברת נתונים. כדי לאתר עומסי עבודה שמועברים בין אזורים:
- בקטע Organize flows by, בוחרים את השדות של אזור המקור ואזור היעד.
- לוחצים על הפעלת שאילתה חדשה וקוראים את הטבלה כל זרימות הנתונים. שורות שבהן אזור המקור שונה מאזור היעד מייצגות את התנועה בין האזורים. המסננים ב-Flow Analyzer מתאימים לערכים, ולכן אי אפשר לסנן לפי 'לא שווה'. במקום זאת, צריך להשוות את זוגות האזורים בתוצאות.
- מרחיבים זוג אזורים עם נפח גבוה כדי לראות את עומסי העבודה הבסיסיים של GKE במקור וביעד.
פתרון:
- כדי למקם שירותים שמתקשרים באותו אזור זמינות, מטמיעים את Kubernetes
topologySpreadConstraintsאוpodAffinity. - מפעילים את Topology Aware Routing (
service.kubernetes.io/topology-mode: Auto) בשירות כדי שהתנועה תישאר באזור שממנו היא מגיעה.
שלב 3: מעמיקים בניתוח של נתוני Observability (לשאילתות SQL מתקדמות)
בכלי לניתוח זרימה, לוחצים על הצגה ב-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 מעביר בסטרימינג ומסנן נתוני תעבורה בזמן אמת ישירות ממאגר הנתונים הזמני של ליבת GKE Dataplane V2.
הגדרה: יצירת כתובת אימייל רשמית של עוזר
מכיוון ש-Hubble פועל בתוך מישור הבקרה של האשכול, צריך להגדיר כינוי למעטפת כדי להריץ פקודות של Hubble בלי לפרוס קבצים בינאריים מקומיים:
alias gke-hubble="kubectl exec -it -n gke-managed-dpv2-observability deployment/hubble-relay -c hubble-cli -- hubble"
מתכונים נפוצים לסינון
| פתרון בעיות שקשורות למטרות עסקיות | פקודת CLI של Hubble |
|---|---|
| מעקב בזמן אמת אחרי כל המנות שהושמטו באשכול | 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 |
| בדיקת תעבורה בשכבת האפליקציה (שכבה 7 ב-OSI) של HTTP | 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 flows מאוחסנים במאגר זמני של נתוני טבעת בזיכרון בכל צומת בנפרד. במהלך אירועים עם נפח תעבורת נתונים גבוה, יומני זרימת נתונים ישנים יותר נמחקים תוך שניות. לניתוח היסטורי, אפשר להסתמך על רישום ביומן של NetworkPolicy ועל VPC Flow Logs ב-Cloud Logging.
- אין OR לוגי מובנה: דגלי ה-CLI של Hubble מעריכים כמה ארגומנטים באמצעות AND לוגי. כדי לחפש כמה תנאים (למשל Port 80 OR Port 443), צריך להריץ פקודות נפרדות או לסנן את פלט ה-JSON באמצעות
jq.
המאמרים הבאים
- שיטות מומלצות לשיפור יכולת הצפייה ברשת
- פתרון בעיות ברישות ב-GKE
- פתרון בעיות בקישוריות באשכול
- מידע על יכולות התצפית של GKE Dataplane V2
- פתרון בעיות בנתונים ב-Flow Analyzer