1. Tổng quan
Phòng thí nghiệm này giới thiệu cho bạn về ClusterNetworkPolicy trên Google Kubernetes Engine (GKE). ClusterNetworkPolicy được áp dụng cho nhiều trường hợp sử dụng và có thể được áp dụng trên toàn bộ Cụm, cũng như được thực thi ở cấp Quản trị viên và cấp cơ sở. Trong ví dụ này, chúng tôi sẽ minh hoạ cách kiểm soát bằng một mô hình ngôn ngữ lớn (Gemma) được triển khai trên GKE có TPU, vLLM và quy trình xác thực.
Bạn sẽ làm việc với các công nghệ sau:
- Google Kubernetes Engine (GKE) – Nền tảng điều phối vùng chứa cơ bản để lưu trữ các khối lượng công việc riêng tư, có thể mở rộng.
- ClusterNetworkPolicy (CNP) — Chính sách mạng nhiều tầng trong phạm vi cụm, cho phép các biện pháp bảo vệ SecOps trên các tầng Quản trị, NetworkPolicy và Đường cơ sở.
- Công cụ suy luận vLLM TPU – Cung cấp dịch vụ suy luận có công suất cao cho mô hình Gemma 4 gọn nhẹ (google/gemma-4-E2B-it) trên Google TPU bằng các điểm cuối REST tương thích với OpenAI.
Vai trò và chân dung người dùng
Network Policy API được xây dựng dựa trên các vai trò cụ thể trong tổ chức:
- Sử dụng Cluster Administrator (
ClusterNetworkPolicy): Thực thi các biện pháp bảo vệ bảo mật trên các cụm ở cấp Quản trị viên và cấp cơ sở. - Quyền sử dụng của Quản trị viên không gian tên (
NetworkPolicy): Quản lý ranh giới và sự tách biệt ở cấp đối tượng thuê trong các không gian tên cụ thể. - Sử dụng cho nhà phát triển ứng dụng (
NetworkPolicy): Xác định các quy tắc chi tiết cho các dịch vụ vi mô dành riêng cho ứng dụng.
Để định cấu hình môi trường này, bạn sẽ triển khai một VPC riêng tư tuỳ chỉnh, Cloud NAT và một cụm GKE riêng tư có bộ nút TPU chuyên dụng.
Để bảo mật cụm, bạn sẽ tạo tài nguyên ClusterNetworkPolicy nhiều tầng cùng với các đối tượng NetworkPolicy tiêu chuẩn để thực thi các rào chắn mạng nghiêm ngặt. Sau đó, bạn sẽ triển khai một khối lượng công việc AI sử dụng vLLM, TPU của Google Cloud để phân phát mô hình Gemma 4.
Cuối cùng, bạn sẽ thiết lập một đường cơ sở hoạt động, áp dụng các chính sách bảo mật và định cấu hình NetworkLogging bằng Cloud Logging và các luồng khả năng ghi nhận Hubble eBPF trực tiếp để kiểm tra các quyết định dựa trên chính sách đó và xác minh việc rớt gói. Tất cả cấu hình sẽ sử dụng kết hợp Terraform, gcloud và kubectl.
Trong lớp học lập trình này, bạn sẽ tìm hiểu cách thực hiện những việc sau:
- Cung cấp mạng riêng tư, một cụm GKE và trình tăng tốc Cloud TPU v5e bằng Terraform.
- Định cấu hình GKE NetworkLogging để ghi lại dữ liệu đo từ xa về kết nối.
- Triển khai Gemma 4 E2B trên TPU bằng cách sử dụng hình ảnh vùng chứa vllm/vllm-tpu chính thức.
- Thiết lập một đường cơ sở hoạt động để chứng minh khả năng kết nối toàn diện trước khi áp dụng các quy định hạn chế.
- Áp dụng
Baseline-tierClusterNetworkPolicy để từ chối lưu lượng truy cập trái phép giữa các không gian tên theo mặc định. - Áp dụng NetworkPolicy do nhà phát triển quản lý để uỷ quyền truy cập cho các ứng dụng được uỷ quyền.
- Áp dụng
Admin-tierClusterNetworkPolicy để thực thi các rào chắn lưu lượng truy cập ra ngoài chung, ghi đè chế độ cài đặt của nhà phát triển. - Xác minh các gói bị loại bỏ và được chuyển trực tiếp bằng (luồng eBPF của Hubble và Cloud Logging).
Trong lớp học lập trình này, bạn sẽ tạo mẫu sau.
Hình 1.
2. Thiết lập các dịch vụ của Google Cloud
Thiết lập môi trường tự học
- Đăng nhập vào Google Cloud Console rồi tạo một dự án mới hoặc sử dụng lại một dự án hiện có. Nếu chưa có tài khoản Gmail hoặc Google Workspace, bạn phải tạo một tài khoản.



- Tên dự án là tên hiển thị cho những người tham gia dự án này. Đây là một chuỗi ký tự không được các API của Google sử dụng. Bạn có thể cập nhật thông tin này bất cứ lúc nào.
- Mã dự án là duy nhất trong tất cả các dự án trên Google Cloud và không thể thay đổi (không thể thay đổi sau khi đã đặt). Cloud Console tự động tạo một chuỗi duy nhất; thường thì bạn không cần quan tâm chuỗi đó là gì. Trong hầu hết các lớp học lập trình, bạn sẽ cần tham chiếu Mã dự án (thường được xác định là
PROJECT_ID). Nếu không thích mã được tạo, bạn có thể tạo một mã ngẫu nhiên khác. Ngoài ra, bạn có thể thử tên người dùng của riêng mình và xem tên đó có sẵn hay không. Bạn không thể thay đổi thông tin này sau bước này và thông tin này sẽ được giữ nguyên trong suốt thời gian diễn ra dự án. - Để bạn biết, có một giá trị thứ ba là Số dự án mà một số API sử dụng. Tìm hiểu thêm về cả ba giá trị này trong tài liệu.
- Tiếp theo, bạn cần bật tính năng thanh toán trong Cloud Console để sử dụng các tài nguyên/API của Cloud. Việc chạy lớp học lập trình này sẽ không tốn nhiều chi phí, nếu có. Để tắt tài nguyên nhằm tránh phát sinh phí ngoài hướng dẫn này, bạn có thể xoá tài nguyên đã tạo hoặc xoá dự án. Người dùng mới của Google Cloud đủ điều kiện tham gia chương trình Dùng thử miễn phí trị giá 300 USD.
Bắt đầu Cloud Shell
Mặc dù có thể vận hành Google Cloud từ xa bằng máy tính xách tay, nhưng trong lớp học lập trình này, bạn sẽ sử dụng Google Cloud Shell, một môi trường dòng lệnh chạy trên Cloud.
Trong Google Cloud Console, hãy nhấp vào biểu tượng Cloud Shell trên thanh công cụ trên cùng bên phải:

Quá trình cấp phép và kết nối với môi trường chỉ mất vài phút. Khi quá trình này hoàn tất, bạn sẽ thấy kết quả như sau:

Máy ảo này được trang bị tất cả công cụ cho nhà phát triển mà bạn cần. Cloud Shell cung cấp thư mục gốc 5 GB cố định và chạy trên Google Cloud, giúp cải thiện đáng kể hiệu suất mạng và khả năng xác thực. Bạn có thể thực hiện tất cả công việc trong lớp học lập trình này bằng trình duyệt. Bạn không cần cài đặt gì cả.
3. Thiết lập môi trường bằng Terraform
Để hoàn thành bài thực hành này,
- Bạn cần có quyền truy cập vào hạn mức TPU v5e trong khu vực và vùng mà bạn đã chọn, ví dụ: (
us-central1-a, us-west4-a, us-south1-a, us-west1-c, europe-west4-b). Bạn nên làm theo tài liệu về gói TPU và bật hạn mức TPU để có quyền truy cập. - Đây là một mô hình triển khai nhỏ cần 4 khối TPU phiên bản 5e (
ct5lp-hightpu-4t),sẽ tạo thành một lát cắt 2x2 trong một vùng.
Cách sử dụng Hugging Face
- Mã thông báo Hugging Face: Bạn cần có Mã truy cập để tải trọng số mô hình Gemma xuống.
- Chấp nhận mọi thoả thuận sử dụng theo yêu cầu.
Chúng ta sẽ tạo một VPC tuỳ chỉnh có các quy tắc tường lửa, một mạng con và sau đó là một cụm Autopilot. Mở Cloud Console rồi chọn dự án bạn sẽ sử dụng.
- Mở Cloud Shell ở phía trên cùng bên phải của bảng điều khiển, đảm bảo bạn thấy đúng mã dự án trong Cloud Shell, xác nhận mọi lời nhắc để cho phép truy cập.

- Tạo một thư mục có tên là
gke-cnp-lab,rồi chuyển đến thư mục đó.
mkdir -p gke-cnp-lab && cd gke-cnp-lab
- Bây giờ, hãy tạo một số biến. Lưu ý: Chỉnh sửa REGION, ZONE để phản ánh vị trí thực tế nơi bạn có quyền truy cập vào tài nguyên TPU. Giá trị mặc định được dùng trong khu vực
us-west4và vùngus-west4-acủa phòng thí nghiệm
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"
- Lưu các biến cấu hình vào một tập lệnh trợ giúp trong thư mục gke-cnp-lab. Nếu phiên Cloud Shell của bạn bị ngắt kết nối hoặc đặt lại, bạn có thể nhanh chóng khôi phục các biến đang hoạt động bằng cách chạy
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
- Bây giờ, hãy thêm một số tệp cấu hình. Các lệnh này sẽ tạo tệp terraform.tfvars , variables.tf, main.tf sau đây trong thư mục 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
- Đảm bảo bạn đang ở trong thư mục gke-cnp-lab rồi chạy các lệnh sau
terraform initKhởi chạy thư mục đang hoạt động. Đây là bước đầu tiên và bước này sẽ tải các nhà cung cấp cần thiết cho cấu hình đã cho xuống.terraform plan -outtạo một kế hoạch thực thi, cho biết những hành động mà Terraform sẽ thực hiện để triển khai cơ sở hạ tầng của bạn.-outcho phép bạn lưu kế hoạch thực thi vào một tệp nhị phân có tên. Bạn có thể xem điều gì sẽ xảy ra mà không cần thực hiện bất kỳ thay đổi nào.terraform applychạy các bản cập nhật.
terraform init
terraform plan -out cnpgke
- Áp dụng kế hoạch thực thi. Vì bạn đang áp dụng kế hoạch thực thi đã lưu, nên kế hoạch này sẽ thực thi ngay lập tức mà không cần xác nhận (Quá trình này có thể mất từ 6 đến 10 phút)
terraform apply cnpgke
- Xác minh quá trình triển khai cơ sở hạ tầng:
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. Định cấu hình tính năng Ghi nhật ký mạng
Trước khi triển khai khối lượng công việc và chính sách, hãy định cấu hình GKE Network Logging để ghi lại dữ liệu đo từ xa về kết nối và kiểm tra các quyết định dựa trên chính sách trong Cloud Logging.
- Trong thư mục
gke-cnp-lab, hãy tạo tệp kê khai cấu hình 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
- Áp dụng cấu hình cho cụm
kubectl apply -f 00-network-logging.yaml
kubectl get networklogging default
Lưu ý: Bạn có thể thấy cảnh báo cho biết tài nguyên bị thiếu kubectl.kubernetes.io/last-applied-configuration annotation. Điều này hoàn toàn bình thường và đúng như dự kiến! GKE tạo sẵn một đối tượng NetworkLogging mặc định khi cụm khởi động và lệnh kubectl apply chỉ đơn giản là tiếp quản việc quản lý đối tượng đó để áp dụng các quy tắc mới của bạn.
5. Triển khai khối lượng công việc và đầu dò ứng dụng khách của Gemma 4
Bạn sẽ tạo các không gian tên riêng biệt để kiểm thử việc đánh giá chính sách nhiều cấp:
gemma-llm: Chứa khối lượng công việc suy luận chính của Gemma 4 (tier: ai-core).client-ns: Chứa ứng dụng trò chuyện khách RAG được uỷ quyền (tier: app-frontend).untrusted-tenant: Chứa một vùng chứa thăm dò trái phép (tier: untrusted).
- Trong
gke-cnp-lab directory,, hãy tạo tệp kê khai01-namespaces-clients.yamlchứa không gian tên và nhóm máy khách thử nghiệm:
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
- Áp dụng không gian tên và triển khai ứng dụng khách:
kubectl apply -f 01-namespaces-clients.yaml
kubectl get namespaces gemma-llm client-ns untrusted-tenant --show-labels
Triển khai khối lượng công việc vLLM và Gemma
Tạo khoá bí mật Hugging Face. Thay thế YOUR_ACTUAL_HUGGING_FACE_TOKEN bằng mã thông báo của bạn:
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}
- Tạo tệp kê khai khối lượng công việc suy luận Gemma 4 nhắm đến Cloud TPU v5e bằng 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
- Tạo bản triển khai.
kubectl apply -f 02-gemma4-tpu-vllm.yaml
- Để theo dõi trạng thái hoàn tất, hãy chạy tập lệnh sau đây. Các nhóm sẽ đợi cho đến khi nút được cấp phép thì mới có thể tiếp tục, quá trình này có thể mất hơn 13 phút.
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. Tìm hiểu về quy trình đánh giá chính sách và trạng thái mặc định
Trước khi áp dụng chính sách mạng, hãy tìm hiểu cách GKE ClusterNetworkPolicy và NetworkPolicy tiêu chuẩn của Kubernetes tương tác với nhau trên các cấp đánh giá khác nhau.
Lưu lượng truy cập trong GKE được đánh giá thông qua một mô hình ưu tiên nhiều cấp:
Admin Tier ⟶ NetworkPolicy Tier ⟶ Baseline Tier ⟶ Default GKE Behavior

Quy trình kiểm thử của chúng tôi
===================================================
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
===================================================
Thiết lập nền tảng cơ sở (Thử nghiệm trước khi áp dụng chính sách)
Xác minh rằng mô hình Gemma 4 đang hoạt động bình thường và đang phân phát các yêu cầu suy luận. Trong Kubernetes tiêu chuẩn không có chính sách, tất cả lưu lượng truy cập giữa các không gian tên đều được cho phép ngầm định.
- Kiểm tra suy luận từ ứng dụng khách được uỷ quyền trong
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'
- Kiểm thử suy luận từ ứng dụng khách giả mạo trái phép trong
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'
- Kiểm tra xem các nhóm pod trên cả ba không gian tên có thể kết nối với máy chủ siêu dữ liệu (169.254.169.254) hay không:
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. Thử nghiệm đánh giá Cấp cơ sở và Cấp chính sách mạng
Trong bước này, với tư cách là Quản trị viên cụm, bạn sẽ áp dụng Cấp cơ sở ClusterNetworkPolicy để thiết lập trạng thái từ chối mặc định dự phòng trên toàn cụm. Mọi hoạt động giao tiếp giữa các không gian tên không được cấp cao hơn cho phép rõ ràng sẽ bị loại bỏ.
Thiết lập trạng thái không tin tưởng bất cứ điều gì (Cấp cơ sở)
- Tạo tệp kê khai chính sách
03-baseline-deny.yamlCấp cơ sở:
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
- Áp dụng chính sách cấp Cơ bản:
kubectl apply -f 03-baseline-deny.yaml
- Kiểm tra khả năng kết nối của ứng dụng từ
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'
- Kiểm thử suy luận từ ứng dụng khách giả mạo trái phép trong đối tượng thuê không đáng tin cậy:
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'
Uỷ quyền truy cập cho nhà phát triển (Cấp NetworkPolicy)
Giờ đây, nhóm ứng dụng gemma-llm sẽ áp dụng NetworkPolicy theo phạm vi không gian tên tiêu chuẩn để cấp quyền truy cập cho lưu lượng truy cập được uỷ quyền từ client-ns.
- Tạo tệp kê khai
04-app-networkpolicy.yamlNetworkPolicy của nhà phát triển:
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
- Áp dụng chính sách:
kubectl apply -f 04-app-networkpolicy.yaml
- Kiểm tra khả năng kết nối của ứng dụng từ
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'
- Kiểm tra khả năng kết nối từ ứng dụng khách giả mạo trong
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. Chế độ đánh giá sẽ thực thi các Biện pháp bảo vệ chung (Cấp quản trị viên)
Với tư cách là Quản trị viên cụm, giờ đây, bạn sẽ thực thi Cấp quản trị viên ClusterNetworkPolicy ở đầu thứ tự đánh giá của GKE. Cấp này được đánh giá trước tiên, mọi quy tắc phù hợp sẽ được ưu tiên ngay lập tức so với tất cả các cấp khác. Nếu không có kết quả trùng khớp, gói sẽ được chuyển xuống để các cấp thấp hơn (NetworkPolicy và Baseline) đánh giá.
Trong bước này, bạn sẽ áp dụng một chính sách:
- Rào chắn lưu lượng truy cập ra ngoài trên toàn cụm: Chặn tất cả các nhóm trong mọi không gian tên truy cập vào Máy chủ siêu dữ liệu của Google Cloud (
169.254.169.254/32). - Hỗ trợ DNS: Cho phép tất cả lưu lượng truy cập DNS trên cổng 53 để các nhóm có thể phân giải tên máy chủ (tính đến bộ nhớ đệm DNS cục bộ của GKE).
- Uỷ quyền lưu lượng truy cập vào và ra: Chuyển tất cả các quyết định khác về lưu lượng truy cập xuống bằng hành động Chuyển để các chính sách mạng tiêu chuẩn của nhà phát triển và quy tắc từ chối mặc định cơ sở có thể đưa ra quyết định cuối cùng.
- Tạo tệp kê khai chính sách cấp quản trị viên
05-admin-guardrails.yamlnhắm đến tất cả không gian tên
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
- Áp dụng chính sách cấp Quản trị viên:
kubectl apply -f 05-admin-guardrails.yaml
- Kiểm tra hành vi đánh cắp siêu dữ liệu trên cả ba không gian tên:
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)"
- Kiểm tra khả năng kết nối của ứng dụng từ
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'
- Mô phỏng nỗ lực vượt qua của nhà phát triển bằng cách áp dụng NetworkPolicy cho phép tất cả lưu lượng truy cập ra bên ngoài trong 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
- Kiểm tra xem chế độ bỏ qua của nhà phát triển có thể bỏ chặn quyền truy cập vào siêu dữ liệu hay không:
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. Xác minh tương tác bằng Hubble và Cloud Logging
Để quan sát việc thực thi chính sách theo thời gian thực và kiểm tra các quyết định về gói trên cụm, bạn sẽ sử dụng phiên Cloud Shell hai ngăn kết hợp tính năng theo dõi gói eBPF ở cấp nhân hệ điều hành với việc thực thi phiên chạy thử nghiệm tự động.
- Nhấp vào biểu tượng "+" trong trình đơn Cloud Shell để mở thẻ dòng lệnh thứ hai.
- Trong thẻ mới này, hãy chạy các lệnh sau để tạo bí danh và bắt đầu quan sát lưu lượng truy cập trực tiếp cho không gian tên
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
- Chuyển về thẻ Cloud Shell đầu tiên và đảm bảo bạn đang ở trong thư mục
gke-cnp-lab
cd ~/gke-cnp-lab
- Chạy khối sau để tạo và thực thi tập lệnh xác minh tự động. Tập lệnh này chạy các kiểm thử lưu lượng truy cập bắt buộc và truy vấn Cloud Logging bằng giản đồ siêu dữ liệu cấp gốc chính xác của GKE để hiển thị các quy tắc chính xác của Dataplane V2 đã đánh giá các yêu cầu:
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
- Trong khi tập lệnh thực thi trong thẻ đầu tiên, hãy xem kết quả của Hubble trong thẻ thứ hai.
Trong Hubble (Thẻ 2): Bạn sẽ thấy các yêu cầu HTTP được uỷ quyền được CHUYỂN TIẾP bằng màu xanh lục. Đối với lưu lượng truy cập bị chặn, bạn sẽ thấy các sự kiện màu đỏ (BỊ HUỶ). Đối tượng thuê giả mạo: Kết nối được chuyển xuống từ Cấp quản trị và bị chặn ở Cấp cơ sở. Truy vấn siêu dữ liệu: Yêu cầu truy cập thông tin xác thực trên đám mây của truy vấn này bị chặn ngay lập tức ở Cấp quản trị.

Trong Cloud Logging (Thẻ 1): Tập lệnh hoàn tất bằng cách lấy chính xác các bản ghi kiểm tra được gửi đến Google Cloud Logging. Điều này chứng minh rõ ràng Cấp (Quản trị viên hoặc Cơ sở) và Chính sách nào chịu trách nhiệm ngăn chặn lưu lượng truy cập trái phép, được định dạng bằng dấu thời gian được bản địa hoá, nhận biết múi giờ.

10. Dọn dẹp
- Đóng thẻ thứ hai
- Chuyển về thẻ Cloud Shell đầu tiên.
- Xoá tệp kê khai, không gian tên và khoá bí mật Kubernetes đã triển khai theo thứ tự:
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
- Dọn dẹp cơ sở hạ tầng bằng lệnh sau, nhập
yesđể xác nhận
terraform destroy --auto-approve
- Xác minh rằng tất cả tài nguyên đều được chấm dứt hoàn toàn trong dự án đang hoạt động của bạn:
gcloud container clusters list --region=us-west4
gcloud compute networks list
- Xoá thư mục
gke-cnp-labvà nội dung:
cd
rm -r gke-cnp-lab
11. Xin chúc mừng
Bạn đã hoàn thành lớp học lập trình Bảo mật khối lượng công việc suy luận AI bằng ClusterNetworkPolicy của GKE!
Bằng cách hoàn thành lớp học thực hành này, bạn đã thiết kế và xác thực một cấu trúc mạng phòng thủ theo chiều sâu, nhiều tầng và mạnh mẽ để phân phát các khối lượng công việc LLM riêng tư nhạy cảm trên Google Kubernetes Engine.
Thành tích bạn đã đạt được:
- Cơ sở hạ tầng dưới dạng mã: Cung cấp một Cụm GKE tiêu chuẩn riêng tư có độ bảo mật cao, một mạng con riêng tư theo khu vực và phần cứng Cloud TPU v5e chuyên dụng một cách linh động bằng Terraform.
- Đo từ xa và khả năng ghi nhận: Định cấu hình tính năng Ghi nhật ký mạng Dataplane V2 cùng với tính năng theo dõi Hubble eBPF ở cấp nhân để có được khả năng ghi nhận sâu về gói thời gian chạy.
- Hệ thống bảo mật phân cấp: Ví dụ: phân tách rõ ràng nhiệm vụ vận hành giữa 3 cấp đánh giá riêng biệt:
- Cấp quản trị: Các biện pháp bảo vệ dữ liệu đầu ra không thể bỏ qua, được thực thi trên toàn bộ cụm, chặn quyền truy cập thông tin xác thực siêu dữ liệu ngang hàng (169.254.169.254).
- Cấp NetworkPolicy: Ranh giới lưu lượng truy cập vào trong phạm vi không gian tên được uỷ quyền cho nhà phát triển ứng dụng để cho phép kết nối máy khách chính thức một cách an toàn.
- Cấp cơ sở: Xây dựng một mạng lưới an toàn dự phòng trên toàn cụm, từ chối lưu lượng truy cập trái phép của đối tượng thuê theo mặc định.
- Kiểm tra theo thời gian thực: Chạy một bộ kiểm thử xác minh hoàn chỉnh, theo dõi các gói bị rớt theo thời gian thực ở cấp nhân Linux và truy vấn trực tiếp các bản kiểm tra hành động chính sách có cấu trúc trong Google Cloud Logging
Các bước tiếp theo / Tìm hiểu thêm
Bạn có thể đọc thêm về mạng GKE
- Tìm hiểu sâu về Định cấu hình ClusterNetworkPolicy của GKE