הגדרת שער NAT לתעבורת נתונים יוצאת

בעזרת Google Distributed Cloud, אתם יכולים להגדיר תרגום כתובות רשת של מקור (SNAT) כדי שלתנועת נתונים יוצאת מסוימת מאשכול המשתמשים שלכם תוקצה כתובת IP צפויה של המקור.

במסמך הזה מוסבר איך להגדיר שער NAT לתעבורת נתונים יוצאת עבור אשכול משתמשים.

מבוא

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

ריכזנו כאן כמה תרחישים:

  • יש לכם חומת אש לפני מסד נתונים שמאפשרת גישה רק לפי כתובת IP. הצוות שמנהל את חומת האש של מסד הנתונים שונה מהצוות שמנהל את אשכול המשתמשים.

  • עומסי עבודה באשכול המשתמשים צריכים לגשת ל-API של צד שלישי דרך האינטרנט. מטעמי אבטחה, ספק ה-API מאמת את התנועה ומעניק לה הרשאה באמצעות כתובת ה-IP כזהות.

עם שער NAT ליציאה, אתם יכולים לשלוט בצורה מדויקת בכתובות ה-IP של המקור שמשמשות לתעבורת נתונים שיוצאת מאשכול.

איך שער NAT ליציאה עובד

בדרך כלל, כש-Pod שולח חבילת נתונים מחוץ לאשכול, חבילת הנתונים מתורגמת באמצעות SNAT עם כתובת ה-IP של הצומת שבו ה-Pod פועל.

כששער NAT לתעבורת נתונים יוצאת (egress) מוגדר, אפשר לציין שחלק מהמנות היוצאות יישלחו קודם לצומת שער ייעודי. ממשק הרשת בצומת השער מוגדר עם שתי כתובות IP: כתובת ה-IP הראשית וכתובת IP של מקור יציאה.

כשמנה נבחרת לשימוש בשער NAT ליציאה, היא יוצאת מהאשכול מצומת השער ועוברת תרגום SNAT עם כתובת ה-IP של המקור ליציאה שהוגדרה בממשק הרשת.

התרשים הבא מדגים את זרימת המנות:

זרימת מנות עם NAT Gateway לתעבורת נתונים יוצאת.

בתרשים הקודם אפשר לראות את הזרימה של חבילת נתונים שנשלחת מה-Pod.

  1. בצומת עם כתובת ה-IP‏ 192.168.1.1, ‏ Pod עם כתובת ה-IP‏ 10.10.10.1 יוצר חבילת נתונים יוצאת.

  2. החבילה תואמת לכלל לתעבורת נתונים יוצאת (egress), ולכן היא מועברת לצומת של שער הכניסה.

  3. צומת השער משנה את כתובת ה-IP של המקור ל-192.168.1.100 ושולח את חבילת הנתונים אל מחוץ לאשכול.

  4. תנועת החזרה מגיעה בחזרה לצומת השער עם היעד 192.168.1.100.

  5. צומת השער משתמש ב-conntrack כדי לשנות את כתובת ה-IP של היעד ל-10.10.10.1.

  6. החבילה מטופלת כתנועה בתוך האשכול, מועברת לצומת המקורי ומוחזרת ל-Pod המקורי.

פרסונות

בנושא הזה נתייחס לשתי דמויות:

  • אדמין של אשכול. האדם הזה יוצר אשכול משתמש ומציין כתובות IP צפות לשימוש על ידי Anthos Network Gateway.

  • מפתח. המשתמש הזה מריץ עומסי עבודה באשכול המשתמשים ויוצר מדיניות יציאה.

הפעלת שער NAT ליציאה

הקטע הזה מיועד לאדמינים של אשכולות.

כדי להגדיר שער NAT לתעבורת נתונים יוצאת (egress), משתמשים בשדות enableDataplaneV2 ו-advancedNetworking בקובץ ההגדרות של אשכול המשתמשים, ויוצרים אובייקט אחד או יותר מסוג NetworkGatewayGroup.

בקובץ התצורה של האשכול, מגדירים את השדות האלה לערך true:

enableDataplaneV2: true
...
advancedNetworking: true

יוצרים את אשכול המשתמשים.

ציון כתובות IP צפות

הקטע הזה מיועד לאדמינים של אשכולות.

בוחרים קבוצה של כתובות IP שרוצים להשתמש בהן ככתובות מקור ליציאה. הן נקראות כתובות IP צפות, כי Network Gateway Group מקצה אותן, לפי הצורך, לממשקי הרשת של הצמתים שהוא בוחר להיות שערים ליציאה.

כתובות ה-IP הצפות צריכות להיות באותה תת-רשת כמו כתובות ה-IP של הצומת.

הקבוצה של כתובות ה-IP הדינמיות לא יכולה לחפוף לקבוצה של כתובות ה-IP שציינתם עבור הצמתים.

לדוגמה, נניח שלרשת משנה יש טווח כתובות 192.168.1.0/24. נניח שבחרתם להשתמש בכתובות 192.168.1.1 עד 192.168.1.99 לצמתים. אז אפשר להשתמש בכתובות 192.168.1.100 עד 192.168.1.104 ככתובות IP צפות.

יצירת אובייקט NetworkGatewayGroup

הקטע הזה מיועד לאדמינים של אשכולות.

דוגמה למניפסט של אובייקט NetworkGatewayGroup:

kind: NetworkGatewayGroup
apiVersion: networking.gke.io/v1
metadata:
  namespace: kube-system
  name: default
spec
  floatingIPs:
  - 192.168.1.100
  - 192.168.1.101
  - 192.168.1.102
  - 192.168.1.103
  - 192.168.1.104

מחליפים את המערך floatingIPs בכתובות ה-IP הדינמיות שלכם ושומרים את המניפסט בקובץ בשם my-ngg.yaml.

יוצרים את האובייקט NetworkGatewayGroup:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG apply -f my-ngg.yaml

דוגמה למדיניות NAT ליציאה

הקטע הזה מיועד למפתחים.

דוגמה למשאב מותאם אישית מסוג EgressNatPolicy:

kind: EgressNATPolicy
apiVersion: networking.gke.io/v1
metadata:
  name: alice-paul
spec:
  sources:
  - namespaceSelector:
      matchLabels:
        user: alice
    podSelector:
      matchLabels:
        role: frontend
  - namespaceSelector:
      matchLabels:
        user: paul
    podSelector:
      matchLabels:
        role: frontend
  action: SNAT
  destinations:
  - cidr: 8.8.8.0/24
  gatewayRef:
    name: default
    namespace: kube-system

במניפסט שלמעלה אפשר לראות:

  • פוד הוא מועמד ל-NAT של תעבורת נתונים יוצאת (egress) אם הוא עומד באחד מהתנאים הבאים:

    • ל-Pod יש את התווית role: frontend, וה-Pod נמצא במרחב שמות עם התווית user: alice.

    • ל-Pod יש את התווית role: frontend, וה-Pod נמצא במרחב שמות עם התווית user: paul.

  • תנועה מ-Pod של מועמד לכתובת בטווח 8.8.8.0/24 נשלחת לשער NAT של יציאה.

  • בקטע gatewayRef מוגדרת כתובת ה-IP של מקור היציאה. המשאב המותאם אישית EgressNATPolicy משתמש בערכים gatewayRef.name ו-gatewayRef.namespace כדי למצוא אובייקט NetworkGatewayGroup. המדיניות משתמשת באחת מכתובות ה-IP הצפות של NetworkGatewayGroup ככתובת ה-IP של המקור לתעבורת נתונים יוצאת. אם יש כמה כתובות IP צפות בקבוצת NetworkGatewayGroup התואמת, המדיניות משתמשת בכתובת ה-IP הראשונה ברשימה floatingIPs ומתעלמת מכתובות IP אחרות. אם יש שדות לא תקינים בקטע gatewayRef, לא תהיה אפשרות להחיל את האובייקט EgressNATPolicy.

יצירת אובייקט EgressNATPolicy

יוצרים מניפסט EgressNATPolicy משלכם. מגדירים את metadata.name להיות "my-policy". שומרים את קובץ המניפסט בשם my-policy.yaml.

יוצרים את האובייקט EgressNatPolicy:

kubectl apply --kubeconfig USER_CLUSTER_KUBECONFIG -f my-policy.yaml

הצגת מידע על מדיניות NAT ליציאה

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get egressnatpolicy my-policy --output yaml

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get networkgatewaygroup --namespace kube-system --output yaml

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG describe egressnatpolicy my-policy

סדר הפעולות

מדיניות NAT לתעבורת נתונים יוצאת (egress) תואמת לממשקי API של מדיניות רשת. מדיניות הרשת מוערכת לפני מדיניות NAT של יציאה. אם מדיניות רשת קובעת שצריך להשליך חבילת נתונים, חבילת הנתונים מושלכת בלי קשר למדיניות ה-NAT של התעבורה היוצאת.

מדיניות תעבורת נתונים יוצאת מרובה

כפי שמתואר למעלה, כל EgressNATPolicy משתמש בכתובת ה-IP הראשונה ברשימה floatingIPs מ-NetworkGatewayGroup שתואמת ל-gatewayRef.name ול-gatewayRef.namespace. אם יוצרים כמה כללי מדיניות ומתכוונים להשתמש בכתובות IP שונות, צריך ליצור כמה אובייקטים מסוג NetworkGatewayGroup ולהפנות אליהם בהתאם. אם יוצרים כמה כללי מדיניות, אובייקט gatewayRef צריך להיות ייחודי לכל כלל מדיניות.

כל משאב NetworkGatewayGroup צריך להכיל כתובות IP צפות ייחודיות. כדי להגדיר כמה אובייקטים של EgressNATPolicy לשימוש באותה כתובת IP, צריך להשתמש באותו gatewayRef.name ובאותו gatewayRef.namespace בשניהם.

כדי להגדיר כמה כללי מדיניות ליציאה וכמה אובייקטים של שערים:

  1. יוצרים אובייקטים של שערים במרחב השמות kube-system כדי לנהל כל כתובת IP צפה. בדרך כלל, לכל מדיניות יציאה צריך להיות אובייקט שער תואם כדי להבטיח הקצאה של כתובת ה-IP הנכונה.

    לאחר מכן מאמתים כל אובייקט של שער באמצעות kubectl כדי לקבל את סטטוס ההקצאה של כתובות ה-IP הצפות:

    kind: NetworkGatewayGroup
    apiVersion: networking.gke.io/v1
    metadata:
      namespace: kube-system
      name: gateway1
    spec:
      floatingIPs:
      - 192.168.1.100
    status:
      ...
      floatingIPs:
        192.168.1.100: worker1
    ---
    kind: NetworkGatewayGroup
    apiVersion: networking.gke.io/v1
    metadata:
      namespace: kube-system
      name: gateway2
    spec:
      floatingIPs:
      - 192.168.1.101
    status:
      ...
      floatingIPs:
        192.168.1.101: worker2
    ---
    kind: NetworkGatewayGroup
    apiVersion: networking.gke.io/v1
    metadata:
      namespace: kube-system
      name: gateway3
    spec:
      floatingIPs:
      - 192.168.1.102
    status:
      ...
      floatingIPs:
        192.168.1.102: worker1
    
  2. יוצרים כמה כללי מדיניות שמפנים לאובייקטים של השער, כמו gateway1 שנוצר בשלב הקודם:

    kind: EgressNATPolicy
    apiVersion: networking.gke.io/v1
    metadata:
      name: egresspolicy1
    spec:
      ...
      gatewayRef:
        name: gateway1
        namespace: kube-system
    ---
    kind: EgressNATPolicy
    apiVersion: networking.gke.io/v1
    metadata:
      name: egresspolicy2
    spec:
      ...
      gatewayRef:
        name: gateway2
        namespace: kube-system
    ---
    kind: EgressNATPolicy
    apiVersion: networking.gke.io/v1
    metadata:
      name: egresspolicy3
    spec:
      ...
      gatewayRef:
        name: gateway3
        namespace: kube-system
    

(אופציונלי) ציון צמתים להצבת כתובות IP צפות

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

kind: NetworkGatewayGroup
apiVersion: networking.gke.io/v1
metadata:
  namespace: cluster-cluster1
  name: default
spec:
  floatingIPs:
  - 192.168.1.100
  - 192.168.1.101
  - 192.168.1.102
  nodeSelector:
    node-type: "egressNat"

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