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

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

סקירה כללית

באמצעות רישום ביומן של מדיניות הרשת, אפשר:

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

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

דרישות

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

תמחור

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

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

כדי להגדיר את ההגדרות של רישום ביומן של מדיניות הרשת, צריך לערוך את האובייקט באשכול.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, החיבורים המותרים באשכול נרשמים ביומן. אחרת, החיבורים המותרים לא נרשמים ביומן.

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

delegate bool

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

אם משתמשים ב-true, רישום של חיבורים מותרים מתבצע רק אם הם מותרים על ידי מדיניות רשת עם הערת הרישום policy.network.gke.io/enable-logging: "true". אם כמה כללי מדיניות רשת מאפשרים חיבור, כל כללי המדיניות התואמים עם ההערה 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.

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

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

Cloud Logging

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

    כניסה לדף Logs Explorer

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

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

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

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

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

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

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

gcloud

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

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 != ""
    
  • הצגת יומנים שתואמים למדיניות רשת מסוימת, במקרה הזה allow-frontend-to-db:

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

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

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

רשומות היומן של מדיניות הרשת הן בפורמט 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 שנאכף. בחיבור נכנס, ה-Pod שנאכף הוא ה-Pod של היעד. בחיבור יציאה, ה-Pod שנאכף הוא ה-Pod של המקור. אם חיבור תואם לכללי מדיניות רבים, הם נרשמים ביומן.

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

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

הגדרה של חיבור

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

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

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

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

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

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

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

בדוגמה הבאה, מדיניות הרשת בשם allow-green שחלה על test-service מאפשרת חיבורים אל test-service מ-Pod בשם client-green. באופן מרומז, המדיניות הזו דוחה את כל תעבורת הנתונים הנכנסת (ingress) האחרת אל 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 לצירוף של חיבורים שנדחו.

פתרון בעיות ביומני מדיניות הרשת

  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 חיבורים בשנייה לפני שהוא מתחיל להשמיט רשומות ביומן. מדיניות הרשת בצומת עדיין נאכפת. כדי לראות אם יש יומני מדיניות שהושמטו, בודקים אם יש מוני שגיאות שמבצעים אינקרימנט:

    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, ללא קשר למדיניות הרשת שחלה על ה-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 לא תואם לאף תרמיל או צומת.

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