הגדרה של כללי מדיניות לרשת של אשכול

‫ClusterNetworkPolicy מאפשרת להגדיר מצבי אבטחה גלובליים של GKE בכל האשכול. המסמך הזה מיועד לאדמינים של אשכולות שצריכים לאכוף אמצעי הגנה מחייבים או לקבוע קווי בסיס של אפס אמון.

המשאב הזה מסתמך על היררכיית הערכה קפדנית שפועלת בעדיפות גבוהה יותר ממשאבי NetworkPolicy רגילים בהיקף של מרחב שמות. אפשר להשתמש במשאב ClusterNetworkPolicy כדי להטמיע פעולות מפורשות של דחייה, אישור או העברה. הפעולות האלה מאפשרות להגדיר מדיניות גלובלית של אישור או דחייה, להאציל בקרת תעבורת נתונים למרחבי שמות ספציפיים ולהגביל את תעבורת נתונים יוצאת (egress) לבלוקים של CIDR.

לפני שמתחילים

לפני שמגדירים מדיניות רשת של אשכול, צריך לוודא שעומדים בדרישות הבאות:

  1. מוודאים שאשכול GKE פועל בגרסה 1.36.0-gke.4447000 ואילך.
  2. מוודאים שהאשכול משתמש ב-GKE Dataplane V2.

פרוטוקולים ויציאות נתמכים

כללים של ClusterNetworkPolicy יכולים להתאים לתעבורת נתונים על סמך פרוטוקולי TCP,‏ UDP או SCTP. אפשר לציין יציאות יעד בדרכים הבאות:

  • מספר יציאה ספציפי: משתמשים בהגדרה destinationPort.number כדי לטרגט יציאה בודדת (לדוגמה, 80).
  • טווח יציאות: משתמשים בהגדרה destinationPort.range כדי לטרגט טווח של יציאות (לדוגמה, 8000 עד 9000).
  • יציאה עם שם: משתמשים בהגדרה destinationNamedPort כדי לטרגט שם סמלי שמוגדר במפרט של Pod.

היררכיית הערכת המדיניות

בניגוד ל-NetworkPolicies רגילים, מצטברים, ClusterNetworkPolicy ‏ (CNP) מסתמך על היררכיית הערכה קפדנית שבה הכלל הראשון שתואם זוכה. התנועה זורמת באופן רציף דרך צינור של שלוש שכבות:

  • הרמה: כללי אדמין מופעלים ראשונים, ואז כללי NetworkPolicy, ואז כללי Baseline.
  • עדיפות CNP: בתוך רמה, המערכת מעריכה את המדיניות על סמך העדיפות המספרית המפורשת שלה.
  • סדר הכללים במדיניות CNP: בתוך מדיניות אחת, הכללים מעובדים מלמעלה למטה, כמו ברשימת בקרת גישה (ACL).

תרשים שמציג את היררכיית ההערכה של מדיניות הרשת ב-GKE

התרשים שלמעלה מדגים את תהליך קבלת ההחלטות בהיררכיית ההערכה של CNP:

  1. רמת האדמין: התנועה מוערכת קודם לפי הכללים ClusterNetworkPolicy ברמה Admin. אם יש התאמה ל-Allow או ל-Deny, ההערכה נפסקת. אם אין התאמה או פעולה של כרטיס, התנועה עוברת לרמה NetworkPolicy.
  2. NetworkPolicy Tier: תעבורת הנתונים נבדקת בהתאם למדיניות של מרחב שמות רגיל. אם יש התאמה, התעבורה מותרת. אם אין התאמה, התעבורה עוברת לרמת הבסיס.
  3. מסלול בסיסי: התנועה מוערכת בהשוואה לכללים במסלול הבסיסי.ClusterNetworkPolicy אם יש התאמה של Allow או Deny, ההערכה נפסקת. אם אין התאמה, התנועה ממשיכה להתנהגות ברירת המחדל.
  4. התנהגות ברירת המחדל של GKE: אם אין התאמה למדיניות באף רמה, התנועה כפופה להתנהגות של אישור מרומז.

פעולות לגבי פסיקה: Allow (אישור), Deny (דחייה) ו-Pass (העברה)

כשחבילת נתונים תואמת לכלל, מופעלת אחת משלוש פעולות מחמירות:

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

הגדרת מדיניות דחייה גלובלית

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

  1. שומרים את קובץ המניפסט הבא בשם global-deny.yaml:

    apiVersion: policy.networking.k8s.io/v1alpha2
    kind: ClusterNetworkPolicy
    metadata:
      name: cluster-wide-deny-sensitive
    spec:
      tier: Admin
      priority: 10
      subject:
        namespaces:
          matchLabels:
            kubernetes.io/metadata.name: sensitive-ns
      ingress:
      - action: Deny
        name: deny-all-ingress
        from:
        - namespaces:
            matchLabels: {}
      egress:
      - action: Deny
        name: deny-all-egress
        to:
        - namespaces:
            matchLabels: {}
    
  2. מחילים את המניפסט על האשכול:

    kubectl apply -f global-deny.yaml
    

הגדרת מדיניות הרשאות גלובלית

מדיניות גלובלית של הרשאות יכולה לעזור לוודא שכל ה-Pods יכולים להגיע לשירות ה-DNS של האשכול, ללא קשר למדיניות הרשת שנוצרה על ידי מפתחים.

  1. שומרים את קובץ המניפסט הבא בשם global-allow-dns.yaml:

    apiVersion: policy.networking.k8s.io/v1alpha2
    kind: ClusterNetworkPolicy
    metadata:
      name: allow-kube-dns-admin
    spec:
      tier: Admin
      priority: 20
      subject:
        namespaces: {}
      egress:
      - action: Accept
        name: allow-dns-egress
        to:
        - pods:
            namespaceSelector:
              matchLabels:
                kubernetes.io/metadata.name: kube-system
            podSelector:
              matchLabels:
                k8s-app: kube-dns
        protocols:
        - udp:
            destinationPort:
              number: 53
        - tcp:
            destinationPort:
              number: 53
    
  2. מחילים את המניפסט על האשכול:

    kubectl apply -f global-allow-dns.yaml
    

העברת תנועה למדיניות של מרחב שמות

הקצאת תבניות תנועה ספציפיות לאובייקטים רגילים של NetworkPolicy בהיקף של מרחב שמות.

  1. שומרים את קובץ המניפסט הבא בשם delegate-policy.yaml:

    apiVersion: policy.networking.k8s.io/v1alpha2
    kind: ClusterNetworkPolicy
    metadata:
      name: delegate-to-netpol
    spec:
      tier: Admin
      priority: 30
      subject:
        namespaces: {}
      egress:
      - action: Pass
        name: delegate-web-traffic
        to:
        - namespaces:
            matchLabels:
              app: web-backend
        protocols:
        - tcp:
            destinationPort:
              number: 8080
    
  2. מחילים את המניפסט על האשכול:

    kubectl apply -f delegate-policy.yaml
    
  3. כדי לאפשר את התנועה שהוקצתה במרחב השמות של היעד, שומרים את המניפסט הרגיל NetworkPolicy בתור allow-web-backend.yaml :

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-web-backend
      namespace: backend-ns
    spec:
      podSelector:
        matchLabels:
          app: web-backend
      ingress:
      - from:
        - namespaceSelector:
            matchLabels:
              app: web-frontend
        ports:
        - protocol: TCP
          port: 8080
    
  4. מחילים את המניפסט הרגיל NetworkPolicy על האשכול:

    kubectl apply -f allow-web-backend.yaml
    

הגדרת הגבלות בסיסיות

הגדרת מצב אבטחה שמוגדר כברירת מחדל ב-GKE, שאדמינים של מרחבי שמות יכולים לבטל באמצעות כללי מדיניות רגילים לרשת.

  1. שומרים את קובץ המניפסט הבסיסי הבא בשם baseline-deny.yaml:

    apiVersion: policy.networking.k8s.io/v1alpha2
    kind: ClusterNetworkPolicy
    metadata:
      name: default-deny-baseline
    spec:
      tier: Baseline
      priority: 100
      subject:
        namespaces: {}
      ingress:
      - action: Deny
        name: baseline-deny-all
        from:
        - namespaces: {}
    
  2. מחילים את מניפסט הבסיס על האשכול:

    kubectl apply -f baseline-deny.yaml
    
  3. שומרים את קובץ המניפסט הבא של שינוי ברירת המחדל של המפתח בשם developer-allow.yaml:

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-frontend-access
      namespace: my-app-ns
    spec:
      podSelector:
        matchLabels:
          app: frontend
      ingress:
      - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: ingress-nginx
    
  4. מחילים את מניפסט ההחלפה על האשכול:

    kubectl apply -f developer-allow.yaml
    

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

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

  1. שומרים את מניפסט הפריסה הבא בשם app-deployment.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-webapp
    spec:
      template:
        spec:
          containers:
          - name: web-container
            image: nginx
            ports:
            - name: http-web
              containerPort: 8080
    
  2. מחילים את מניפסט הפריסה על האשכול:

    kubectl apply -f app-deployment.yaml
    
  3. שומרים את מניפסט המדיניות הבא בשם named-port-policy.yaml:

    apiVersion: policy.networking.k8s.io/v1alpha2
    kind: ClusterNetworkPolicy
    metadata:
      name: allow-web-named-port
    spec:
      tier: Admin
      priority: 40
      subject:
        namespaces: {}
      egress:
      - action: Accept
        to:
        - namespaces:
            matchLabels:
              app: my-webapp
        protocols:
        - tcp:
            destinationNamedPort: http-web
    
  4. מחילים את מניפסט המדיניות על האשכול:

    kubectl apply -f named-port-policy.yaml
    

הגבלת תעבורת נתונים יוצאת (egress) לחסימות CIDR

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

  1. שומרים את קובץ המניפסט הבא בשם cidr-policy.yaml:

    apiVersion: policy.networking.k8s.io/v1alpha2
    kind: ClusterNetworkPolicy
    metadata:
      name: allow-egress-to-intranet
    spec:
      tier: Admin
      priority: 60
      subject:
        namespaces: {}
      egress:
      - action: Accept
        name: allow-intranet
        to:
        - networks:
          - 10.0.0.0/8
          - 192.168.0.0/16
    
  2. מחילים את המניפסט על האשכול:

    kubectl apply -f cidr-policy.yaml
    

הגדרת הקדימות של העדיפות

כדי לשלוט בסדר ההערכה כשכמה כללי מדיניות חלים על אותם פודים, צריך לציין עדיפות. העדיפויות נעות בין 0 ל-1000, כאשר מספרים נמוכים יותר מציינים עדיפות גבוהה יותר. אובייקט ClusterNetworkPolicy יחיד יכול להכיל עד 100 כללים לתעבורת נתונים נכנסת ו-100 כללים לתעבורת נתונים יוצאת.

  1. שומרים את קובץ המניפסט הבא בשם priority-policies.yaml:

    apiVersion: policy.networking.k8s.io/v1alpha2
    kind: ClusterNetworkPolicy
    metadata:
      name: deny-beta
    spec:
      tier: Admin
      priority: 10
      subject:
        namespaces:
          matchLabels:
            team: alpha
      ingress:
      - action: Accept
        name: allow-beta-monitoring
        from:
        - pods:
            namespaceSelector:
              matchLabels:
                team: beta
            podSelector:
              matchLabels:
                app: monitoring
      - action: Deny
        name: deny-all-other-ingress-from-beta
        from:
        - namespaces:
            matchLabels:
              team: beta
    ---
    apiVersion: policy.networking.k8s.io/v1alpha2
    kind: ClusterNetworkPolicy
    metadata:
      name: allow-beta
    spec:
      tier: Admin
      priority: 50
      subject:
        namespaces:
          matchLabels:
            team: alpha
      ingress:
      - action: Accept
        name: allow-all-ingress-from-beta
        from:
        - namespaces:
            matchLabels:
              team: beta
    
  2. מחילים את המניפסט על האשכול:

    kubectl apply -f priority-policies.yaml
    

פתרון בעיות

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

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

kubectl get clusternetworkpolicies

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

kubectl describe clusternetworkpolicy/<policy-name>

השדה status.conditions בפלט מספק מידע על כך שהמדיניות תואמת להטמעה של הרשת באשכול.

כדי לעקוב אחרי תנועת הנתונים והחלטות המדיניות, אפשר להשתמש ב-GKE Dataplane V2 Observability.

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