הגדרת מדיניות רשת

בדף הזה נדגים איך להשתמש במדיניות רשת של אשכול כדי לקבוע אם ל-Pod יש אפשרות לקבל תעבורת נתונים נכנסת (או Ingress) ברשת, ואם הוא יכול לשלוח תעבורת נתונים יוצאת (או Egress).

מדיניות הרשת מאפשרת להגביל את החיבורים בין אובייקטים של Pod, וכך לצמצם את החשיפה להתקפות.

מדיניות רשת פועלת כחומת אש בשכבה 3 או בשכבה 4 של מודל OSI. הם לא מציעים תכונות נוספות כמו הרשאה או הצפנה.

הגבלת תנועה נכנסת לאובייקטים של Pod

אובייקט NetworkPolicy מאפשר להגדיר מדיניות גישה לרשת עבור Pod. אובייקטים של NetworkPolicy מכילים את המידע הבא:

  • אובייקטים של Pod שהמדיניות חלה עליהם. מגדירים אובייקטים של Pod ועומסי עבודה באמצעות תוויות וסלקטורים.

  • סוג התעבורה שמדיניות רשת ב-Kubernetes משפיעה עליה: תעבורת נתונים נכנסת (ingress) או תעבורת נתונים יוצאת (egress), או שניהם.

  • במדיניות Ingress, אילו אובייקטים של Pod יכולים להתחבר לאובייקטים של Pod שצוינו.

  • במדיניות Egress, אובייקטים של Pod שאליהם אובייקטים ספציפיים של Pod יכולים להתחבר.

דוגמה להגבלה על תנועה נכנסת

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

  1. מריצים אפליקציית שרת אינטרנט עם התווית app=hello וחושפים אותה באופן פנימי באשכול:

    kubectl run hello-web --labels app=hello \
        --image=us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0 \
        --port 8080 --expose
    
  2. מגדירים NetworkPolicy כדי לאפשר תעבורת נתונים אל ה-Pod‏ hello-web רק מהאובייקטים של ה-Pod‏ app=foo. ‫GKE ב-AWS חוסם תנועה נכנסת מאובייקטים של Pod שלא כוללים את התווית הזו, וגם תנועה חיצונית ותנועה מאובייקטים של Pod במרחב שמות אחר.

    במניפסט הבא נבחרו אובייקטים של Pod עם התווית app=hello, וצוינה מדיניות Ingress כדי לאפשר תנועה רק מאובייקטים של Pod עם התווית app=foo:

    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: hello-allow-from-foo
    spec:
      policyTypes:
      - Ingress
      podSelector:
        matchLabels:
          app: hello
      ingress:
      - from:
        - podSelector:
            matchLabels:
              app: foo
  3. החלת המדיניות על האשכול:

    kubectl apply -f hello-allow-from-foo.yaml
    

אימות מדיניות ה-Ingress

  1. מריצים Pod זמני עם התווית app=foo. כדי לוודא שהתנועה הנכנסת מותרת, שולחים בקשה לנקודת הקצה hello-web:8080:

    kubectl run -l app=foo --image=alpine --restart=Never --rm -i -t foo-app \
        -- wget -qO- --timeout=2 http://hello-web:8080
    

    אם התנועה מ-Pod app=foo לאובייקטים של Pod app=hello מופעלת, הפלט נראה כך:

    Hello, world!
    Version: 1.0.0
    Hostname: hello-web-2258067535-vbx6z
    
  2. מריצים Pod זמני עם תווית אחרת (app=other) ומבצעים את אותה בקשה כדי לראות שהתנועה לא מורשית:

    kubectl run -l app=other --image=alpine --restart=Never --rm -i -t other-app \
        -- wget -qO- --timeout=2 http://hello-web:8080
    

    הפלט מאשר שלא מתקבלת תגובה מהחיבור:

    wget: download timed out
    

הגבלת תנועה יוצאת מאובייקטים של Pod

אפשר להגביל את התנועה היוצאת בדיוק כמו את התנועה הנכנסת.

עם זאת, כדי לשלוח שאילתות לשמות מארחים פנימיים כמו hello-web או לשמות מארחים חיצוניים כמו www.example.com, צריך ליצור מדיניות יציאה שמאפשרת תנועת DNS ביציאה 53 באמצעות פרוטוקולי TCP ו-UDP.

כדי להפעיל כללי מדיניות של רשת ליציאת נתונים, צריך לפרוס NetworkPolicy ששולט בתעבורת נתונים יוצאת מאובייקטים של Pod עם התווית app=foo, תוך מתן אפשרות לתעבורת נתונים רק לאובייקטים של Pod עם התווית app=hello, וגם לתעבורת נתונים של DNS.

במניפסט הבא מוגדרת מדיניות NetworkPolicy לשליטה בתעבורת נתונים יוצאת (egress) מאובייקטים של Pod עם התווית app=foo, עם שני יעדים מותרים:

  1. אובייקטים של Pod באותו מרחב שמות עם התווית app=hello
  2. נקודות קצה פנימיות או חיצוניות ביציאה 53 (UDP ו-TCP)
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: foo-allow-to-hello
spec:
  policyTypes:
  - Egress
  podSelector:
    matchLabels:
      app: foo
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: hello
  - ports:
    - port: 53
      protocol: TCP
    - port: 53
      protocol: UDP

החלת המדיניות על האשכול:

kubectl apply -f foo-allow-to-hello.yaml

אימות מדיניות היציאה

  1. פורסים אפליקציית אינטרנט חדשה בשם hello-web-2 וחושפים אותה באופן פנימי באשכול:

    kubectl run hello-web-2 --labels app=hello-2 \
      --image=us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0 --port 8080 --expose
    
  2. מריצים Pod זמני עם התווית app=foo ומוודאים שה-Pod יכול ליצור חיבורים אל hello-web:8080:

    kubectl run -l app=foo --image=alpine --rm -i -t --restart=Never foo-app \
      -- wget -qO- --timeout=2 http://hello-web:8080
    

    ה-Pod מגיב לבקשה:

    Hello, world!
    Version: 1.0.0
    Hostname: hello-web-2258067535-vbx6z
    
  3. מוודאים שאין אפשרות ליצור חיבורים ל-hello-web-2:8080:

    kubectl run -l app=foo --image=alpine --rm -i -t --restart=Never foo-app \
        -- wget -qO- --timeout=2 http://hello-web-2:8080
    

    הפלט מאשר שלא מתקבלת תגובה מהחיבור:

    wget: download timed out
    
  4. מוודאים שאין אפשרות ליצור חיבורים לאתרים חיצוניים כמו www.example.com.

    kubectl run -l app=foo --image=alpine --rm -i -t --restart=Never foo-app \
        -- wget -qO- --timeout=2 http://www.example.com
    

    הפלט מאשר שלא מתקבלת תגובה מהחיבור:

    wget: download timed out
    

הסרת המשאבים

כדי להסיר את המשאבים שיצרתם במדריך הזה, מריצים את הפקודות הבאות:

kubectl delete pods --labels app=hello-2
kubectl delete pods --labels app=hello
kubectl delete -f foo-allow-to-hello.yaml
kubectl delete -f hello-allow-from-foo.yaml

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