שימוש ברישום ביומן של מדיניות הרשת

בדף הזה מוסבר איך להשתמש ברישום ביומן של מדיניות רשת ב-Kubernetes ב-Google Kubernetes Engine‏ (GKE). מדיניות רשת ב-Kubernetes מציינים את תנועת הנתונים ברשת שקבוצות Pod יכולות לשלוח ולקבל. רישום ביומן של מדיניות רשת ב-Kubernetes מאפשר לכם לתעד מקרים שבהם מדיניות רשת ב-Kubernetes מאפשרת או דוחה חיבור. רישום ביומן של מדיניות רשת ב-Kubernetes יכול לעזור לכם לפתור בעיות שקשורות למדיניות רשת ב-Kubernetes.

סקירה כללית

באמצעות רישום ביומן של מדיניות רשת ב-Kubernetes, אתם יכולים:

  • מוודאים שמדיניות הרשת פועלת כצפוי.
  • להבין אילו Pods באשכול מתקשרים עם האינטרנט.
  • להבין אילו מרחבי שמות מתקשרים זה עם זה.
  • זיהוי של התקפת מניעת שירות.

אם Cloud Logging מופעל, יומני מדיניות הרשת מועלים אל Cloud Logging לצורך אחסון, חיפוש, ניתוח והתראות. כברירת מחדל, Cloud Logging מופעל באשכולות חדשים. מידע נוסף מופיע במאמר הגדרת רישום ביומן ומעקב ב-GKE.

דרישות

  • רישום ביומן של מדיניות רשת ב-Kubernetes זמין רק לאשכולות שמשתמשים ב-GKE Dataplane V2.
  • כדי להשתמש ברישום ביומן של מדיניות רשת ב-Kubernetes, צריך Google Cloud CLI בגרסה 303.0.0 ומעלה.
  • אין תמיכה ברישום ביומן של מדיניות רשת ב-Kubernetes במאגרי צמתים של Windows Server.

תמחור

  • אין חיובים על יצירת יומנים של מדיניות רשת ב-Kubernetes.
  • אפשר גם לנתב את היומנים ל-Pub/Sub, ל-Cloud Storage או ל-BigQuery. יכול להיות שיחולו חיובים על Pub/Sub,‏ Cloud Storage או BigQuery. מידע נוסף מופיע במאמר סקירה כללית על ניתוב ואחסון.

הגדרת רישום ביומן של מדיניות הרשת

כדי להגדיר את ההגדרות של רישום ביומן של מדיניות רשת ב-Kubernetes, צריך לערוך את האובייקט NetworkLogging באשכול. ‫GKE יוצר באופן אוטומטי אובייקט NetworkLogging בשם default באשכולות Dataplane V2 חדשים. יכול להיות רק אובייקט NetworkLogging אחד לכל אשכול, ואי אפשר לשנות את השם שלו.

אפשר להגדיר בנפרד את הרישום ביומן של חיבורים מותרים ואת הרישום ביומן של חיבורים שנחסמו. אפשר גם להפעיל את הרישום ביומן באופן סלקטיבי עבור חלק ממדיניות הרשת. הדוגמה הבאה מציגה את NetworkLogging ההגדרה, עם הגדרות שקובעות שכל החיבורים שאושרו ונדחו יתועדו:

kind: NetworkLogging
apiVersion: networking.gke.io/v1alpha1
metadata:
  name: default
spec:
  cluster:
    allow:
      log: true
      delegate: false
    deny:
      log: true
      delegate: false

משתמשים בפקודה kubectl כדי לערוך את ההגדרה:

kubectl edit networklogging default

מפרט NetworkLogging

מפרט האובייקט NetworkLogging הוא בפורמט YAML. הפורמט הזה מתואר בטבלה הבאה:

שדהסוגתיאור
cluster.allowstruct הגדרות לרישום ביומן של חיבורים מותרים.
שדהסוגתיאור
log bool

אם הערך הוא true, החיבורים המותרים באשכול מתועדים ביומן. אחרת, החיבורים המותרים לא מתועדים ביומן.

מדיניות רשת ב-Kubernetes שבוחרת את ה-Pod וכוללת כלל שתואם לחיבור מפורטת בהודעה ביומן.

delegate bool

אם הערך הוא false, כל החיבורים המותרים מתועדים ביומן. אם כמה כללי מדיניות רשת ב-Kubernetes מאפשרים חיבור, כל כללי המדיניות התואמים מופיעים בהודעת היומן.

אם true, חיבורים מותרים מתועדים רק אם הם מותרים על ידי מדיניות רשת ב-Kubernetes עם אנוטציית הרישום ביומן policy.network.gke.io/enable-logging: "true". אם כמה מדיניות רשת ב-Kubernetes מאפשרות חיבור, כל כללי המדיניות התואמים עם ההערה enable-logging מפורטים בהודעה ביומן.

שגיאת הגדרה מתרחשת אם מגדירים את spec.cluster.allow.delegate ל-true ואת spec.cluster.allow.log ל-false.

cluster.deny struct הגדרות לרישום חיבורים שנדחו.
שדהסוגתיאור
log bool

אם המדיניות מוגדרת לערך true, החיבורים שנדחו באשכול נרשמים ביומן. אחרת, החיבורים שנדחו לא נרשמים ביומן.

delegate bool

אם הערך הוא false, כל החיבורים שנדחו נרשמים ביומן.

אם true, חיבורים שנדחו מתועדים רק אם ה-Pod שבו החיבור נדחה נמצא במרחב שמות עם ההערה policy.network.gke.io/enable-deny-logging: "true".

שגיאת הגדרה מתרחשת אם מגדירים את spec.cluster.deny.delegate ל-true ואת spec.cluster.deny.log ל-false.

גישה ליומנים של מדיניות הרשת ב-Kubernetes

יומני מדיניות הרשת מועלים אוטומטית ל-Cloud Logging. אפשר לגשת ליומנים דרך Logs Explorer או באמצעות Google Cloud CLI. אפשר גם לנתב יומנים לכיור.

Cloud Logging

  1. נכנסים לדף Logs Explorer במסוף Google Cloud .

    כניסה לדף Logs Explorer

  2. לוחצים על Query builder (כלי ליצירת שאילתות).

  3. כדי למצוא את כל הרשומות ביומן של מדיניות רשת ב-Kubernetes, משתמשים בשאילתה הבאה:

    resource.type="k8s_node"
    resource.labels.location="CLUSTER_LOCATION"
    resource.labels.cluster_name="CLUSTER_NAME"
    logName="projects/PROJECT_NAME/logs/policy-action"
    

    מחליפים את מה שכתוב בשדות הבאים:

במאמר שימוש ב-Logs Explorer מוסבר איך להשתמש ב-Logs Explorer.

אפשר גם ליצור שאילתה באמצעות הכלי לבניית שאילתות. כדי ליצור שאילתה ליומני מדיניות רשת ב-Kubernetes, בוחרים באפשרות policy-action מהרשימה הנפתחת שם היומן. אם אין יומנים זמינים, האפשרות policy-action לא מופיעה בתפריט הנפתח.

gcloud

כדי למצוא את כל הרשומות ביומן של מדיניות הרשת ב-Kubernetes:

gcloud logging read --project "PROJECT_NAME" 'resource.type="k8s_node"
    resource.labels.location="CLUSTER_LOCATION"
    resource.labels.cluster_name="CLUSTER_NAME"
    logName="projects/PROJECT_NAME/logs/policy-action"'

מחליפים את מה שכתוב בשדות הבאים:

  • ‫PROJECT_NAME: השם של הפרויקט ב- Google Cloud .
  • ‫CLUSTER_LOCATION: המיקום של Compute Engine של האשכול.
  • ‫CLUSTER_NAME: השם של האשכול.

אפשר להוסיף עוד תנאים כדי לסנן את התוצאות. לדוגמה:

  • הצגת יומנים במסגרת זמן מסוימת:

    timestamp>="2020-06-22T06:30:51.128Z"
    timestamp<="2020-06-23T06:30:51.128Z"
    
  • הצגת יומנים של חיבורים שנדחו:

    jsonPayload.disposition="deny"
    
  • הצגת יומנים של פריסה בשם "redis":

    jsonPayload.dest.pod_name=~"redis"
    jsonPayload.dest.pod_namespace="default"
    
  • הצגת יומנים של חיבורים חיצוניים לאשכול:

    jsonPayload.dest.instance != ""
    
  • הצגת יומנים שתואמים למדיניות רשת ב-Kubernetes מסוימת, במקרה הזה allow-frontend-to-db:

    jsonPayload.policies.name="allow-frontend-to-db"
    jsonPayload.policies.namespace="default"
    

אם אתם משתמשים באשכול Standard, תוכלו גם למצוא את יומני מדיניות רשת ב-Kubernetes שנוצרו בכל צומת באשכול באופן מקומי ב-/var/log/network/policy_action.log*. קובץ יומן ממוספר חדש נוצר כשקובץ היומן הנוכחי מגיע ל-10MB. המערכת שומרת עד חמישה קובצי יומן קודמים.

הפורמט של יומן מדיניות הרשת

רשומות היומן של מדיניות רשת ב-Kubernetes הן בפורמט JSON. הפורמט הזה מתואר בטבלה הבאה:

שדהסוגתיאור
connectionstruct פרטי החיבור:
שדהסוגתיאור
src_ipstringכתובת ה-IP של המקור של החיבור.
src_portintיציאת המקור של החיבור.
dest_ipstringכתובת ה-IP של היעד של החיבור.
dest_portintיציאת היעד של החיבור.
protocolstringהפרוטוקול של החיבור, שיכול להיות אחד מהערכים tcp, udp או icmp.
directionstringכיוון החיבור, שיכול להיות ingress או egress.
srcstruct פרטי נקודת הקצה של המקור:
שדהסוגתיאור
pod_namestringשם ה-Pod, אם המקור הוא Pod.
pod_namespace (deprecated)stringמרחב השמות של ה-Pod, אם המקור הוא Pod. pod_namespace הוצא משימוש. במקומו צריך להשתמש ב-namespace.
namespacestringמרחב השמות של ה-Pod, אם המקור הוא Pod.
workload_namestringשם עומס העבודה, אם עומס העבודה של המקור זמין.
workload_kindstringסוג עומס העבודה, אם עומס העבודה של המקור זמין.
instancestringכתובת ה-IP של המקור, אם המקור הוא לא Pod.
deststruct פרטי נקודת הקצה של היעד:
שדהסוגתיאור
pod_namestringשם ה-Pod, אם היעד הוא Pod.
pod_namespace (deprecated)stringמרחב השמות של ה-Pod, אם היעד הוא Pod. pod_namespace הוצא משימוש, צריך להשתמש ב-namespace במקום.
namespacestringמרחב השמות של ה-Pod, אם היעד הוא Pod.
workload_namestringהשם של עומס העבודה, אם עומס העבודה של היעד זמין.
workload_kindstringסוג עומס העבודה, אם עומס העבודה ביעד זמין.
instancestringכתובת ה-IP של המקור, אם היעד הוא לא Pod.
dispositionstringהסטטוס של החיבור, שיכול להיות allow או deny.
policieslist of structs

כללי מדיניות תואמים לחיבורים המותרים מנקודת המבט של ה-Pod שנאכף. בחיבורי Ingress, ה-Pod שנאכף הוא ה-Pod של היעד. בחיבור יוצא, ה-Pod שנאכף הוא ה-Pod של המקור. אם חיבור מסוים תואם לכל המדיניות, כל המדיניות הזו מתועדת.

השדה הזה נכלל רק ביומנים של חיבורים מותרים.

שדהסוגתיאור
namestringהשם של מדיניות רשת ב-Kubernetes התואמת.
namespacestringמרחב השמות של מדיניות הרשת התואמת ב-Kubernetes.
countintמשמש לצבירת יומנים של שאילתות שנדחו. הערך הוא תמיד 1 לחיבור מותר.
node_namestringהצומת שמריץ את ה-Pod שיצר את הודעת היומן הזו.
timestampstringמתי התרחש ניסיון החיבור.

הגדרת החיבור

בפרוטוקולים מוכווני-חיבור כמו TCP, נוצרת רשומה ביומן לכל חיבור שאושר או נדחה. בפרוטוקולים כמו UDP ו-ICMP, שאינם מוכווני-חיבור, החבילות מקובצות לחיבורים שמבוססים על חלון זמן.

יומני מדיניות של חיבורים שנדחו

רשומות היומן של חיבורים שנדחו לא כוללות את השדה policies כי ל-Kubernetes מדיניות רשת ב-Kubernetes API אין מדיניות דחייה מפורשת. החיבור נדחה אם Pod מסוים נכלל במדיניות רשת ב-Kubernetes אחת או יותר, אבל אף אחת מהן לא מאפשרת את החיבור. המשמעות היא שאף מדיניות לא אחראית באופן פרטני לחיבור שנחסם.

צבירת יומנים לחיבורים שנדחו

לפעמים לקוח מנסה שוב להתחבר אחרי שהגישה שלו נדחתה. כדי למנוע רישום מוגזם ביומן, חיבורים שנדחו שוב ושוב בטווח של חמש שניות נצברים להודעת יומן אחת באמצעות השדה count.

חיבורים שנדחו לאחר מכן נצברים עם הודעת יומן קודמת אם ה-src_ip, dest_ip, dest_port, protocol, וה-direction של החיבור תואמים לחיבור הראשון שנדחה. שימו לב: src_port של חיבורים עוקבים לא חייב להיות זהה כי חיבורים חוזרים עשויים להגיע מיציאה אחרת. הודעת היומן המצטברת כוללת את src_prt של החיבור הראשון שנדחה בתחילת חלון הצבירה.

דוגמאות לרשומות ביומן

מדיניות הרשת הבאה בשם allow-green שחלה על test-service מאפשרת חיבורים אל test-service מ-Pod בשם client-green. באופן משתמע, המדיניות הזו דוחה את כל תעבורת הנתונים הנכנסת האחרת אל test-service, כולל מה-Pod‏ client-red.

  apiVersion: networking.k8s.io/v1
  kind: NetworkPolicy
  metadata:
    name: allow-green
    namespace: default
    annotations:
      policy.network.gke.io/enable-logging: "true"
  spec:
    podSelector:
      matchLabels:
        app: test-service
    ingress:
    - from:
      - podSelector:
          matchLabels:
            app: client-green
    policyTypes:
    - Ingress

בתרשים הזה מוצגת ההשפעה של מדיניות allow-green על שני חיבורים ל-test-service. המדיניות allow-green מאפשרת את החיבור מ-client-green. החיבור נדחה כי אין מדיניות שמאפשרת חיבור מ-client-red.

תמונה

היומן של החיבור המורשה מ-client-green נראה כך:

{
   "connection":{
      "src_ip":"10.84.0.252",
      "dest_ip":"10.84.0.165",
      "src_port":52648,
      "dest_port":8080,
      "protocol":"tcp",
      "direction":"ingress"
   },
   "disposition":"allow",
   "policies":[
      {
         "name":"allow-green",
         "namespace":"default"
      }
   ],
   "src":{
      "pod_name":"client-green-7b78d7c957-68mv4",
      "pod_namespace":"default",
      "namespace":"default",
      "workload_name":"client-green-7b78d7c957",
      "workload_kind":"ReplicaSet"
   },
   "dest":{
      "pod_name":"test-service-745c798fc9-sfd9h",
      "pod_namespace":"default",
      "namespace":"default",
      "workload_name":"test-service-745c798fc9",
      "workload_kind":"ReplicaSet"
   },
   "count":1,
   "node_name":"gke-demo-default-pool-5dad52ed-k0h1",
   "timestamp":"2020-06-16T03:10:37.993712906Z"
}

היומן של החיבור שנדחה מ-client-red נראה כך:

{
   "connection":{
      "src_ip":"10.84.0.180",
      "dest_ip":"10.84.0.165",
      "src_port":39610,
      "dest_port":8080,
      "protocol":"tcp",
      "direction":"ingress"
   },
   "disposition":"deny",
   "src":{
      "pod_name":"client-red-5689846f5b-b5ccx",
      "pod_namespace":"default",
      "namespace":"default",
      "workload_name":"client-red-5689846f5b",
      "workload_kind":"ReplicaSet"
   },
   "dest":{
      "pod_name":"test-service-745c798fc9-sfd9h",
      "pod_namespace":"default",
      "namespace":"default",
      "workload_name":"test-service-745c798fc9",
      "workload_kind":"ReplicaSet"
   },
   "count":3,
   "node_name":"gke-demo-default-pool-5dad52ed-k0h1",
   "timestamp":"2020-06-15T22:38:32.189649531Z"
}

שימו לב שיומן החיבורים שנדחו לא כולל את השדה policies. התיאור הזה מופיע בקטע הקודם, יומני מדיניות לחיבורים שנדחו.

יומן החיבורים שנדחו כולל שדה count לצירוף של חיבורים שנדחו.

פתרון בעיות שקשורות ליומני מדיניות רשת ב-Kubernetes

  1. בודקים אם יש אירועי שגיאה באובייקט NetworkLogging:

    kubectl describe networklogging default
    

    אם הגדרת הרישום ביומן לא תקינה, ההגדרה לא תיכנס לתוקף ותופיע שגיאה בקטע 'אירועים':

    Name:         default
    Namespace:
    Labels:       addonmanager.kubernetes.io/mode=EnsureExists
    Annotations:  API Version:  networking.gke.io/v1alpha1
    Kind:         NetworkLogging
    Metadata:
      Creation Timestamp:  2020-06-20T05:54:08Z
      Generation:          8
      Resource Version:    187864
      Self Link:           /apis/networking.gke.io/v1alpha1/networkloggings/default
      UID:                 0f1ddd6e-4193-4295-9172-baa6a52aa6e6
    Spec:
      Cluster:
        Allow:
          Delegate:  true
          Log:       false
        Deny:
          Delegate:  false
          Log:       false
    Events:
      Type     Reason                 Age                From                                                               Message
      ----     ------                 ----               ----                                                               -------
      Warning  InvalidNetworkLogging  16s (x3 over 11h)  network-logging-controller, gke-anthos-default-pool-cee49209-0t09  cluster allow log action is invalid: delegate cannot be true when log is false
      Warning  InvalidNetworkLogging  16s (x3 over 11h)  network-logging-controller, gke-anthos-default-pool-cee49209-80fx  cluster allow log action is invalid: delegate cannot be true when log is false
    
  2. כדי להגביל את ניצול ה-CPU שמוקדש לרישום ביומן, צומת יכול לרשום ביומן עד 500 חיבורים בשנייה לפני שהוא מתחיל להשמיט יומנים. מדיניות רשת ב-Kubernetes בצומת עדיין נאכפת. כדי לראות אם יש יומני מדיניות שהושמטו, בודקים אם יש מוני שגיאות שהערך שלהם גדל:

    kubectl exec ANETD_POD_NAME -n kube-system -- curl -s http://localhost:9990/metrics |grep policy_logging
    

    מחליפים את ANETD_POD_NAME בשם של Pod מסוג anetd. בודקים כל צומת. anetd הוא בקר הרשת של Dataplane V2.

יומנים ללא שם מופיעים עבור Pods עם מדיניות דחייה שמוגדרת כברירת מחדל

בדיקות פעילות, מוכנות והפעלה דורשות שה-Pod יקבל חיבורי Ingress שנוצרו על ידי הבדיקות מ-kubelet. כדי לוודא שהבקשות לבדיקת תקינות האלה פועלות בצורה תקינה, GKE מאפשרת באופן אוטומטי תעבורת נתונים של בקשות לבדיקת תקינות אל ה-Pod שנבחר, בהתאם להגדרות של ה-Pod, ללא קשר למדיניות רשת ב-Kubernetes שחלה על ה-Pod. אי אפשר לשנות את ההתנהגות הזו.

היומנים של חיבורי הבדיקה דומים ליומנים הבאים:

{
   "connection":{
      "src_ip":"10.88.1.1",
      "dest_ip":"10.88.1.4",
      "src_port":35848,
      "dest_port":15021,
      "protocol":"tcp",
      "direction":"ingress"
   },
   "disposition":"allow",
   "src":{
      "instance":"10.88.1.1"
   },
   "dest":{
      "pod_name":"testpod-745c798fc9-sfd9h",
      "pod_namespace":"default",
      "namespace":"default",
      "workload_name":"testpod-745c798fc9",
      "workload_kind":"ReplicaSet"
   },
   "count":1,
   "policies": [
     {
       "name":""
     }
    ],
   "node_name":"gke-demo-default-pool-5dad52ed-k0h1",
   "timestamp":"2021-04-01T12:42:32.1898720941Z"
}

אלה המאפיינים של היומן:

  • הערך של policies.name ריק כי אין מדיניות רשת משויכת שמאפשרת את החיבור.
  • הערך של connection.src_ip לא תואם לאף תרמיל או צומת.

המאמרים הבאים