בדף הזה מוסבר איך לשלוט בתקשורת יוצאת בין קבוצות Pod ובין משאבים מחוץ לאשכול Google Kubernetes Engine (GKE) באמצעות שמות דומיין מלאים (FQDN). המשאב המותאם אישית שמשמש להגדרת שמות דומיין מלאים (FQDN) הוא משאב FQDNNetworkPolicy.
לפני שמתחילים
לפני שמתחילים, חשוב לוודא שביצעתם את המשימות הבאות:
- מפעילים את ממשק ה-API של Google Kubernetes Engine. הפעלת Google Kubernetes Engine API
- כדי להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז לאתחל את ה-CLI של gcloud. אם התקנתם בעבר את ה-CLI של gcloud, מריצים את הפקודה
gcloud components updateכדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.
דרישות ומגבלות
הדרישות והמגבלות הבאות חלות על משאבי FQDNNetworkPolicy:
- צריך להריץ אשכול GKE באחת מהגרסאות הבאות:
- 1.26.4-gke.500 ואילך
- 1.27.1-gke.400 ואילך
- באשכול צריך להשתמש ב-GKE Dataplane V2.
- אתם צריכים להשתמש באחד מספקי ה-DNS באשכול GKE, kube-dns או Cloud DNS. אין תמיכה בפריסות מותאמות אישית של kube-dns או Core DNS.
- Google Cloud CLI בגרסה 462.0.0 ואילך.
- אין תמיכה במאגרי צמתים של Windows.
- אין תמיכה ב-Cloud Service Mesh.
- אם יש לכם כתובות IP שמוגדרות בהארדקוד באפליקציה, צריך להשתמש בשדה
IPBlockשל KubernetesNetworkPolicyבמקום ב-FQDNNetworkPolicy. - תוצאות שמוחזרות על ידי שרתי שמות DNS שאינם שייכים לאשכול, כמו שרתי שמות חלופיים ב-
resolv.conf, לא נחשבות תקפות לצורך תכנות ברשימת ההיתרים במישור הנתונים של GKE. - המספר המקסימלי של כתובות IPv4 ו-IPv6 שאפשר להקצות ל-
FQDNNetworkPolicyהוא 50. - אי אפשר לאפשר תעבורה ל-ClusterIP או לשירות Headless כיעד יציאה ב-
FQDNNetworkPolicy, כי GKE מתרגם את כתובת ה-IP הווירטואלית (VIP) של השירות לכתובות IP של Pod בקצה העורפי לפני הערכת הכללים של מדיניות רשת ב-Kubernetes. במקום זאת, משתמשים בNetworkPolicyשמבוסס על תוויות Kubernetes. - יש מכסת מקסימום של 100 כתובות IP לכל שם מארח.
- הצפנה שקופה בין צמתים לא אפשרית במדיניות רשת עם FQDN.
- מדיניות רשת FQDN שמשתמשת בהתאמת תבניות מתאימה רק לתת-דומיינים באותה רמה כמו התו הכללי. לדוגמה,
pattern: *.company.comתואם ל-api.company.comאו ל-store.company.com, אבל לא ל-eu.api.company.comאו ל-company.com.
הפעלת מדיניות רשת FQDN
אפשר להפעיל מדיניות רשת FQDN באשכול חדש או באשכול קיים.
הפעלת מדיניות רשת FQDN באשכול חדש
יוצרים את האשכול באמצעות הדגל --enable-fqdn-network-policy:
gcloud container clusters create CLUSTER_NAME \
--enable-fqdn-network-policy
מחליפים את CLUSTER_NAME בשם האשכול.
הפעלת מדיניות רשת FQDN באשכול קיים
גם באשכולות במצב Autopilot וגם באשכולות במצב Standard, מעדכנים את האשכול באמצעות הדגל
--enable-fqdn-network-policy:gcloud container clusters update CLUSTER_NAME \ --enable-fqdn-network-policyמחליפים את
CLUSTER_NAMEבשם האשכול.באשכולות Standard בלבד, מפעילים מחדש את GKE Dataplane V2
anetdDaemonSet:kubectl rollout restart ds -n kube-system anetd
יצירת FQDNNetworkPolicy
שומרים את קובץ המניפסט הבא בשם
fqdn-network-policy.yaml:apiVersion: networking.gke.io/v1alpha1 kind: FQDNNetworkPolicy metadata: name: allow-out-fqdnnp spec: podSelector: matchLabels: app: curl-client egress: - matches: - pattern: "*.yourdomain.com" - name: "www.google.com" ports: - protocol: "TCP" port: 443למניפסט הזה יש את המאפיינים הבאים:
-
name: www.google.com: שם הדומיין המלא. מותרות כתובות IP שמסופקות על ידי שרת השמות שמשויך ל-www.google.com. חובה לציין אתnameאו אתpattern, או את שניהם. pattern: "*.yourdomain.com": מותרות כתובות IP שסופקו על ידי שרתי שמות שתואמים לתבנית הזו. אפשר להשתמש בביטויים הרגולריים הבאים עבור מפתח התבנית:^([a-zA-Z0-9*]([-a-zA-Z0-9_*]*[a-zA-Z0-9*])*\.?)*$. קריטריוני ההתאמה הם מצטברים. אפשר להשתמש בכמה שדותpattern. חובה לציין אתnameאו אתpattern, או את שניהם.-
protocol: "TCP"ו-port: 443: מציינים פרוטוקול ויציאה. אם רכיב Pod מנסה ליצור חיבור לכתובות IP באמצעות הפרוטוקול הזה ושילוב היציאה, פתרון השם פועל, אבל מישור הנתונים חוסם את החיבור היוצא. השדה הזה הוא אופציונלי.
-
מוודאים שמדיניות רשת ב-Kubernetes בוחרת את עומסי העבודה:
kubectl describe fqdnnpהפלט אמור להיראות כך:
Name: allow-out-fqdnnp Labels: <none> Annotations: <none> API Version: networking.gke.io/v1alpha1 Kind: FQDNNetworkPolicy Metadata: ... Spec: Egress: Matches: Pattern: *.yourdomain.com Name: www.google.com Ports: Port: 443 Protocol: TCP Pod Selector: Match Labels: App: curl-client Events: <none>
מחיקת FQDNNetworkPolicy
כדי למחוק FQDNNetworkPolicy, משתמשים בפקודה kubectl delete fqdnnp:
kubectl delete fqdnnp FQDN_POLICY_NAME
מחליפים את FQDN_POLICY_NAME בשם של FQDNNetworkPolicy.
GKE מוחק את הכללים מאכיפת המדיניות, אבל חיבורים קיימים נשארים פעילים עד שהם נסגרים בהתאם להנחיות של פרוטוקול conntrack.
איך פועלת מדיניות רשת FQDN
FQDNNetworkPolicies הן מדיניות ליציאה בלבד, שקובעת לאילו נקודות קצה פודים נבחרים יכולים לשלוח תעבורה. בדומה ל-Kubernetes NetworkPolicy, FQDNNetworkPolicy שבוחר עומס עבודה יוצר כלל דחייה מרומז לנקודות קצה שלא צוינו כיעדי יציאה מותרים. FQDNNetworkPolicies
אפשר להשתמש ב-Kubernetes NetworkPolicies כמו שמתואר במאמרים FQDNNetworkPolicy
ו-NetworkPolicy.
FQDNNetworkPolicies נאכפות ברמת כתובת ה-IP והיציאה. הם לא נאכפים באמצעות מידע על פרוטוקול Layer 7 (לדוגמה, Request-URI בבקשת HTTP). שמות הדומיינים שצוינו מתורגמים לכתובות IP באמצעות פרטי ה-DNS שסופקו על ידי ספק ה-DNS של אשכול GKE.
בקשות DNS
אם יש לכם FQDNNetworkPolicy פעיל שבוחר עומסי עבודה, הוא לא משפיע על היכולת של עומסי העבודה לשלוח בקשות DNS. פקודות כמו nslookup או dig פועלות בכל הדומיינים בלי להיות מושפעות מהמדיניות. עם זאת, בקשות עוקבות לכתובת ה-IP שמאחורי דומיינים שלא נמצאים ברשימת ההיתרים יידחו.
לדוגמה, אם FQDNNetworkPolicy מאפשר תעבורת נתונים יוצאת (egress) אל www.github.com, אז בקשות DNS לכל הדומיינים מותרות, אבל תעבורת נתונים שנשלחת לכתובת IP שמגבה את twitter.com נפסלת.
תפוגת ה-TTL
FQDNNetworkPolicy מכבד את ה-TTL שמוגדר ברשומת DNS. אם רכיב Pod מנסה ליצור קשר עם כתובת IP שתוקפה פג אחרי שחלף הזמן שמוגדר בשדה TTL של רשומת ה-DNS, בקשות לחיבורים חדשים נדחות. בחיבורים ארוכי טווח שהמשך שלהם חורג מה-TTL של רשומת ה-DNS, לא אמורות להיות הפרעות בתנועה בזמן שהחיבור נחשב עדיין פעיל על ידי conntrack.
FQDNNetworkPolicy ו-NetworkPolicy
אם גם FQDNNetworkPolicy וגם NetworkPolicy חלות על אותו Pod, כלומר התוויות של ה-Pod תואמות למה שמוגדר במדיניות, תעבורת נתונים יוצאת מותרת כל עוד היא תואמת לאחת מהמדיניות. אין היררכיה בין NetworkPolicies לבין FQDNNetworkPolicies.
נקודות קצה (endpoints) של כתובות IP משותפות (מאזני עומסים, CDN, שער VPN וכו')
להרבה דומיינים אין כתובות IP ייעודיות שתומכות בהם, והם נחשפים באמצעות כתובות IP משותפות. זה נפוץ במיוחד כשהאפליקציה מוגשת על ידי מאזן עומסים או CDN. לדוגמה,
לממשקי API (Google Cloud , compute.googleapis.com, container.googleapis.com וכו') אין כתובות IP ייחודיות לכל API.
במקום זאת, כל ממשקי ה-API נחשפים באמצעות טווח משותף.
כשמגדירים את FQDNNetworkPolicies, חשוב לבדוק אם הדומיינים המותרים משתמשים בכתובות IP ייעודיות או בכתובות IP משותפות. מכיוון שFQDNNetworkPolicies נאכפים ברמת כתובת ה-IP והיציאה, הם לא יכולים להבחין בין כמה דומיינים שמוצגים על ידי אותה כתובת IP. מתן גישה לדומיין שמגובה על ידי כתובת IP משותפת יאפשר ל-Pod שלכם לתקשר עם כל הדומיינים האחרים שמקבלים שירות על ידי כתובת ה-IP הזו. לדוגמה, אם תאפשרו תנועה אל compute.googleapis.com, תאפשרו גם תקשורת של ה-Pod עם ממשקי API אחרים של Google Cloud .
מעקב אחר CNAME
אם אובייקט ה-FQDN ב-FQDNNetworkPolicy כולל דומיין שיש לו רשומות CNAME ברשומת ה-DNS, צריך להגדיר את FQDNNetworkPolicy עם כל שמות הדומיינים שה-Pod יכול לשלוח להם שאילתות ישירות, כולל כל הכינויים הפוטנציאליים, כדי להבטיח התנהגות מהימנה של FQDNNetworkPolicy.
אם שאילתת ה-Pod היא example.com, אז example.com זה מה שצריך לכתוב
בכלל. גם אם תקבלו שרשרת של שמות בדויים משרתי ה-DNS במעלה הזרם (לדוגמה, example.com עד example.cdn.com עד 1.2.3.4), מדיניות הרשת FQDN עדיין תאפשר לתנועה שלכם לעבור.
בעיות ידועות
בקטע הזה מפורטות כל הבעיות המוכרות בשמות דומיין שמוגדרים במלואם (FQDN).
אם מציינים protocol: ALL, המערכת מתעלמת מהמדיניות
הבעיה המוכרת הזו תוקנה בגרסאות GKE 1.27.10-gke.1055000 ואילך ו-1.28.3-gke.1055000 ואילך
אם יוצרים FQDNNetworkPolicy שבו מציינים protocol: ALL בקטע ports, מערכת GKE לא אוכפת את המדיניות. הבעיה הזו מתרחשת בגלל בעיה בניתוח המדיניות. הבעיה הזו לא מתרחשת כשמציינים TCP או UDP.
כפתרון עקיף, אם לא מציינים protocol ברשומה ports, הכלל תואם לכל הפרוטוקולים כברירת מחדל. הסרת protocol: ALL עוקפת את בעיית הניתוח, ו-GKE אוכף את FQDNNetworkPolicy.
בגרסאות GKE 1.27.10-gke.1055000+ ו-1.28.3-gke.1055000+, המדיניות עם protocol: ALL מנותחת ומיושמת בצורה נכונה.
רישום ביומן של NetworkPolicy גורם ליומנים שגויים או חסרים
הבעיה המוכרת הזו תוקנה בגרסאות GKE 1.27.10-gke.1055000 ואילך ו-1.28.2-gke.1157000 ואילך
אם באשכול שלכם נעשה שימוש ברישום ביומן של מדיניות הרשת ובמדיניות רשת של FQDN, יש באג שיכול לגרום לחוסר בערכי יומן או לערכים שגויים.
כשמשתמשים ברישום ביומן של מדיניות רשת ב-Kubernetes בלי להשתמש בהרשאת גישה, ביומני המדיניות של חיבורי DNS שיוצאים מעומס עבודה מצוין באופן שגוי שהתעבורה נחסמה.
התנועה עצמה הייתה מותרת (לפי FQDNNetworkPolicy), אבל היו שגיאות ביומנים.
כשמשתמשים ברישום ביומן של מדיניות רשת ב-Kubernetes עם הענקת גישה, חסרים יומני מדיניות. התנועה עצמה לא מושפעת.
הבאג הזה תוקן בגרסאות GKE 1.27.10-gke.105500+ ו-1.28.2-gke.1157000+. חיבורי DNS יתועדו עכשיו בצורה נכונה כ-ALLOWED,
כשתנועת הגולשים נבחרת על ידי NetworkPolicy או FQDNNetworkPolicy.
המאמרים הבאים
- קריאת מאמרי העזרה של Kubernetes בנושא מדיניות רשת
- שימוש בתובנות אבטחה כדי לבחון דרכים נוספות להגנה על התשתית