۱. نمای کلی
این آزمایشگاه شما را با ClusterNetworkPolicy در Google Kubernetes Engine (GKE) آشنا میکند. ClusterNetworkPolicy برای موارد استفاده مختلف اعمال میشود و میتواند در سراسر خوشه اعمال شود و در ردیفهای سرپرست و پایه اجرا شود. در این مثال، کنترل را با استقرار LLM (Gemma) در GKE با TPU، vLLM، و اعتبارسنجی نشان خواهیم داد.
با فناوریهای زیر کار خواهید کرد:
- Google Kubernetes Engine (GKE) — پلاتفرم هماهنگسازی کانتینر بنیادی برای میزبانی حجمهای کاری خصوصی و مقیاسپذیر.
- ClusterNetworkPolicy (CNP) — خطمشیهای شبکه چندلایه با محدوده خوشه که امکان ایجاد حفاظهای SecOps را در سطوح Admin، NetworkPolicy، و Baseline فراهم میکند.
- vLLM TPU Inference Engine — استنتاج با توان گذرداد بالا که مدل Gemma 4 سبک (google/gemma-4-E2B-it) را در Google TPUs با نقاط پایانی REST سازگار با OpenAI ارائه میدهد.
نقشها و شخصیتها
Network Policy API براساس شخصیتهای سازمانی خاصی ساختار یافته است:
- استفاده «سرپرست خوشه» (
ClusterNetworkPolicy): حفاظهای امنیتی را در سراسر خوشهها در سطوح «سرپرست» و پایه اعمال میکند. - استفاده «سرپرست فضای نام» (
NetworkPolicy): مرزها و جداسازی سطح مستأجر را در فضاهای نام خاص مدیریت میکند. - استفاده توسعهدهنده برنامه (
NetworkPolicy): قوانین دقیق برای ریزخدمات خاص برنامه تعریف میکند.
برای پیکربندی این محیط، یک VPC خصوصی سفارشی، Cloud NAT، و یک خوشه GKE خصوصی با استخر گره TPU اختصاصی مستقر خواهید کرد.
برای ایمن کردن خوشهتان، منابع ClusterNetworkPolicy چندسطحی را درکنار اشیاء استاندارد NetworkPolicy ایجاد خواهید کرد تا حفاظهای شبکه سختگیرانهای را اعمال کنید. سپس یک حجم کاری هوش مصنوعی را که از vLLM و Google Cloud TPU برای ارائه مدل Gemma 4 استفاده میکند مستقر خواهید کرد.
درنهایت، یک خط مبنای کاری ایجاد میکنید، خطمشیهای امنیتی را اعمال میکنید، و NetworkLogging را بااستفاده از Cloud Logging و جاریسازیهای زنده مشاهدهپذیری Hubble eBPF پیکربندی میکنید تا آن تصمیمات خطمشی را ممیزی کنید و بستههای حذفشده را تأیید کنید. همه پیکربندیها از ترکیبی از Terraform، gcloud، و kubectl. استفاده خواهند کرد
در این آزمایشگاه با نحوه انجام دادن تکلیف زیر آشنا خواهید شد:
- بااستفاده از Terraform، شبکهسازی خصوصی، خوشه GKE، و شتابدهندههای Cloud TPU v5e را تدارک ببینید.
- برای ثبت دورسنجی اتصال، GKE NetworkLogging را پیکربندی کنید.
- Gemma 4 E2B را بااستفاده از تصویر محتوی رسمی vllm/vllm-tpu در TPU مستقر کنید.
- قبلاز اعمال محدودیتها، یک خط مبنای کاری ایجاد کنید که اتصال سرتاسر را اثبات کند.
- برای رد کردن ترافیک غیرمجاز بین فضای نام بهطور پیشفرض،
Baseline-tierClusterNetworkPolicy را اعمال کنید. - یک NetworkPolicy تحت مدیریت توسعهدهنده را برای واگذاری دسترسی به کارخواههای مجاز اعمال کنید.
Admin-tierClusterNetworkPolicy را اعمال کنید تا حفاظهای خروجی سراسری را که تنظیمات توسعهدهنده را لغو میکنند اجرا کنید.- بااستفاده از (جاریسازیهای Hubble eBPF و Cloud Logging)، بستههای زنده ردشده و پذیرفتهشده را درستیسنجی کنید.
در این آزمایشگاه، الگوی زیر را ایجاد خواهید کرد.
شکل ۱. 
۲. راهاندازی سرویسهای Google Cloud
راهاندازی محیط با سرعت دلخواه
- به سیستم کنسول Google Cloud وارد شوید و پروژه جدیدی ایجاد کنید یا از پروژه موجودی دوباره استفاده کنید. اگر ازقبل حساب Gmail یا Google Workspace ندارید، باید حسابی ایجاد کنید.



- نام پروژه نام نمایشی برای شرکتکنندگان این پروژه است. این رشته نویسهای است که Google APIs از آن استفاده نمیکند. همیشه میتوانید آن را بهروز کنید.
- شناسه پروژه در همه پروژههای Google Cloud یکتا است و تغییرناپذیر است (پساز تنظیم شدن نمیتوان آن را تغییر داد). «کنسول Cloud» بهطور خودکار رشتهای یکتا تولید میکند؛ معمولاً برایتان مهم نیست که این رشته چیست. در اکثر codelabها، باید به «شناسه پروژه» خود (که معمولاً بهصورت
PROJECT_IDشناسایی میشود) ارجاع دهید. اگر شناسه تولیدشده را دوست ندارید، میتوانید شناسه تصادفی دیگری تولید کنید. یا میتوانید نام کاربری خودتان را امتحان کنید و ببینید دردسترس است یا نه. بعداز این مرحله نمیتوان آن را تغییر داد و در طول پروژه باقی میماند. - برای اطلاع شما، مقدار سومی هم وجود دارد، شماره پروژه، که برخیاز میاناهای برنامهسازی کاربردی از آن استفاده میکنند. در اسناد درباره هر سه این مقادیر بیشتر بدانید.
- سپس، برای استفاده از منابع/میاناهای برنامهسازی کاربردی Cloud، باید صورتحساب را در Cloud Console فعال کنید. اجرای این codelab هزینه زیادی ندارد، اگر اصلاً هزینهای داشته باشد. برای خاموش کردن منابع بهمنظور جلوگیری از ایجاد صورتحساب فراتر از این آموزش، میتوانید منابعی را که ایجاد کردهاید حذف کنید یا پروژه را حذف کنید. کاربران جدید Google Cloud واجدشرایط برنامه دوره آزمایشی رایگان ۳۰۰ دلاری هستند.
راهاندازی Cloud Shell
درحالیکه Google Cloud را میتوان از راه دور از رایانه کیفی شما اجرا کرد، در این codelab از Google Cloud Shell استفاده خواهید کرد که یک محیط خط فرمان است که در Cloud اجرا میشود.
از کنسول Google Cloud، روی نماد Cloud Shell در نوار ابزار بالا سمت چپ کلیک کنید:

تأمین و اتصال به محیط فقط چند لحظه طول میکشد. وقتی تمام شد، باید چیزی شبیه به این ببینید:

این ماشین مجازی با همه ابزارهای توسعهای که نیاز دارید بارگیری شده است. این ابزار یک دایرکتوری خانگی ۵ گیگابایتی دائمی ارائه میدهد و در Google Cloud اجرا میشود که عملکرد شبکه و اصالتسنجی را بهطور قابلتوجهی بهبود میبخشد. همه کارهای شما در این codelab میتواند در مرورگر انجام شود. نیازی نیست چیزی نصب کنید.
۳. راهاندازی محیط با Terraform
برای تکمیل این آزمایشی،
- باید به سهمیه TPU v5e در منطقه و ناحیه انتخابیتان دسترسی داشته باشید. برای مثال (
us-central1-a, us-west4-a, us-south1-a, us-west1-c, europe-west4-b). برای دسترسی باید سند طرح TPU را دنبال کنید و سهمیه TPU را فعال کنید. - این یک استقرار کوچک است که به ۴ تراشه TPU v5e نیاز دارد (
ct5lp-hightpu-4t),که یک برش ۲×۲ در یک منطقه تشکیل میدهد.
برای استفاده از Hugging Face
- کد Hugging Face: برای بارگیری وزنهای مدل Gemma، به کد دسترسی نیاز است.
- هرگونه قرارداد استفاده را درصورت نیاز بپذیرید.
یک VPC سفارشی با قوانین دیواره آتش، یک زیرشبکه، و سپس یک خوشه خلبان خودکار ایجاد خواهیم کرد. کنسول ابری را باز کنید و پروژهای را که استفاده خواهید کرد انتخاب کنید.
- Cloud Shell را که در بالا سمت چپ کنسول قرار دارد باز کنید، مطمئن شوید که شناسه پروژه صحیح را در Cloud Shell میبینید، و هرگونه پیاموارهای را که برای اجازه دسترسی نشان داده میشود تأیید کنید.

- فهرست راهنمایی بهنام
gke-cnp-lab,ایجاد کنید و به آن فهرست راهنما بروید.
mkdir -p gke-cnp-lab && cd gke-cnp-lab
- اکنون چند متغیر ایجاد کنید. پینوشت: REGION و ZONE را ویرایش کنید تا مکان واقعی را که در آن به منابع TPU دسترسی دارید نشان دهد. پیشفرض استفادهشده در منطقه آزمایشگاهی
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 directory ایجاد میکنند.
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
- طرح اجرا را اعمال کنید. چون درحال اعمال طرح اجرای ذخیرهشده هستید، این طرح بلافاصله بدون درخواست تأیید اجرا خواهد شد (این کار ممکن است بین ۶ تا ۱۰ دقیقه طول بکشد)
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

۴. پیکربندی ثبت گزارش شبکه
قبلاز استقرار حجمهای کاری و خطمشیها، GKE Network Logging را پیکربندی کنید تا دورسنجی اتصال را ضبط کند و تصمیمات خطمشی را در 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 بهسادگی مدیریت آن را برای اعمال قوانین جدید شما برعهده میگیرد.
۵. Deploy Gemma 4 Workload and Client Probes
فضاهای نام مجزایی برای آزمایش ارزیابیهای خطمشی چندسطحی ایجاد خواهید کرد:
gemma-llm: بار کاری استنتاج Gemma 4 اصلی را در خود جای میدهد (tier: ai-core).client-ns: کارخواه گپ RAG مجاز (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
استقرار حجم کاری 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}
- بااستفاده از vllm-tpu، مانیفست حجم کاری استنتاج Gemma 4 را با هدفگیری Cloud TPU v5e ایجاد کنید:
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
- برای نظارت بر وضعیت تکمیل، دستورات زیر را اجرا کنید. پادها تا زمانی که گره تأمین شود منتظر میمانند تا بتوانند ادامه دهند، این ممکن است بیشاز ۱۳ دقیقه طول بکشد.
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!"
۶. آشنایی با ارزیابی خطمشی و وضعیت پیشفرض
پیشاز اعمال خطمشیهای شبکه، با نحوه تعامل GKE ClusterNetworkPolicy و Kubernetes NetworkPolicy استاندارد در سطوح مختلف ارزیابی آشنا شوید.
ترافیک در 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)"
۷. آزمایش ارزیابی خط مبنا و سطح خطمشی شبکه
در این مرحله، بهعنوان سرپرست خوشه، 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'
۸. ارزیابی «حفاظهای سراسری» را اعمال میکند (سطح سرپرست)
بهعنوان سرپرست خوشه، اکنون سطح سرپرست ClusterNetworkPolicy را در بالاترین سطح ترتیب ارزیابی GKE اعمال خواهید کرد. این سطح ابتدا ارزیابی میشود، هر قانون منطبقی بلافاصله بر همه سطوح دیگر اولویت دارد. اگر مطابقت وجود نداشته باشد، بسته برای ارزیابی به ردیفهای پایینتر (NetworkPolicy و Baseline) منتقل میشود.
در این مرحله، خطمشیای را اعمال خواهید کرد که:
- Cluster-wide Egress Guardrail: همه پادها را در هر فضای نامی از دسترسی به Google Cloud Metadata Server (
169.254.169.254/32) مسدود میکند. - پشتیبانی ساناد: همه ترافیک ساناد را در درگاه ۵۳ مجاز میکند تا پادها بتوانند نامهای میزبان را حلوفصل کنند (با درنظر گرفتن حافظههای پنهان ساناد محلی GKE).
- واگذاری ورودی و خروجی: بااستفاده از کنش «مجاز کردن»، همه تصمیمهای دیگر مربوط به ترافیک را به پایین منتقل میکند تا خطمشیهای استاندارد شبکه توسعهدهنده و قوانین پیشفرض رد کردن پایه بتوانند تصمیمهای نهایی را بگیرند.
- ایجاد مانیفست خطمشی سطح سرپرست
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)"
۹. درستیسنجی تعاملی با 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
- بلوک زیر را اجرا کنید تا دستورگان درستیسنجی خودکار ایجاد و اجرا شود. این اسکریپت آزمایشهای ترافیک لازم را اجرا میکند و بااستفاده از طرحواره فراداده دقیق سطح ریشه GKE، از Cloud Logging پُرسمان میکند تا قوانین دقیق 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 (برگه ۲): درخواستهای HTTP مجاز را خواهید دید که به رنگ سبز «بازارسال» میشوند. برای ترافیک مسدودشده، رویدادهای قرمز (رهاشده) را خواهید دید. مستأجر سرکش: اتصال از «سطح سرپرست» عبور میکند و در «سطح پایه» مسدود میشود. پرسوجوی فراداده: درخواست آن برای دسترسی به اعتبارنامههای ابری بلافاصله در «سطح سرپرست» مسدود میشود.

در Cloud Logging (برگه ۱): اسکریپت با استخراج دقیق سوابق ممیزی ارسالشده به Google Cloud Logging بهپایان میرسد. این گزارش بهطور صریح نشان میدهد که کدام سطح (سرپرست یا پایه) و کدام خطمشی مسئول توقف ترافیک غیرمجاز بوده است، و با مُهرهای زمان بومیسازیشده و آگاه از منطقه زمانی قالببندی شده است.

۱۰. مرتبسازی
- بستن برگه دوم
- به اولین برگه 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
۱۱. تبریک میگوییم
Codelab «حجمهای کاری استنتاج هوش مصنوعی ایمن با GKE ClusterNetworkPolicy» را باموفقیت تکمیل کردید!
با تکمیل این آزمایشگاه عملی، یک معماری شبکه دفاع در عمق چندلایه و قوی را برای ارائه بارهای کاری حساس و خصوصی مدل زبانی بزرگ در Google Kubernetes Engine طراحی و اعتبارسنجی کردهاید.
آنچه انجام دادهاید:
- زیرساخت بهعنوان کد: یک «خوشه GKE استاندارد» خصوصی بسیار امن، یک زیرشبکه منطقهای خصوصی، و سختافزار اختصاصی Cloud TPU v5e را بهصورت پویا بااستفاده از Terraform فراهم کردیم.
- دور سنجی و مشاهدهپذیری: Dataplane V2 Network Logging را در کنار ردیابی eBPF Hubble در سطح هسته پیکربندی کرد تا به رؤیتپذیری عمیق بسته زمان اجرا دست یابد.
- وضعیت امنیتی سلسلهمراتبی: برای مثال، جداسازی واضح وظایف عملیاتی در سه سطح ارزیابی متمایز:
- سطح سرپرست: حفاظهای خروجی غیرقابلدورزدن که در سطح خوشه اعمال میشوند و دسترسی به اطلاعات کاربری فراداده جانبی را مسدود میکنند (169.254.169.254).
- NetworkPolicy Tier: Delegated namespace-scoped ingress boundaries to application developers to authorize production client connections safely.
- سطح پایه: یک شبکه ایمنی بازگشت در سراسر خوشه ساخته شد که بهطور پیشفرض ترافیک مستأجر غیرمجاز را رد میکرد.
- بازرسی همزمان: اجرای مجموعه آزمون درستیسنجی کامل، مشاهده همزمان بستههای حذفشده در سطح هسته Linux، و جستجوی مستقیم بازرسیهای ساختاریافته کنش خطمشی در Google Cloud Logging
مراحل بعدی / بیشتر بدانید
میتوانید درباره شبکهسازی GKE بیشتر بخوانید
- ژرفکاوی در پیکربندی GKE ClusterNetworkPolicy