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

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

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

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

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

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

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

  • סוג התנועה שהמדיניות משפיעה עליה: תנועה נכנסת (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 on 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.

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

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