בדף הזה מוסבר איך להשתמש ברישום ביומן של מדיניות הרשת ב-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.
תמחור
- אין חיובים על יצירת יומנים עבור רישום ביומן של מדיניות רשת.
- אם מאחסנים את היומנים ב-Cloud Logging, חלים חיובים רגילים על Cloud Logging.
- אפשר גם לנתב את היומנים ל-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.allow | struct |
הגדרות לרישום ביומן של חיבורים מותרים.
|
|||||||||
cluster.deny |
struct |
הגדרות לרישום ביומן של חיבורים שנדחו.
|
גישה ליומנים של כללי מדיניות הרשת
יומני מדיניות הרשת מועלים אוטומטית ל-Cloud Logging. אפשר לגשת ליומנים דרך Logs Explorer או באמצעות Google Cloud CLI. אפשר גם להפנות יומנים למאגר.
Cloud Logging
נכנסים לדף Logs Explorer במסוף Google Cloud .
לוחצים על Query builder (כלי ליצירת שאילתות).
כדי למצוא את כל הרשומות ביומן של מדיניות הרשת, משתמשים בשאילתה הבאה:
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. הפורמט הזה מתואר בטבלה הבאה:
| שדה | סוג | תיאור | |||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
connection | struct |
פרטי החיבור:
|
|||||||||||||||||||||
src | struct |
פרטי נקודת הקצה של המקור:
|
|||||||||||||||||||||
dest | struct |
פרטי נקודת הקצה של היעד:
|
|||||||||||||||||||||
disposition | string | הסטטוס של החיבור, שיכול להיות allow או deny. | |||||||||||||||||||||
policies | list of structs |
כללי מדיניות תואמים לחיבורים המותרים בתצוגה של ה-Pod שנאכף. בחיבור נכנס, ה-Pod שנאכף הוא ה-Pod של היעד. בחיבור יציאה, ה-Pod שנאכף הוא ה-Pod של המקור. אם חיבור תואם לכללי מדיניות רבים, הם נרשמים ביומן. השדה הזה נכלל רק ביומנים של חיבורים מותרים.
|
|||||||||||||||||||||
count | int | משמש לצבירת יומנים של שאילתות שנדחו. הערך הוא תמיד 1 לחיבור מותר. | |||||||||||||||||||||
node_name | string | הצומת שמריץ את ה-Pod שיצר את הודעת היומן הזו. | |||||||||||||||||||||
timestamp | string | מתי התרחש ניסיון החיבור. |
הגדרה של חיבור
בפרוטוקולים מוכווני-חיבור כמו 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 לצירוף של חיבורים שנדחו.
פתרון בעיות ביומני מדיניות הרשת
בודקים אם יש אירועי שגיאה באובייקט
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כדי להגביל את השימוש במעבד (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לא תואם לאף תרמיל או צומת.
המאמרים הבאים
- איך צופים ביומנים ומנתחים אותם באמצעות Cloud Logging
- מטמיעים גישות נפוצות להגבלת התנועה באמצעות מדיניות רשת.