1. نظرة عامة
يقدّم لك هذا التمرين ClusterNetworkPolicy على Google Kubernetes Engine (GKE). يتم تطبيق ClusterNetworkPolicy في حالات استخدام مختلفة، ويمكن تطبيقه على مستوى المجموعة العنقودية وتنفيذه في مستويَي المشرف والأساسي. في هذا المثال، سنوضّح كيفية التحكّم في عملية نشر نموذج لغوي كبير (Gemma) على GKE باستخدام وحدات معالجة الموتّرات (TPU) وvLLM والتحقّق من الصحة.
ستعمل مع التكنولوجيات التالية:
- Google Kubernetes Engine (GKE): منصة أساسية لإدارة الحاويات من أجل استضافة أعباء العمل الخاصة والقابلة للتوسّع.
- ClusterNetworkPolicy (CNP): سياسات شبكة متعددة المستويات على مستوى المجموعة تتيح استخدام حواجز حماية SecOps في مستويات المشرف وNetworkPolicy وBaseline.
- vLLM TPU Inference Engine: يقدّم هذا المحرّك استدلالاً بمعدّل نقل بيانات عالٍ لنموذج Gemma 4 الخفيف (google/gemma-4-E2B-it) على وحدات معالجة الموتّرات في Google مع نقاط نهاية REST المتوافقة مع OpenAI.
الأدوار والشخصيات
تم تصميم Network Policy API استنادًا إلى أدوار تنظيمية محدّدة:
- استخدام مشرف المجموعة (
ClusterNetworkPolicy): يفرض إجراءات الأمان الوقائية على مستوى المجموعات في مستويات المشرف والمستويات الأساسية. - استخدام مشرف مساحة الاسم (
NetworkPolicy): يدير الحدود والعزل على مستوى المستأجر ضمن مساحات اسم محدّدة. - استخدام مطوّر التطبيقات (
NetworkPolicy): يحدّد قواعد دقيقة للخدمات المصغّرة الخاصة بالتطبيقات.
لضبط هذه البيئة، عليك نشر شبكة VPC خاصة مخصّصة وCloud NAT ومجموعة GKE خاصة مع مجموعة أجهزة ذات التخصيص نفسه لوحدة معالجة الموتّرات.
لتأمين المجموعة، ستنشئ موارد ClusterNetworkPolicy متعددة المستويات إلى جانب عناصر NetworkPolicy العادية لفرض قيود صارمة على الشبكة. بعد ذلك، ستنشر عبء عمل مستند إلى الذكاء الاصطناعي يستخدم vLLM ووحدات معالجة الموتّرات في Google Cloud لعرض نموذج Gemma 4.
أخيرًا، ستضع أساسًا للعمل، وتطبّق سياسات الأمان، وتضبط NetworkLogging باستخدام Cloud Logging وHubble eBPF observability المباشرة لتدقيق قرارات السياسات هذه والتحقّق من عمليات إسقاط الحِزم. ستستخدم جميع الإعدادات مجموعة من Terraform وgcloud وkubectl.
في هذا التمرين، ستتعرّف على كيفية تنفيذ المهمة التالية:
- توفير شبكة خاصة ومجموعة GKE ومسرّعات Cloud TPU v5e باستخدام Terraform
- اضبط إعدادات GKE NetworkLogging لتسجيل بيانات الاتصال عن بُعد.
- نشر نموذج Gemma 4 E2B على وحدة معالجة الموتّرات (TPU) باستخدام صورة حاوية vllm/vllm-tpu الرسمية
- أنشئ خطًا أساسيًا للعمل يثبت الاتصال من طرف إلى طرف قبل تطبيق القيود.
- تطبيق سياسة
Baseline-tierClusterNetworkPolicy لرفض الزيارات غير المصرّح بها بين مساحات الأسماء تلقائيًا - تطبيق سياسة NetworkPolicy يديرها المطوّر لتفويض الوصول إلى العملاء المصرّح لهم
- طبِّق سياسة
Admin-tierClusterNetworkPolicy لفرض إجراءات وقائية عامة على حركة البيانات الصادرة تلغي إعدادات المطوّرين. - التحقّق من عمليات إسقاط الحزم وتمريرها في الوقت الفعلي باستخدام (تدفقات Hubble eBPF وCloud Logging)
في هذا التمرين المعملي، ستقوم بإنشاء النمط التالي.
الشكل 1: 
2. إعداد خدمات Google Cloud
إعداد بيئة التعلّم الذاتي
- سجِّل الدخول إلى Google Cloud Console وأنشئ مشروعًا جديدًا أو أعِد استخدام مشروع حالي. إذا لم يكن لديك حساب على Gmail أو Google Workspace، عليك إنشاء حساب.



- اسم المشروع هو الاسم المعروض للمشاركين في هذا المشروع. وهي سلسلة أحرف لا تستخدمها Google APIs. ويمكنك تعديلها في أي وقت.
- رقم تعريف المشروع فريد في جميع مشاريع Google Cloud وغير قابل للتغيير (لا يمكن تغييره بعد ضبطه). تنشئ Cloud Console تلقائيًا سلسلة فريدة، وعادةً لا يهمّك ما هي. في معظم الدروس التطبيقية حول الترميز، ستحتاج إلى الإشارة إلى رقم تعريف المشروع (يتم تحديده عادةً على أنّه
PROJECT_ID). إذا لم يعجبك رقم التعريف الذي تم إنشاؤه تلقائيًا، يمكنك إنشاء رقم تعريف عشوائي آخر. يمكنك بدلاً من ذلك تجربة اسم من اختيارك والتحقّق من توفّره. ولا يمكن تغييرها بعد هذه الخطوة وتبقى طوال مدة المشروع. - للعلم، هناك قيمة ثالثة، وهي رقم المشروع، تستخدمها بعض واجهات برمجة التطبيقات. يمكنك الاطّلاع على مزيد من المعلومات عن هذه القيم الثلاث في المستندات.
- بعد ذلك، عليك تفعيل الفوترة في Cloud Console لاستخدام موارد/واجهات برمجة تطبيقات Cloud. لن يتطلّب منك هذا الدرس التطبيقي حول الترميز دفع تكاليف كبيرة، هذا إن تطلّب دفع أي تكاليف على الإطلاق. لإيقاف الموارد لتجنُّب تحمُّل تكاليف الفوترة بعد هذا البرنامج التعليمي، يمكنك حذف الموارد التي أنشأتها أو حذف المشروع. يمكن لمستخدمي Google Cloud الجدد الاستفادة من برنامج الفترة التجريبية المجانية بقيمة 300 دولار أمريكي.
بدء Cloud Shell
على الرغم من إمكانية تشغيل Google Cloud عن بُعد من الكمبيوتر المحمول، ستستخدم في هذا الدرس التطبيقي حول الترميز Google Cloud Shell، وهي بيئة سطر أوامر تعمل في السحابة الإلكترونية.
من Google Cloud Console، انقر على رمز Cloud Shell في شريط الأدوات في أعلى يسار الصفحة:

من المفترض أن يستغرق توفير البيئة والاتصال بها بضع ثوانٍ فقط. عند الانتهاء، من المفترض أن يظهر لك شيء مثل هذا:

يتم تحميل هذا الجهاز الافتراضي بجميع أدوات المطوّرين التي ستحتاج إليها. وتوفّر هذه الأداة دليلاً رئيسيًا دائمًا بسعة 5 غيغابايت، وتعمل على Google Cloud، ما يحسّن أداء الشبكة والمصادقة بشكل كبير. يمكن تنفيذ جميع أعمالك في هذا الدرس التطبيقي حول الترميز من خلال المتصفّح. ولست بحاجة إلى تثبيت أي شيء.
3- إعداد البيئة باستخدام Terraform
لإكمال هذا التمرين،
- يجب أن يكون لديك إذن بالوصول إلى حصة 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 Shell في أعلى وحدة التحكّم على يسار الصفحة، وتأكَّد من ظهور رقم تعريف المشروع الصحيح في Cloud Shell، ثم أكِّد أي طلبات للسماح بالوصول.

- أنشئ دليلاً باسم
gke-cnp-lab,وانتقِل إليه.
mkdir -p gke-cnp-lab && cd gke-cnp-lab
- الآن، أنشئ بعض المتغيّرات. ملاحظة: عدِّل REGION وZONE لتعكس الموقع الجغرافي الفعلي الذي يمكنك الوصول فيه إلى موارد وحدة معالجة الموتّرات. الإعداد التلقائي المستخدَم في منطقة التمرين المعملي
us-west4والمنطقةus-west4-a
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"
- احفظ متغيّرات الإعداد في نص برمجي مساعد في دليل 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
- أضِف الآن بعض ملفات الإعداد. سيؤدي ذلك إلى إنشاء ملفات 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
- تأكَّد من أنّك في دليل gke-cnp-lab وشغِّل الأوامر التالية
terraform initلتهيئة دليل العمل. هذه هي الخطوة الأولى، ويتم فيها تنزيل مقدّمي الخدمات المطلوبين للإعدادات المحدّدة.terraform plan -outينشئ خطة تنفيذ تعرض الإجراءات التي سيتّخذها Terraform لنشر البنية الأساسية. تتيح لك السمة-outحفظ خطة التنفيذ في ملف ثنائي مسمّى. يمكنك الاطّلاع على ما سيحدث بدون إجراء أي تغييرات.terraform applyينفّذ التعديلات.
terraform init
terraform plan -out cnpgke
- طبِّق خطة التنفيذ. بما أنّك تطبّق خطة التنفيذ المحفوظة، سيتم تنفيذها على الفور بدون طلب التأكيد (قد يستغرق ذلك من 6 إلى 10 دقائق)
terraform apply cnpgke
- التحقّق من نشر البنية الأساسية:
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

4. ضبط ميزة "تسجيل الشبكة"
قبل نشر أعباء العمل والسياسات، اضبط تسجيل الشبكة في GKE لتسجيل بيانات الاتصال وقرارات سياسة التدقيق في Cloud Logging.
- في الدليل
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
- تطبيق الإعدادات على المجموعة
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: يتضمّن برنامج المحادثة المصرَّح له باستخدام ميزة "التوليد المعزّز بالاسترجاع" (tier: app-frontend). untrusted-tenant: يحتوي على حاوية فحص غير مصرَّح بها (tier: untrusted).
- في
gke-cnp-lab directory,، أنشئ بيان01-namespaces-clients.yamlالذي يحتوي على مساحات الأسماء ومجموعات عملاء الاختبار:
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}
- أنشئ بيان عبء عمل الاستدلال في 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
- أنشئ عملية النشر.
kubectl apply -f 02-gemma4-tpu-vllm.yaml
- لمراقبة حالة الاكتمال، نفِّذ النص البرمجي التالي أدناه. ستنتظر مجموعات الوحدات إلى أن يتم توفير العقدة قبل المتابعة، وقد يستغرق ذلك أكثر من 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. فهم تقييم السياسات والحالة التلقائية
قبل تطبيق سياسات الشبكة، عليك فهم كيفية تفاعل ClusterNetworkPolicy في GKE وNetworkPolicy العادية في Kubernetes على مستوى مستويات التقييم المختلفة.
يتم تقييم عدد الزيارات في GKE من خلال نموذج أولوية متعدّد المستويات:
Admin Tier ⟶ NetworkPolicy Tier ⟶ Baseline Tier ⟶ Default GKE Behavior

مسار الاختبار
===================================================
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 العادي بدون سياسات، يتم السماح ضمنيًا بجميع الزيارات عبر مساحات الأسماء.
- اختبار الاستنتاج من العميل المفوَّض في
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'
- اختبار الاستدلال من العميل المخادع غير المصرَّح به في
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'
- اختبِر ما إذا كان بإمكان مجموعات الحجيرات في جميع مساحات الأسماء الثلاثة الوصول إلى خادم البيانات الوصفية (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. اختبار التقييم الأساسي وفئة سياسة الشبكة
في هذه الخطوة، بصفتك مشرف المجموعة، ستطبّق مستوى أساسيًا ClusterNetworkPolicy لإنشاء وضعية رفض تلقائية احتياطية على مستوى المجموعة. سيتم تجاهل أي اتصال عبر مساحات الأسماء غير مسموح به صراحةً من خلال مستوى أعلى.
إنشاء وضعية "نهج الثقة المعدومة" (الفئة الأساسية)
- أنشِئ ملف بيان سياسة المستوى الأساسي في
03-baseline-deny.yaml:
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
- تطبيق سياسة المستوى "الأساسي":
kubectl apply -f 03-baseline-deny.yaml
- اختبار اتصال العميل من
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'
- اختبار الاستنتاج من العميل المارق غير المصرَّح به في المستأجر غير الموثوق به:
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.
- أنشِئ ملف بيان 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
- طبِّق السياسة:
kubectl apply -f 04-app-networkpolicy.yaml
- اختبار اتصال العميل من
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'
- اختبِر الاتصال من العميل المخادع في
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).
في هذه الخطوة، ستطبّق سياسة تؤدي إلى ما يلي:
- حاجز حماية الخروج على مستوى المجموعة: يحظر جميع مجموعات الإعلانات في كل مساحة اسم من الوصول إلى خادم البيانات الوصفية في Google Cloud (
169.254.169.254/32). - إتاحة نظام أسماء النطاقات: يسمح هذا الإعداد بجميع زيارات نظام أسماء النطاقات على المنفذ 53 حتى تتمكّن مجموعات الوحدات من تحليل أسماء المضيفين (مع مراعاة ذاكرة التخزين المؤقت المحلية لنظام أسماء النطاقات في GKE).
- تفويض حركة البيانات الواردة والصادرة: يتم تمرير جميع قرارات حركة البيانات الأخرى باستخدام الإجراء "تمرير" (Pass) حتى تتمكّن سياسات شبكة المطوّرين العادية وقواعد الرفض التلقائية الأساسية من اتخاذ القرارات النهائية.
- إنشاء بيان سياسة
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
- طبِّق سياسة "مستوى المشرف":
kubectl apply -f 05-admin-guardrails.yaml
- اختبِر استخراج البيانات الوصفية في جميع مساحات الأسماء الثلاثة:
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)"
- اختبار اتصال العميل من
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'
- يمكنك محاكاة محاولة مطوّر لتجاوز السياسة من خلال تطبيق سياسة 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
- اختبِر ما إذا كان بإمكان تجاوز المطوّر إزالة حظر الوصول إلى البيانات الوصفية:
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 على مستوى النواة والتنفيذ التجريبي الآلي.
- انقر على الرمز "+" في قائمة Cloud Shell لفتح علامة تبويب ثانية في الوحدة الطرفية.
- في علامة التبويب الجديدة هذه، نفِّذ الأوامر التالية لإنشاء الاسم المستعار وبدء مراقبة الزيارات المباشرة لمساحة الاسم
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
- ارجع إلى علامة التبويب الأولى في Cloud Shell وتأكَّد من أنّك في الدليل
gke-cnp-lab
cd ~/gke-cnp-lab
- شغِّل المجموعة التالية لإنشاء النص البرمجي المبرمَج للتحقّق وتنفيذه. ينفّذ هذا النص البرمجي اختبارات الزيارات المطلوبة ويُرسل طلبات بحث إلى 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
- أثناء تنفيذ النص البرمجي في علامة التبويب الأولى، راقِب مخرجات Hubble في علامة التبويب الثانية.
في Hubble (علامة التبويب 2): ستظهر طلبات HTTP المصرَّح بها باللون الأخضر مع الإشارة إلى أنّه تمت إعادة توجيهها. بالنسبة إلى الزيارات المحظورة، ستظهر لك أحداث باللون الأحمر (تم إسقاطها). المستأجر المخادع: يتم تمرير الاتصال من خلال "مستوى المشرف" وحظره في "المستوى الأساسي". طلبات البيانات الوصفية: يتم حظر طلب الوصول إلى بيانات اعتماد السحابة الإلكترونية على الفور في "مستوى المشرف".

في Cloud Logging (علامة التبويب 1): ينتهي النص البرمجي بسحب سجلّات التدقيق الدقيقة التي تم إرسالها إلى Google Cloud Logging. ويثبت ذلك صراحةً المستوى (المشرف أو الأساسي) والسياسة التي كانت مسؤولة عن إيقاف الزيارات غير المصرّح بها، ويتم تنسيقها باستخدام طوابع زمنية محلية تراعي المنطقة الزمنية.

10. تَنظيم
- إغلاق علامة التبويب الثانية
- ارجع إلى علامة تبويب Cloud Shell الأولى.
- احذف ملفات بيان 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
- يُرجى تنظيف البنية الأساسية باستخدام الأمر التالي، ثم كتابة كلمة "
yes" للتأكيد
terraform destroy --auto-approve
- تأكَّد من إنهاء جميع الموارد بشكل كامل في مشروعك النشط:
gcloud container clusters list --region=us-west4
gcloud compute networks list
- احذف دليل
gke-cnp-labومحتوياته:
cd
rm -r gke-cnp-lab
11. تهانينا
لقد أكملت بنجاح الدرس التطبيقي حول الترميز "تأمين أعباء عمل استنتاج الذكاء الاصطناعي باستخدام ClusterNetworkPolicy في GKE".
من خلال إكمال هذا التمرين العملي، تكون قد صمّمت وتحقّقت من بنية شبكة قوية ومتعددة المستويات للدفاع في العمق من أجل عرض أعباء عمل حساسة وخاصة للنماذج اللغوية الكبيرة على Google Kubernetes Engine.
ما حققته:
- البنية الأساسية كرمز برمجي: تم توفير مجموعة GKE عادية خاصة وآمنة للغاية، وشبكة فرعية إقليمية خاصة، وأجهزة Cloud TPU v5e مخصّصة بشكل ديناميكي باستخدام Terraform.
- القياس عن بُعد وإمكانية تتبّع البيانات: تم ضبط ميزة "تسجيل الشبكة" في Dataplane V2 إلى جانب تتبُّع Hubble المستند إلى eBPF على مستوى النواة للحصول على إمكانية تتبّع عميقة للحِزم أثناء التشغيل.
- الوضع الأمني الهرمي: على سبيل المثال، فصل واضح للواجبات التشغيلية عبر ثلاثة مستويات تقييم متميزة:
- مستوى المشرف: يتم فرض قيود على مستوى المجموعة بالكامل لمنع الوصول إلى بيانات الاعتماد الوصفية الجانبية (169.254.169.254)، ولا يمكن تجاوز هذه القيود.
- فئة NetworkPolicy: حدود الدخول المفوَّضة على مستوى مساحة الاسم لمطوّري التطبيقات من أجل السماح باتصالات العملاء في مرحلة الإنتاج بأمان.
- الفئة الأساسية: تم إنشاء شبكة أمان احتياطية على مستوى المجموعة ترفض تلقائيًا حركة البيانات غير المصرَّح بها للمستأجرين.
- التدقيق في الوقت الفعلي: يمكنك تشغيل حزمة اختبارية كاملة للتحقّق من الصحة، ومراقبة عمليات إسقاط الحِزم في الوقت الفعلي على مستوى نواة Linux، والاستعلام عن عمليات تدقيق إجراءات السياسات المنظَّمة مباشرةً في Google Cloud Logging
الخطوات التالية / مزيد من المعلومات
يمكنك الاطّلاع على مزيد من المعلومات حول شبكات GKE
- تعرَّف أكثر على ضبط ClusterNetworkPolicy في GKE