אבטחת עומסי עבודה באמצעות ClusterNetworkPolicy ב-GKE – דוגמה להסקת AI‏ (Gemma, ‏ TPU)

1. סקירה כללית

בשיעור ה-Lab הזה נכיר את ClusterNetworkPolicy ב-Google Kubernetes Engine ‏ (GKE). אפשר להחיל את ClusterNetworkPolicy על תרחישים שונים לדוגמה, וגם על כל האשכול, ולאכוף אותה ברמות Admin ו-Baseline. בדוגמה הזו נדגים את הבקרה באמצעות פריסת LLM‏ (Gemma) ב-GKE עם TPU, ‏ vLLM ואימות.

תעבדו עם הטכנולוגיות הבאות:

  • ‫Google Kubernetes Engine ‏ (GKE) – פלטפורמת הבסיס לתזמור קונטיינרים, שמארחת עומסי עבודה פרטיים וניתנים להתאמה.
  • ‫ClusterNetworkPolicy (CNP) – כללי מדיניות רשת ב-Kubernetes בכמה רמות בהיקף של אשכול, שמאפשרים להגדיר אמצעי הגנה של SecOps ברמות Admin, ‏ NetworkPolicy ו-Baseline.
  • ‫vLLM TPU Inference Engine – מנוע להסקת מסקנות עם תפוקה גבוהה שמריץ את המודל הקל Gemma 4‏ (google/gemma-4-E2B-it) ב-Google TPU עם נקודות קצה (endpoints) של REST שתואמות ל-OpenAI.

תפקידים ופרסונות

‫Network Policy API בנוי סביב פרסונות ארגוניות ספציפיות:

  • שימוש באדמין של אשכול (ClusterNetworkPolicy): אכיפת אמצעי אבטחה באשכולות ברמות אדמין וברמות בסיסיות.
  • שימוש באדמין של מרחב שמות (NetworkPolicy): ניהול הגבולות והבידוד ברמת הדייר במרחבי שמות ספציפיים.
  • שימוש על ידי מפתחי אפליקציות (NetworkPolicy): הגדרת כללים מפורטים למיקרו-שירותים (microservices) ספציפיים לאפליקציה.

כדי להגדיר את הסביבה הזו, תפרסו VPC פרטי בהתאמה אישית, Cloud NAT ואשכול GKE פרטי עם מאגר צמתים ייעודי של TPU.

כדי לאבטח את האשכול, תיצרו משאבים מסוג ClusterNetworkPolicy בכמה רמות לצד אובייקטים רגילים מסוג NetworkPolicy, כדי לאכוף אמצעי הגנה קפדניים ברשת. לאחר מכן תפרסו עומס עבודה של AI שמשתמש ב-vLLM וב-Google Cloud TPU כדי להציג את המודל Gemma 4.

לבסוף, תגדירו בסיס עבודה, תפעילו את כללי מדיניות האבטחה ותגדירו את NetworkLogging באמצעות Cloud Logging וסטרימינג בזמן אמת של Hubble eBPF observability כדי לבדוק את ההחלטות לגבי המדיניות ולאמת את חבילות הנתונים שנמחקו. כל ההגדרות ישתמשו בשילוב של Terraform, gcloud ו-kubectl.

בשיעור ה-Lab הזה תלמדו איך לבצע את המשימה הבאה:

  • הקצאת רשת פרטית, אשכול GKE ומאיצי Cloud TPU v5e באמצעות Terraform.
  • מגדירים את GKE NetworkLogging כדי לתעד את נתוני הטלמטריה של החיבור.
  • פריסת Gemma 4 E2B ב-TPU באמצעות קובץ אימג' של קונטיינר vllm/vllm-tpu הרשמי.
  • לפני שמחילים הגבלות, צריך להגדיר קו בסיס תקין שמוכיח קישוריות מקצה לקצה.
  • מחילים Baseline-tier ClusterNetworkPolicy כדי לדחות כברירת מחדל תנועה לא מורשית בין מרחבי שמות.
  • להחיל מדיניות NetworkPolicy שמנוהלת על ידי המפתח כדי להעביר את הגישה ללקוחות מורשים.
  • מחילים מדיניות ClusterNetworkPolicy של Admin-tier כדי לאכוף כללי הגנה גלובליים לתעבורת נתונים יוצאת, שמבטלים את הגדרות המפתחים.
  • אימות של חבילות נתונים שהועברו או נמחקו בזמן אמת (באמצעות סטרימינג של Hubble eBPF ו-Cloud Logging).

בשיעור ה-Lab הזה תיצרו את התבנית הבאה.

איור 1. dbe5e5f7b35afb8e.jpeg

2. הגדרת שירותי Google Cloud

הגדרת סביבה בקצב אישי

  1. נכנסים למסוף Google Cloud ויוצרים פרויקט חדש או משתמשים בפרויקט קיים. אם עדיין אין לכם חשבון Gmail או Google Workspace, אתם צריכים ליצור חשבון.

295004821bab6a87.png37d264871000675d.png96d86d3d5655cdbe.png

  • שם הפרויקט הוא השם המוצג למשתתפים בפרויקט הזה. זו מחרוזת תווים שלא משמשת את Google APIs. תמיד אפשר לעדכן אותו.
  • מזהה הפרויקט הוא ייחודי לכל הפרויקטים ב-Google Cloud, ואי אפשר לשנות אותו אחרי שהוא הוגדר. מסוף Cloud יוצר באופן אוטומטי מחרוזת ייחודית, שבדרך כלל לא משנה מה היא. ברוב ה-Codelabs תצטרכו להפנות למזהה הפרויקט (בדרך כלל מזוהה בתור PROJECT_ID). אם אתם לא אוהבים את המזהה שנוצר, אתם יכולים ליצור מזהה אקראי אחר. לחלופין, אתם יכולים לנסות להזין שם משלכם ולבדוק אם הוא זמין. אי אפשר לשנות אותו אחרי השלב הזה, והוא נשאר לאורך כל הפרויקט.
  • לידיעתכם, יש ערך שלישי, מספר פרויקט, שמשמש בחלק מממשקי ה-API. מידע נוסף על שלושת הערכים האלה זמין במאמרי העזרה.
  1. בשלב הבא, צריך להפעיל את החיוב במסוף Cloud כדי להשתמש במשאבים או בממשקי ה-API של Cloud. השימוש ב-Codelab הזה לא יעלה הרבה, אם בכלל. כדי להשבית את המשאבים ולהימנע מחיובים נוספים, אתם יכולים למחוק את המשאבים שיצרתם או למחוק את הפרויקט. משתמשים חדשים ב-Google Cloud זכאים לתקופת ניסיון בחינם בשווי 300$‎.

הפעלת Cloud Shell

אפשר להפעיל את Google Cloud מרחוק מהמחשב הנייד, אבל ב-Codelab הזה תשתמשו ב-Google Cloud Shell, סביבה של שורת פקודה שפועלת בענן.

במסוף Google Cloud, לוחצים על הסמל של Cloud Shell בסרגל הכלים שבפינה הימנית העליונה:

הפעלת Cloud Shell

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

צילום מסך של מסוף Google Cloud Shell שמראה שהסביבה מחוברת

המכונה הווירטואלית הזו נטענת עם כל הכלים למפתחים שתצטרכו. יש בה ספריית בית בנפח מתמיד של 5GB והיא פועלת ב-Google Cloud, מה שמשפר מאוד את ביצועי הרשת והאימות. את כל העבודה ב-Codelab הזה אפשר לעשות בדפדפן. לא צריך להתקין שום דבר.

3. הגדרת סביבה באמצעות Terraform

כדי להשלים את ה-Lab,

  • צריכה להיות לכם גישה למכסת TPU v5e באזור ובתחום שבחרתם, למשל (us-central1-a, us-west4-a, us-south1-a, us-west1-c, europe-west4-b). כדי לקבל גישה, צריך לפעול לפי ההוראות במסמך של תוכנית TPU ולהפעיל את מכסת TPU.
  • זהו פריסה קטנה שדורשת 4 שבבי TPU v5e (ct5lp-hightpu-4t),) שייצרו פרוסה בגודל 2x2 באזור אחד.

כדי להשתמש ב-Hugging Face

  • טוקן של Hugging Face: צריך טוקן גישה כדי להוריד את משקלי המודל של Gemma.
  • מאשרים את הסכם השימוש, אם נדרש.

ניצור VPC בהתאמה אישית עם כללים של חומת אש, רשת משנה ואשכול במצב Autopilot. פותחים את מסוף Cloud ובוחרים את הפרויקט שבו רוצים להשתמש.

  1. פותחים את Cloud Shell בחלק העליון של המסוף בצד שמאל, מוודאים שמופיע מזהה הפרויקט הנכון ב-Cloud Shell ומאשרים את כל ההנחיות כדי לאפשר גישה. b51b80043d3bac90.png
  2. יוצרים ספרייה בשם gke-cnp-lab, ועוברים אליה.
mkdir -p gke-cnp-lab && cd gke-cnp-lab
  1. עכשיו יוצרים כמה משתנים. הערה: עורכים את REGION ואת ZONE כדי לשקף את המיקום בפועל שבו יש לכם גישה למשאבי ה-TPU. ברירת המחדל שמשמשת באזור us-west4 ובאזור us-west4-a של ה-Lab
export PROJECT_ID=$(gcloud config get-value project)
export REGION="us-west4"
export ZONE="us-west4-a"
export NETWORK="cnp-demo-vpc"
export SUBNET="cnp-main-subnet"
export CLUSTER_NAME="cnp-demo-cluster"
  1. שומרים את משתני ההגדרות בסקריפט מסייע בספרייה gke-cnp-lab. אם הסשן של Cloud Shell מתנתק או מתאפס, אפשר לשחזר במהירות את המשתנים הפעילים על ידי הפעלת source ./env.sh
cat << EOF > env.sh
export PROJECT_ID="${PROJECT_ID}"
export REGION="${REGION}"
export ZONE="${ZONE}"
export NETWORK="${NETWORK}"
export SUBNET="${SUBNET}"
export CLUSTER_NAME="${CLUSTER_NAME}"

echo -e "\n=== Validating Environment Configuration ==="
echo "Project ID   : \${PROJECT_ID}"
echo "Region       : \${REGION}"
echo "Zone         : \${ZONE}"
echo "Network Name : \${NETWORK}"
echo "Subnet Name  : \${SUBNET}"
echo "Cluster Name : \${CLUSTER_NAME}"

if [[ -z "\${PROJECT_ID}" || -z "\${REGION}" || -z "\${ZONE}" || -z "\${NETWORK}" || -z "\${SUBNET}" || -z "\${CLUSTER_NAME}" ]]; then
  echo -e "\n[ERROR] One or more environment variables are missing! Check your configuration."
else
  echo -e "\n[SUCCESS] Environment variables successfully populated and validated."
fi
EOF

chmod +x env.sh
source ./env.sh
  1. עכשיו צריך להוסיף כמה קובצי תצורה. הפקודות האלה ייצרו את הקבצים הבאים: terraform.tfvars , ‏ variables.tf, ‏ main.tf בספרייה gke-cnp-lab.
cat << EOF > terraform.tfvars
project_id   = "${PROJECT_ID}"
region       = "${REGION}"
zone         = "${ZONE}"
network_name = "${NETWORK}"
subnet_name  = "${SUBNET}"
cluster_name = "${CLUSTER_NAME}"
EOF

cat << 'EOF' > variables.tf
variable "project_id" {
  type        = string
  description = "Google Cloud Project ID"
}

variable "region" {
  type        = string
  description = "Target GCP region"
}

variable "zone" {
  type        = string
  description = "Target GCP zone"
}

variable "network_name" {
  type        = string
  description = "VPC network name"
}

variable "subnet_name" {
  type        = string
  description = "Subnetwork name"
}

variable "cluster_name" {
  type        = string
  description = "GKE cluster name"
}
EOF

cat << 'EOF' > main.tf
terraform {
  required_version = ">= 1.5.0"
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 7.32.0"
    }
    google-beta = {
      source  = "hashicorp/google-beta"
      version = "~> 7.32.0"
    }
  }
}

provider "google" {
  project = var.project_id
  region  = var.region
}

provider "google-beta" {
  project = var.project_id
  region  = var.region
}

# 1. Custom Private VPC Network
resource "google_compute_network" "vpc" {
  name                    = var.network_name
  auto_create_subnetworks = false
  mtu                     = 8896
}

# 2. Private Subnet with Secondary IP Ranges for Pods & Services
resource "google_compute_subnetwork" "subnet" {
  name                     = var.subnet_name
  ip_cidr_range            = "10.10.0.0/20"
  region                   = var.region
  network                  = google_compute_network.vpc.id
  private_ip_google_access = true

  secondary_ip_range {
    range_name    = "gke-pods"
    ip_cidr_range = "10.20.0.0/16"
  }
  secondary_ip_range {
    range_name    = "gke-services"
    ip_cidr_range = "10.30.0.0/20"
  }
}

# 3. Cloud Router & Cloud NAT for Secure Outbound Egress
resource "google_compute_router" "router" {
  name    = "${var.network_name}-router"
  network = google_compute_network.vpc.id
  region  = var.region
}

resource "google_compute_router_nat" "nat" {
  name                               = "${var.network_name}-nat"
  router                             = google_compute_router.router.name
  region                             = var.region
  nat_ip_allocate_option             = "AUTO_ONLY"
  source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES"
}

# 4. Internal Firewall Rules
resource "google_compute_firewall" "allow_internal" {
  name      = "${var.network_name}-allow-internal"
  network   = google_compute_network.vpc.id
  direction = "INGRESS"
  priority  = 1000
  allow {
    protocol = "all"
  }
  source_ranges = ["10.10.0.0/20", "10.20.0.0/16", "10.30.0.0/20"]
}

# 5. Private GKE Cluster with Observability and Dataplane V2
resource "google_container_cluster" "primary" {
  name               = var.cluster_name
  location           = var.region
  node_locations     = [var.zone]
  network            = google_compute_network.vpc.id
  subnetwork         = google_compute_subnetwork.subnet.id
  initial_node_count = 1

  datapath_provider = "ADVANCED_DATAPATH"

  # FIX: Observability config must be nested inside monitoring_config
  monitoring_config {
    advanced_datapath_observability_config {
      enable_metrics = true
      enable_relay   = true
    }
  }

  release_channel {
    channel = "RAPID"
  }

  ip_allocation_policy {
    cluster_secondary_range_name  = "gke-pods"
    services_secondary_range_name = "gke-services"
  }

  private_cluster_config {
    enable_private_nodes    = true
    enable_private_endpoint = false
    master_ipv4_cidr_block  = "172.16.0.0/28"
  }

  node_config {
    machine_type = "e2-standard-4"
    oauth_scopes = ["https://www.googleapis.com/auth/cloud-platform"]
  }

  deletion_protection = false
}

# 6. Dedicated Cloud TPU v5e Node Pool (ct5lp-hightpu-4t / 2x2 Topology)
resource "google_container_node_pool" "tpu_pool" {
  provider       = google-beta
  name           = "tpu-v5e-pool"
  location       = var.region
  node_locations = [var.zone]
  cluster        = google_container_cluster.primary.name
  node_count     = 1

  node_config {
    machine_type = "ct5lp-hightpu-4t"
    oauth_scopes = ["https://www.googleapis.com/auth/cloud-platform"]

    labels = {
      "cloud.google.com/gke-tpu-accelerator" = "tpu-v5-lite-podslice"
      "cloud.google.com/gke-tpu-topology"    = "2x2"
    }

    taint {
      key    = "google.com/tpu"
      value  = "present"
      effect = "NO_SCHEDULE"
    }
  }
}
EOF
  1. מוודאים שנמצאים בספרייה gke-cnp-lab ומריצים את הפקודות הבאות
    terraform init כדי להפעיל את ספריית העבודה. זה השלב הראשון, שבו מורידים את הספקים שנדרשים להגדרות האישיות שצוינו.הפקודה
    terraform plan -out יוצרת תוכנית ביצוע שמראה אילו פעולות Terraform תבצע כדי לפרוס את התשתית. הפקודה -out מאפשרת לשמור את תוכנית הביצוע בקובץ בינארי עם שם. אתם יכולים לראות מה יקרה בלי לבצע שינויים.
    terraform apply מריץ את העדכונים.
terraform init 
terraform plan -out cnpgke 
  1. מפעילים את תוכנית הביצוע. מכיוון שאתם מחילים את תוכנית ההרצה השמורה, היא תפעל באופן מיידי בלי לבקש אישור (התהליך עשוי להימשך בין 6 ל-10 דקות).
terraform apply cnpgke
  1. אימות פריסת התשתית:
gcloud container clusters get-credentials ${CLUSTER_NAME} --region ${REGION} --project=${PROJECT_ID}
echo -e "\n=== Verifying Cluster Nodes ==="
kubectl get nodes -L cloud.google.com/gke-tpu-accelerator,cloud.google.com/gke-tpu-topology

8b187e355548b7c5.png

4. הגדרת רישום ביומן הרשת

לפני שפורסים עומסי עבודה וכללי מדיניות, מגדירים את GKE Network Logging כדי לתעד את הטלמטריה של החיבורים ולבצע ביקורת על החלטות לגבי מדיניות ב-Cloud Logging.

  1. בספרייה gke-cnp-lab, יוצרים את מניפסט ההגדרות של NetworkLogging
cat << 'EOF' > 00-network-logging.yaml
apiVersion: networking.gke.io/v1alpha1
kind: NetworkLogging
metadata:
  name: default
spec:
  cluster:
    allow:
      delegate: false
      log: true
    deny:
      delegate: false
      log: true
EOF
  1. החלת ההגדרות על האשכול
kubectl apply -f 00-network-logging.yaml
kubectl get networklogging default

הערה: יכול להיות שתופיע אזהרה שהמשאב חסר ב-kubectl.kubernetes.io/last-applied-configuration annotation.. זה תקין וצפוי. ‫GKE יוצר מראש אובייקט NetworkLogging כברירת מחדל כשהאשכול מופעל, והפקודה kubectl apply פשוט משתלטת על הניהול שלו כדי להחיל את הכללים החדשים.

5. פריסת בדיקות של עומס העבודה והלקוח ב-Gemma 4

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

  • ‫gemma-llm: מכיל את עומס העבודה העיקרי של הסקת המסקנות של Gemma 4‏ (tier: ai-core).
  • ‫client-ns: מכיל את אפליקציית הלקוח המורשית לצ'אט RAG‏ (tier: app-frontend).
  • ‫untrusted-tenant: מכיל קונטיינר בדיקה לא מורשה (tier: untrusted).
  1. ב-gke-cnp-lab directory,, יוצרים את המניפסט 01-namespaces-clients.yaml שמכיל את מרחבי השמות ואת ה-pods של לקוח הבדיקה:
cat << 'EOF' > 01-namespaces-clients.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: gemma-llm
  labels:
    tier: ai-core
---
apiVersion: v1
kind: Namespace
metadata:
  name: client-ns
  labels:
    tier: app-frontend
---
apiVersion: v1
kind: Namespace
metadata:
  name: untrusted-tenant
  labels:
    tier: untrusted
---
# Authorized Client Pod
apiVersion: apps/v1
kind: Deployment
metadata:
  name: rag-agent-client
  namespace: client-ns
  labels:
    app: rag-agent
spec:
  replicas: 1
  selector:
    matchLabels:
      app: rag-agent
  template:
    metadata:
      labels:
        app: rag-agent
    spec:
      containers:
        - name: client
          image: curlimages/curl:latest
          command: ["/bin/sh", "-c", "sleep 86400"]
---
# Rogue / Untrusted Probe Pod
apiVersion: apps/v1
kind: Deployment
metadata:
  name: rogue-client
  namespace: untrusted-tenant
  labels:
    app: rogue-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: rogue-app
  template:
    metadata:
      labels:
        app: rogue-app
    spec:
      containers:
        - name: probe
          image: curlimages/curl:latest
          command: ["/bin/sh", "-c", "sleep 86400"]
EOF
  • מחילים את מרחבי השמות ואת פריסות הלקוח:
kubectl apply -f 01-namespaces-clients.yaml
kubectl get namespaces gemma-llm client-ns untrusted-tenant --show-labels

פריסת עומס עבודה (workload) של vLLM ו-Gemma

יוצרים את הסוד של Hugging Face. מחליפים את YOUR_ACTUAL_HUGGING_FACE_TOKEN באסימון:

export HF_TOKEN="YOUR_ACTUAL_HUGGING_FACE_TOKEN"
echo $HF_TOKEN
kubectl create secret generic hf-secret -n gemma-llm --from-literal=hf_token=${HF_TOKEN}
  1. יוצרים את המניפסט של עומס העבודה להסקת מסקנות של Gemma 4 שמטרגט את Cloud TPU v5e באמצעות vllm-tpu:
cat << 'EOF' > 02-gemma4-tpu-vllm.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gemma-serving
  namespace: gemma-llm
  labels:
    app: gemma-service
spec:
  replicas: 1
  selector:
    matchLabels:
      app: gemma-service
  template:
    metadata:
      labels:
        app: gemma-service
        ai.gke.io/model: gemma4
        ai.gke.io/inference-server: vllm-tpu
    spec:
      tolerations:
        - key: "google.com/tpu"
          operator: "Exists"
          effect: "NoSchedule"
      nodeSelector:
        cloud.google.com/gke-tpu-accelerator: tpu-v5-lite-podslice
        cloud.google.com/gke-tpu-topology: 2x2
      containers:
        - name: vllm-inference
          image: vllm/vllm-tpu:latest
          command: ["python3", "-m", "vllm.entrypoints.openai.api_server"]
          args:
            - "--model=google/gemma-4-E2B-it"
            - "--tensor-parallel-size=4"
            - "--host=0.0.0.0"
            - "--port=8000"
            - "--max-model-len=4096"
            - "--max-num-batched-tokens=4096"
          env:
            - name: HF_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_token
            - name: HUGGING_FACE_HUB_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_token
          volumeMounts:
            - mountPath: /dev/shm
              name: dshm
          ports:
            - name: http-inference
              containerPort: 8000
          resources:
            requests:
              google.com/tpu: "4"
              memory: "32Gi"
              cpu: "8"
            limits:
              google.com/tpu: "4"
              memory: "32Gi"
              cpu: "8"
          startupProbe:
            httpGet:
              path: /health
              port: 8000
            failureThreshold: 120
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /health
              port: 8000
            periodSeconds: 5
      volumes:
        - name: dshm
          emptyDir:
            medium: Memory
---
apiVersion: v1
kind: Service
metadata:
  name: gemma-service
  namespace: gemma-llm
spec:
  type: ClusterIP
  selector:
    app: gemma-service
  ports:
    - name: http
      protocol: TCP
      port: 8000
      targetPort: 8000
EOF
  1. יוצרים את הפריסה.
kubectl apply -f 02-gemma4-tpu-vllm.yaml
  1. כדי לעקוב אחרי סטטוס ההשלמה, מריצים את הסקריפט הבא. ה-pods ימתינו עד להקצאת הצומת לפני שיוכלו להמשיך, וזה עשוי להימשך יותר מ-13 דקות.
echo "       __|__"
echo "  --@--(_|_)--@--"
echo ""
echo "Waiting for Gemma 4 TPU Pod to initialize and become Ready..."

# 1. Wait for the pod to be scheduled and reach the Running state
kubectl wait -n gemma-llm --for=condition=Ready pod -l app=gemma-service --timeout=600s

echo ""
echo "✅ Pod is Running! Streaming vLLM engine initialization logs..."

# 2. Stream logs until Uvicorn/vLLM is ready to serve
kubectl logs -n gemma-llm -l app=gemma-service -c vllm-inference -f | sed -u '/Application startup complete/q'

echo ""
echo "🚀 Gemma 4 on TPU v5e is ready for inference!"

6. הסבר על הערכת המדיניות ועל מצב ברירת המחדל

לפני שמחילים מדיניות רשת ב-Kubernetes, חשוב להבין איך ClusterNetworkPolicy של GKE ו-NetworkPolicy הרגיל של Kubernetes פועלים יחד ברמות הערכה שונות.

התנועה ב-GKE נבדקת באמצעות מודל קדימויות בכמה רמות:

Admin Tier ⟶ NetworkPolicy Tier ⟶ Baseline Tier ⟶ Default GKE Behavior

d4cf83398c69b6b8.png

תהליך הבדיקה שלנו

===================================================
           4-STAGE POLICY EVALUATION FLOW
===================================================

[Stage 1: Default State]
 ├── Pre-Policy State: Default Kubernetes allow-all
 ├── Ingress: client-ns  ──▶ Gemma 4: ALLOWED (200 OK)
 ├── Ingress: untrusted  ──▶ Gemma 4: ALLOWED (200 OK)
 ├── Egress:  All Pods   ──▶ Metadata: ALLOWED (Exposed)
 └── Security Posture: ⚠️ Overly permissive
      │
      ▼
[Stage 2: Baseline Lockdown]
 ├── Policy: ClusterNetworkPolicy (tier: Baseline)
 ├── Rule: Default-deny all cross-namespace ingress
 ├── Ingress: client-ns  ──▶ Gemma 4: DROPPED (Timeout)
 ├── Ingress: untrusted  ──▶ Gemma 4: DROPPED (Timeout)
 └── Security Posture: 🛑 Zero-trust baseline active
      │
      ▼
[Stage 3: Developer Delegation]
 ├── Policy: NetworkPolicy (tier: NetworkPolicy)
 ├── Rule: App team allows ingress from client-ns
 ├── Ingress: client-ns  ──▶ Gemma 4: ALLOWED (200 OK)
 ├── Ingress: untrusted  ──▶ Gemma 4: DROPPED (Timeout)
 └── Security Posture: 🔀 App isolation achieved
      │
      ▼
[Stage 4: Admin Guardrail]
 ├── Policy: ClusterNetworkPolicy (tier: Admin)
 ├── Rule: Cluster-wide metadata drop (169.254.169.254)
 ├── Egress:  All Pods   ──▶ Metadata: DROPPED (Timeout)
 ├── Dev NetPol bypass attempt:   OVERRIDDEN (Blocked)
 └── Security Posture: 🔒 Enforced guardrail
===================================================

הגדרת בסיס (בדיקה לפני המדיניות)

מוודאים שהמודל Gemma 4 תקין ומשרת בקשות להסקת מסקנות. ב-Kubernetes רגיל בלי כללי מדיניות, כל תעבורת הנתונים בין מרחבי שמות מותרת באופן משתמע.

  1. בודקים את ההסקה מהלקוח המורשה ב-client-ns:
kubectl exec -n client-ns deploy/rag-agent-client -- curl --connect-timeout 3 -s -X POST \
  http://gemma-service.gemma-llm.svc.cluster.local:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemma-4-E2B-it",
    "messages": [{"role": "user", "content": "Explain zero trust in one short sentence."}],
    "max_tokens": 40
  }' | jq -r '.choices[0].message.content'
  1. בדיקת ההסקה מהלקוח הלא מורשה ב-untrusted-tenant:
kubectl exec -n untrusted-tenant deploy/rogue-client -- curl --connect-timeout 3 -s -X POST \
  http://gemma-service.gemma-llm.svc.cluster.local:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemma-4-E2B-it",
    "messages": [{"role": "user", "content": "Explain zero trust in one short sentence."}],
    "max_tokens": 40
  }' | jq -r '.choices[0].message.content'
  1. בודקים אם Pods בכל שלושת מרחבי השמות יכולים להגיע לשרת המטא-נתונים (169.254.169.254):
echo -e "\n[1/3] Testing Metadata access from Gemma serving pod (gemma-llm)..."
kubectl exec -n gemma-llm deploy/gemma-serving -- curl --connect-timeout 3 -s -w "\nHTTP Code: %{http_code}\n" -H "Metadata-Flavor: Google" \
  http://169.254.169.254/computeMetadata/v1/instance/zone || echo "🛑 RESULT: Connection Timed Out (Blocked)"

echo -e "\n[2/3] Testing Metadata access from authorized client (client-ns)..."
kubectl exec -n client-ns deploy/rag-agent-client -- curl --connect-timeout 3 -s -w "\nHTTP Code: %{http_code}\n" -H "Metadata-Flavor: Google" \
  http://169.254.169.254/computeMetadata/v1/instance/zone || echo "🛑 RESULT: Connection Timed Out (Blocked)"

echo -e "\n[3/3] Testing Metadata access from rogue client (untrusted-tenant)..."
kubectl exec -n untrusted-tenant deploy/rogue-client -- curl --connect-timeout 3 -s -w "\nHTTP Code: %{http_code}\n" -H "Metadata-Flavor: Google" \
  http://169.254.169.254/computeMetadata/v1/instance/zone || echo "🛑 RESULT: Connection Timed Out (Blocked)"

7. בדיקת הערכה של Baseline ו-Network Policy Tier

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

הגדרת גישה למודל האבטחה של אפס אמון (רמת בסיס)

  1. יוצרים את מניפסט המדיניות של 03-baseline-deny.yaml Baseline-tier:
cat << 'EOF' > 03-baseline-deny.yaml
apiVersion: policy.networking.k8s.io/v1alpha2
kind: ClusterNetworkPolicy
metadata:
  name: baseline-default-deny
spec:
  tier: Baseline
  priority: 1000
  subject:
    namespaces: {}
  ingress:
    # 1. Allow CoreDNS Ingress cluster-wide so DNS resolution never breaks
    - name: allow-dns-ingress
      action: Accept
      from:
        - namespaces: {}
      protocols:
        - udp:
            destinationPort:
              number: 53
        - tcp:
            destinationPort:
              number: 53
    # 2. Default Deny all other cross-namespace ingress
    - name: baseline-deny-cross-ns
      action: Deny
      from:
        - namespaces: {}
EOF
  1. מחילים את המדיניות של רמת הבסיס:
kubectl apply -f 03-baseline-deny.yaml
  1. בדיקת הקישוריות של הלקוח מ-client-ns.
kubectl exec -n client-ns deploy/rag-agent-client -- curl --connect-timeout 3 -s -X POST \
  http://gemma-service.gemma-llm.svc.cluster.local:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemma-4-E2B-it",
    "messages": [{"role": "user", "content": "Explain zero trust in one short sentence."}],
    "max_tokens": 40
  }' | jq -r '.choices[0].message.content'
  1. בודקים את ההסקה מהלקוח הלא מורשה והזדוני בדייר הלא מהימן:
kubectl exec -n untrusted-tenant deploy/rogue-client -- curl --connect-timeout 3 -s -X POST \
  http://gemma-service.gemma-llm.svc.cluster.local:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemma-4-E2B-it",
    "messages": [{"role": "user", "content": "Explain zero trust in one short sentence."}],
    "max_tokens": 40
  }' | jq -r '.choices[0].message.content'

הענקת גישה למפתחים (רמת NetworkPolicy)

עכשיו צוות האפליקציה gemma-llm יחיל NetworkPolicy רגיל ברמת מרחב השמות כדי לאשר תנועה מורשית מ-client-ns.

  1. יוצרים את המניפסט NetworkPolicy של המפתח 04-app-networkpolicy.yaml:
cat << 'EOF' > 04-app-networkpolicy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-rag-client
  namespace: gemma-llm
spec:
  podSelector:
    matchLabels:
      app: gemma-service
  policyTypes:
    - Ingress
  ingress:
    # Explicitly permit ingress only from pods matching app: rag-agent in client-ns
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: client-ns
          podSelector:
            matchLabels:
              app: rag-agent
      ports:
        - protocol: TCP
          port: 8000
EOF
  1. מחילים את המדיניות:
kubectl apply -f 04-app-networkpolicy.yaml
  1. בדיקת הקישוריות של הלקוח מ-client-ns
kubectl exec -n client-ns deploy/rag-agent-client -- curl --connect-timeout 3 -s -X POST \
  http://gemma-service.gemma-llm.svc.cluster.local:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemma-4-E2B-it",
    "messages": [{"role": "user", "content": "Explain zero trust in one short sentence."}],
    "max_tokens": 40
  }' | jq -r '.choices[0].message.content'
  1. בודקים את הקישוריות מהלקוח הזדוני ב-untrusted-tenant:
kubectl exec -n untrusted-tenant deploy/rogue-client -- curl --connect-timeout 3 -s -X POST \
  http://gemma-service.gemma-llm.svc.cluster.local:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemma-4-E2B-it",
    "messages": [{"role": "user", "content": "Explain zero trust in one short sentence."}],
    "max_tokens": 40
  }' | jq -r '.choices[0].message.content'

8. הערכה של אכיפת שכבות הגנה גלובליות (רמת אדמין)

בתור מנהלי האשכול,תאכפו עכשיו מדיניות ברמת האדמין (ClusterNetworkPolicy) בראש סדר ההערכה של GKE. הרמה הזו נבדקת ראשונה, וכל כלל תואם מקבל עדיפות מיידית על פני כל הרמות האחרות. אם אין התאמה, החבילה מועברת להערכה על ידי השכבות הנמוכות יותר (NetworkPolicy ו-Baseline).

בשלב הזה, תפעילו מדיניות ש:

  • ‫Cluster-wide Egress Guardrail: חוסם את כל הפודים בכל מרחב שמות מלהגיע לשרת המטא-נתונים של Google Cloud‏ (169.254.169.254/32).
  • תמיכה ב-DNS: מאפשרת את כל תעבורת הנתונים של DNS ביציאה 53, כדי ש-Pods יוכלו לפתור שמות מארחים (תוך התחשבות במטמוני ה-DNS המקומיים של GKE).
  • העברת סמכויות לתעבורת נתונים נכנסת ויוצאת: העברת כל שאר ההחלטות לגבי תעבורת הנתונים באמצעות הפעולה Pass, כדי שכללי המדיניות הרגילים של המפתחים לגבי הרשת וכללי ברירת המחדל הבסיסיים לדחייה יוכלו לקבל את ההחלטות הסופיות.
  1. יוצרים את המניפסט של המדיניות ברמת האדמין של 05-admin-guardrails.yaml שמטרגט את כל מרחבי השמות
cat << 'EOF' > 05-admin-guardrails.yaml
apiVersion: policy.networking.k8s.io/v1alpha2
kind: ClusterNetworkPolicy
metadata:
  name: admin-global-guardrails
spec:
  tier: Admin
  priority: 10
  subject:
    namespaces: {}
  ingress:
    - name: delegate-all-ingress
      action: Pass
      from:
        - namespaces: {}
  egress:
    - name: allow-all-dns
      action: Accept
      to:
        - networks:
            - 0.0.0.0/0
      protocols:
        - udp:
            destinationPort:
              number: 53
        - tcp:
            destinationPort:
              number: 53
    - name: block-metadata-server-global
      action: Deny
      to:
        - networks:
            - 169.254.169.254/32
    - name: delegate-other-egress
      action: Pass
      to:
        - namespaces: {}
EOF
  1. מחילים את המדיניות של רמת האדמין:
kubectl apply -f 05-admin-guardrails.yaml
  1. בודקים את זליגת המטא-נתונים בכל שלושת מרחבי השמות:
echo -e "\n[1/3] Testing Metadata access from Gemma serving pod (gemma-llm)..."
kubectl exec -n gemma-llm deploy/gemma-serving -- curl --connect-timeout 3 -s -w "\nHTTP Code: %{http_code}\n" -H "Metadata-Flavor: Google" \
  http://169.254.169.254/computeMetadata/v1/instance/zone || echo "🛑 RESULT: Connection Timed Out (Blocked)"

echo -e "\n[2/3] Testing Metadata access from authorized client (client-ns)..."
kubectl exec -n client-ns deploy/rag-agent-client -- curl --connect-timeout 3 -s -w "\nHTTP Code: %{http_code}\n" -H "Metadata-Flavor: Google" \
  http://169.254.169.254/computeMetadata/v1/instance/zone || echo "🛑 RESULT: Connection Timed Out (Blocked)"

echo -e "\n[3/3] Testing Metadata access from rogue client (untrusted-tenant)..."
kubectl exec -n untrusted-tenant deploy/rogue-client -- curl --connect-timeout 3 -s -w "\nHTTP Code: %{http_code}\n" -H "Metadata-Flavor: Google" \
  http://169.254.169.254/computeMetadata/v1/instance/zone || echo "🛑 RESULT: Connection Timed Out (Blocked)"
  1. בדיקת הקישוריות של הלקוח מ-client-ns
kubectl exec -n client-ns deploy/rag-agent-client -- curl --connect-timeout 3 -s -X POST \
  http://gemma-service.gemma-llm.svc.cluster.local:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemma-4-E2B-it",
    "messages": [{"role": "user", "content": "Explain zero trust in one short sentence."}],
    "max_tokens": 40
  }' | jq -r '.choices[0].message.content'
  1. כדי לדמות ניסיון של מפתח לעקוף את המדיניות, מפעילים מדיניות NetworkPolicy שמאפשרת את כל תעבורת הנתונים היוצאת בתוך gemma-llm:
cat << 'EOF' > 06-bypass-attempt.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: dev-allow-all-egress
  namespace: gemma-llm
spec:
  podSelector: {}
  policyTypes:
    - Egress
  egress:
    - {}
EOF

kubectl apply -f 06-bypass-attempt.yaml
  1. בודקים אם המעקף של המפתח יכול לבטל את החסימה של הגישה למטא-נתונים:
kubectl exec -n gemma-llm deploy/gemma-serving -- curl --connect-timeout 3 -s -w "\nHTTP Code: %{http_code}\n" -H "Metadata-Flavor: Google" \
  http://169.254.169.254/computeMetadata/v1/instance/zone || echo "🛑 RESULT: Connection Timed Out (Admin Guardrail Overrode Developer Policy)"

9. אימות אינטראקטיבי באמצעות Hubble ו-Cloud Logging

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

  1. לוחצים על הסמל "+" בתפריט של Cloud Shell כדי לפתוח כרטיסיית טרמינל שנייה.
  2. בכרטיסייה החדשה, מריצים את הפקודות הבאות כדי ליצור את הכינוי ולהתחיל לצפות בתנועה בזמן אמת במרחב השמות gemma-llm:
# Create an alias to execute Hubble natively inside the relay pod
alias hubble="kubectl exec -it -n gke-managed-dpv2-observability deploy/hubble-relay -c hubble-cli -- hubble"

# Observe real-time traffic to and from the Gemma namespace
hubble observe --follow --namespace gemma-llm
  1. חוזרים לכרטיסייה הראשונה של Cloud Shell ומוודאים שנמצאים בספרייה gke-cnp-lab.
cd ~/gke-cnp-lab
  1. מריצים את הבלוק הבא כדי ליצור ולהריץ את סקריפט האימות האוטומטי. הסקריפט הזה מריץ את בדיקות התנועה הנדרשות ושולח שאילתות ל-Cloud Logging באמצעות סכימת המטא-נתונים המדויקת ברמת הבסיס של GKE, כדי להציג את הכללים המדויקים של Dataplane V2 שהעריכו את הבקשות:
cat << 'EOF' > verify-suite.sh
#!/usr/bin/env bash
set -e

echo "========================================================"
echo " 🧪 RUNNING MULTI-TIER POLICY VERIFICATION SUITE"
echo "========================================================"

# Test 1: Ingress Authorized Client -> Gemma (Allowed by NetworkPolicy)
echo -e "\n[1/5] Testing Authorized Client -> Gemma Serving..."
if kubectl exec -n client-ns deploy/rag-agent-client -- \
  curl -s --connect-timeout 3 \
  http://gemma-service.gemma-llm.svc.cluster.local:8000/v1/chat/completions > /dev/null; then
  echo "  ✅ RESULT: FORWARDED (Allowed by Developer Network Policy)"
else
  echo "  🛑 RESULT: FAILED"
fi

# Test 2: Ingress Rogue Client -> Gemma (Blocked by Baseline Tier)
echo -e "\n[2/5] Testing Unauthorized Rogue Tenant -> Gemma Serving..."
if kubectl exec -n untrusted-tenant deploy/rogue-client -- \
  curl -s --connect-timeout 3 \
  http://gemma-service.gemma-llm.svc.cluster.local:8000/v1/chat/completions > /dev/null; then
  echo "  ⚠️ RESULT: UNEXPECTED ALLOW"
else
  echo "  🛑 RESULT: DROPPED (Blocked by Baseline Tier)"
fi

# Test 3: Egress Gemma -> GCP Metadata Server (Blocked by Admin Tier)
echo -e "\n[3/5] Testing Metadata access from Gemma serving pod (gemma-llm)..."
kubectl exec -n gemma-llm deploy/gemma-serving -- \
  curl --connect-timeout 3 -s -w "\nHTTP Code: %{http_code}\n" -H "Metadata-Flavor: Google" \
  http://169.254.169.254/computeMetadata/v1/instance/zone || echo "  🛑 RESULT: Connection Timed Out (Blocked)"

# Test 4: Egress Authorized Client -> GCP Metadata Server (Blocked by Admin Tier)
echo -e "\n[4/5] Testing Metadata access from authorized client (client-ns)..."
kubectl exec -n client-ns deploy/rag-agent-client -- \
  curl --connect-timeout 3 -s -w "\nHTTP Code: %{http_code}\n" -H "Metadata-Flavor: Google" \
  http://169.254.169.254/computeMetadata/v1/instance/zone || echo "  🛑 RESULT: Connection Timed Out (Blocked)"

# Test 5: Egress Rogue Client -> GCP Metadata Server (Blocked by Admin Tier)
echo -e "\n[5/5] Testing Metadata access from rogue client (untrusted-tenant)..."
kubectl exec -n untrusted-tenant deploy/rogue-client -- \
  curl --connect-timeout 3 -s -w "\nHTTP Code: %{http_code}\n" -H "Metadata-Flavor: Google" \
  http://169.254.169.254/computeMetadata/v1/instance/zone || echo "  🛑 RESULT: Connection Timed Out (Blocked)"

echo -e "\n========================================================"
echo " 📋 FETCHING AUDIT TRAIL FROM CLOUD LOGGING"
echo "========================================================"
echo "Waiting 12 seconds for telemetry ingestion..."
sleep 12

echo -e "\n🔍 1. Validating Baseline Tier (Rogue Client Block):"
gcloud logging read '
  resource.type="k8s_node"
  logName=~"logs/policy-action"
  jsonPayload.disposition="deny"
  jsonPayload.src.namespace="untrusted-tenant"
  jsonPayload.dest.namespace="gemma-llm"
' --limit=1 --format="table(
    timestamp.date('%H:%M:%S', tz=LOCAL):label=TIME,
    jsonPayload.src.namespace:label=SRC_NS,
    jsonPayload.dest.namespace:label=DEST_NS,
    jsonPayload.policies[0].name:label=BLOCKED_BY_POLICY
)"

echo -e "\n🔍 2. Validating Admin Tier (Metadata Block across all namespaces):"
gcloud logging read '
  resource.type="k8s_node"
  logName=~"logs/policy-action"
  jsonPayload.disposition="deny"
  jsonPayload.connection.dest_ip="169.254.169.254"
' --limit=3 --format="table(
    timestamp.date('%H:%M:%S', tz=LOCAL):label=TIME,
    jsonPayload.src.namespace:label=SRC_NS,
    jsonPayload.connection.dest_ip:label=DEST_IP,
    jsonPayload.policies[0].name:label=BLOCKED_BY_POLICY
)"
EOF

chmod +x verify-suite.sh
./verify-suite.sh
  1. בזמן שהסקריפט פועל בכרטיסייה הראשונה, צופים בפלט של Hubble בכרטיסייה השנייה.

ב-Hubble (כרטיסייה 2): בקשות ה-HTTP המורשות יועברו ויוצגו בירוק. במקרה של תנועה חסומה, יוצגו אירועים אדומים (DROPPED). הדייר הנוכל: החיבור מועבר על ידי שכבת הניהול ונחסם בשכבת הבסיס. שאילתות לקבלת מטא נתונים: הבקשה שלה לגשת לפרטי הכניסה לענן נחסמת מיד ברמת הניהול.

7d68cc0e9b90f820.png

ב-Cloud Logging (כרטיסייה 1): הסקריפט מסיים את הפעולה על ידי שליפת רשומות הביקורת המדויקות שנשלחו אל Google Cloud Logging. הדוח מוכיח באופן מפורש איזו רמה (אדמין או בסיסית) ואיזו מדיניות היו אחראיות לעצירת התנועה הלא מורשית, בפורמט עם חותמות זמן מקומיות שמותאמות לאזור הזמן.

b9e48fd473451ca2.png

10. הסרת המשאבים

  1. סגירת הכרטיסייה השנייה
  2. חוזרים לכרטיסייה הראשונה של Cloud Shell.
  3. מוחקים את המניפסטים, מרחבי השמות והסודות שנפרסו ב-Kubernetes לפי הסדר הבא:
cd ~/gke-cnp-lab

# Delete policy and verification scripts
rm -f verify-suite.sh
kubectl delete -f 05-admin-guardrails.yaml --ignore-not-found
kubectl delete -f 04-app-networkpolicy.yaml --ignore-not-found
kubectl delete -f 03-baseline-deny.yaml --ignore-not-found
kubectl delete -f 00-network-logging.yaml --ignore-not-found

# Delete workload deployments, secrets, and namespaces
kubectl delete -f 02-gemma4-tpu-vllm.yaml --ignore-not-found
kubectl delete secret hf-secret -n gemma-llm --ignore-not-found
kubectl delete -f 01-namespaces-clients.yaml --ignore-not-found
  1. מנקים את התשתית באמצעות הפקודה הבאה, ומקלידים yes כדי לאשר:
terraform destroy --auto-approve
  1. מוודאים שכל המשאבים בפרויקט הפעיל נסגרו כמו שצריך:
gcloud container clusters list --region=us-west4
gcloud compute networks list
  1. מוחקים את הספרייה gke-cnp-lab ואת התוכן שלה:
cd
rm -r gke-cnp-lab

11. מזל טוב

סיימתם את ה-Codelab בנושא אבטחת עומסי עבודה של הסקת AI באמצעות ClusterNetworkPolicy ב-GKE.

בשיעור ה-Lab המעשי הזה תכננתם ואימתם ארכיטקטורת רשת חזקה, רב-שכבתית ומעמיקה להגנה על עומסי עבודה רגישים ופרטיים של LLM ב-Google Kubernetes Engine.

מה השגתם:

  • תשתית כקוד: הקצאה דינמית של אשכול GKE מסוג Standard פרטי ומאובטח ברמה גבוהה, רשת משנה אזורית פרטית וחומרת Cloud TPU v5e ייעודית באמצעות Terraform.
  • טלמטריה וניראות: הגדרת רישום ביומן של רשת Dataplane V2 לצד מעקב eBPF Hubble ברמת הליבה (kernel) כדי להשיג ניראות עמוקה של חבילות בזמן ריצה.
  • מצב אבטחה היררכי: למשל, הפרדה ברורה של חובות תפעוליות בין שלוש רמות הערכה נפרדות:
  • רמת אדמין: אמצעי הגנה על תעבורת נתונים יוצאת (egress) שנאכפים בכל האשכול, שאי אפשר לעקוף אותם ושחוסמים גישה רוחבית לפרטי הכניסה של המטא-נתונים (169.254.169.254).
  • שכבת NetworkPolicy: גבולות כניסה מוקצים ברמת מרחב השמות למפתחי אפליקציות, כדי לאשר חיבורים של לקוחות בסביבת הייצור באופן בטוח.
  • רמת בסיס: בניית רשת ביטחון חלופית לכל האשכול, שדוחה כברירת מחדל תנועה לא מורשית של דיירים.
  • ביקורת בזמן אמת: הפעלה של חבילת מקרים לבדיקה מלאה, צפייה בזמן אמת בחבילות שנמחקו ברמת הליבה של Linux, ושאילתות על ביקורות מובְנות של פעולות מדיניות ישירות ב-Google Cloud Logging

השלבים הבאים / מידע נוסף

מידע נוסף על רשתות GKE