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

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

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

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

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

  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, ההערכה נפסקת. אם אין התאמה או פעולה של Pass, התעבורה עוברת לרמה NetworkPolicy.
  2. NetworkPolicy Tier: תעבורת הנתונים נבדקת בהתאם למדיניות הרגילה של מרחב השמות. אם יש התאמה, התעבורה מותרת. אם אין התאמה, התנועה עוברת לרמת הבסיס.
  3. רמת הבסיס: התנועה מוערכת בהתאם לClusterNetworkPolicy כללים ברמת הבסיס. אם יש התאמה ל-Allow או ל-Deny, ההערכה נפסקת. אם אין התאמה, התנועה ממשיכה להתנהגות ברירת המחדל.
  4. התנהגות ברירת המחדל של GKE: אם אין התאמה למדיניות באף רמה, התנועה כפופה להתנהגות של אישור מרומז.

פעולות לגבי פסיקה: אישור, דחייה והעברה

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

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

  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 כברירת מחדל, שמנהלי מרחב השמות יכולים לשנות באמצעות מדיניות רשת ב-Kubernetes.

  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
    

הגבלת תעבורה יוצאת לבלוקים של 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
    

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

כדי לשלוט בסדר ההערכה כשכמה כללי מדיניות חלים על אותם Pods, צריך לציין עדיפות. העדיפויות נעות בין 0 ל-1,000, כאשר מספרים נמוכים יותר מציינים עדיפות גבוהה יותר. אובייקט 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
    

פתרון בעיות

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

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

kubectl get clusternetworkpolicies

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

kubectl describe clusternetworkpolicy/<policy-name>

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

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

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