GKE ClusterNetworkPolicy ile iş yüklerinin güvenliğini sağlama: Yapay zeka çıkarımı örneği (Gemma, TPU)

1. Genel Bakış

Bu laboratuvarda, Google Kubernetes Engine'deki (GKE) ClusterNetworkPolicy hakkında bilgi edineceksiniz. ClusterNetworkPolicy, çeşitli kullanım alanları için uygulanır ve küme genelinde uygulanıp yönetici ve temel katmanlarda zorunlu kılınabilir. Bu örnekte, TPU'lar, vLLM ve doğrulama ile GKE'de bir LLM dağıtımı (Gemma) kullanarak kontrolü göstereceğiz.

Aşağıdaki teknolojilerle çalışacaksınız:

Roller ve karakterler

Ağ Politikası API'si, belirli kurumsal karakterlere göre yapılandırılmıştır:

  • Küme Yöneticisi kullanımı (ClusterNetworkPolicy): Yönetici ve temel katmanlardaki kümelerde güvenlik önlemlerini uygular.
  • Ad Alanı Yöneticisi kullanımı (NetworkPolicy): Belirli ad alanlarında kiracı düzeyindeki sınırları ve izolasyonu yönetir.
  • Uygulama geliştirici kullanımı (NetworkPolicy): Uygulamaya özel mikro hizmetler için ayrıntılı kurallar tanımlar.

Bu ortamı yapılandırmak için özel bir özel VPC, Cloud NAT ve özel bir GKE kümesi ile özel bir TPU düğüm havuzu dağıtacaksınız.

Kümenizin güvenliğini sağlamak için katı ağ koruma önlemleri uygulamak üzere standart NetworkPolicy nesnelerinin yanı sıra çok katmanlı ClusterNetworkPolicy kaynakları oluşturacaksınız. Ardından,Gemma 4 modelini sunmak için vLLM ve Google Cloud TPU'ları kullanan bir yapay zeka iş yükü dağıtacaksınız.

Son olarak, çalışan bir referans oluşturacak, güvenlik politikalarını uygulayacak ve Cloud Logging ile canlı Hubble eBPF gözlemlenebilirlik akışlarını kullanarak NetworkLogging'i yapılandıracaksınız. Bu sayede, politika kararlarını denetleyebilecek ve paket düşüşlerini doğrulayabileceksiniz. Tüm yapılandırmalarda Terraform, gcloud ve kubectl. kombinasyonu kullanılır.

Bu laboratuvarda, aşağıdaki görevi nasıl gerçekleştireceğinizi öğreneceksiniz:

  • Terraform kullanarak özel ağ, GKE kümesi ve Cloud TPU v5e hızlandırıcıları temel hazırlığı yapma
  • Bağlantı telemetrisini kaydetmek için GKE NetworkLogging'i yapılandırma
  • Resmi vllm/vllm-tpu container görüntüsünü kullanarak Gemma 4 E2B'yi TPU'da dağıtın.
  • Kısıtlamaları uygulamadan önce uçtan uca bağlantıyı kanıtlayan bir çalışma temeli oluşturun.
  • Yetkisiz ad alanları arası trafiği varsayılan olarak reddetmek için Baseline-tier ClusterNetworkPolicy uygulayın.
  • Yetkili istemcilere erişim yetkisi vermek için geliştirici tarafından yönetilen bir NetworkPolicy uygulayın.
  • Geliştirici ayarlarını geçersiz kılan genel çıkış önlemlerini uygulamak için Admin-tier ClusterNetworkPolicy uygulayın.
  • Hubble eBPF akışlarını ve Cloud Logging'i kullanarak canlı paket düşüşlerini ve geçişlerini doğrulama

Bu laboratuvarda aşağıdaki kalıbı oluşturacaksınız.

Şekil 1. dbe5e5f7b35afb8e.jpeg

2. Google Cloud hizmetleri kurulumu

Yönlendirmesiz ortam kurulumu

  1. Google Cloud Console'da oturum açın ve yeni bir proje oluşturun veya mevcut bir projeyi yeniden kullanın. Gmail veya Google Workspace hesabınız yoksa hesap oluşturmanız gerekir.

295004821bab6a87.png37d264871000675d.png96d86d3d5655cdbe.png

  • Proje adı, bu projenin katılımcıları için görünen addır. Google API'leri tarafından kullanılmayan bir karakter dizesidir. Bu bilgiyi dilediğiniz zaman güncelleyebilirsiniz.
  • Proje kimliği, tüm Google Cloud projeleri genelinde benzersizdir ve sabittir (ayarlandıktan sonra değiştirilemez). Cloud Console, benzersiz bir dizeyi otomatik olarak oluşturur. Genellikle bu dizeyi önemsemeniz gerekmez. Çoğu codelab'de proje kimliğinize (genellikle PROJECT_ID olarak tanımlanır) başvurmanız gerekir. Oluşturulan kimliği beğenmezseniz başka bir rastgele kimlik oluşturabilirsiniz. Alternatif olarak, kendi adınızı deneyebilir ve kullanılabilir olup olmadığını görebilirsiniz. Bu adımdan sonra değiştirilemez ve proje süresince geçerli olur.
  • Bilginiz olsun, bazı API'lerin kullandığı üçüncü bir değer olan Proje Numarası da vardır. Bu üç değer hakkında daha fazla bilgiyi belgelerde bulabilirsiniz.
  1. Ardından, Cloud kaynaklarını/API'lerini kullanmak için Cloud Console'da faturalandırmayı etkinleştirmeniz gerekir. Bu codelab'i tamamlamak için çok az ücret ödersiniz veya hiç ödemezsiniz. Bu eğitimden sonra faturalandırma yapılmaması için kaynakları kapatmak istiyorsanız oluşturduğunuz kaynakları veya projeyi silebilirsiniz. Yeni Google Cloud kullanıcıları 300 ABD doları değerinde ücretsiz deneme programından yararlanabilir.

Cloud Shell'i başlatma

Google Cloud'u dizüstü bilgisayarınızdan uzaktan çalıştırabilirsiniz ancak bu codelab'de, Cloud'da çalışan bir komut satırı ortamı olan Google Cloud Shell'i kullanacaksınız.

Google Cloud Console'da, sağ üstteki araç çubuğunda bulunan Cloud Shell simgesini tıklayın:

Cloud Shell'i etkinleştirme

Birkaç saniye içinde ortamın temel hazırlığı yapılır ve bağlantı kurulur. İşlem tamamlandığında şuna benzer bir şey görürsünüz:

Ortamın bağlandığını gösteren Google Cloud Shell terminalinin ekran görüntüsü

Bu sanal makine, ihtiyaç duyacağınız tüm geliştirme araçlarıyla yüklüdür. 5 GB boyutunda kalıcı bir ana dizin bulunur ve Google Cloud'da çalışır. Bu sayede ağ performansı ve kimlik doğrulama önemli ölçüde güçlenir. Bu codelab'deki tüm çalışmalarınızı tarayıcıda yapabilirsiniz. Herhangi bir şey yüklemeniz gerekmez.

3. Terraform ile ortam oluşturma

Bu laboratuvarı tamamlamak için:

  • Seçtiğiniz bölge ve alt bölgede (ör. us-central1-a, us-west4-a, us-south1-a, us-west1-c, europe-west4-b) TPU v5e kotasına erişiminiz olmalıdır. Erişim elde etmek için TPU planı belgesini inceleyip TPU kotasını etkinleştirmeniz gerekir.
  • Bu, tek bir alt bölgede 2x2 dilim oluşturacak 4 TPU v5e çipi (ct5lp-hightpu-4t),) gerektiren küçük bir dağıtımdır.

Hugging Face'i kullanmak için

  • Hugging Face jetonu: Gemma model ağırlıklarını indirmek için erişim jetonu gerekir.
  • Gerekirse kullanım sözleşmesini kabul edin.

Güvenlik duvarı kuralları, alt ağ ve Autopilot kümesi içeren özel bir VPC oluşturacağız. Cloud Console'u açın ve kullanacağınız projeyi seçin.

  1. Konsolunuzun sağ üst kısmında bulunan Cloud Shell'i açın. Cloud Shell'de doğru proje kimliğini gördüğünüzden emin olun ve erişime izin vermenizi isteyen tüm istemleri onaylayın. b51b80043d3bac90.png
  2. gke-cnp-lab, adlı bir dizin oluşturun ve bu dizine gidin.
mkdir -p gke-cnp-lab && cd gke-cnp-lab
  1. Şimdi bazı değişkenler oluşturun. Not: REGION ve ZONE değerlerini, TPU kaynaklarına erişiminiz olan gerçek konumu yansıtacak şekilde düzenleyin. Laboratuvar bölgesi us-west4 ve alt bölgesi us-west4-a için kullanılan varsayılan değer
export PROJECT_ID=$(gcloud config get-value project)
export REGION="us-west4"
export ZONE="us-west4-a"
export NETWORK="cnp-demo-vpc"
export SUBNET="cnp-main-subnet"
export CLUSTER_NAME="cnp-demo-cluster"
  1. Yapılandırma değişkenlerinizi gke-cnp-lab dizinindeki bir yardımcı komut dosyasına kaydedin. Cloud Shell oturumunuzun bağlantısı kesilir veya oturum sıfırlanırsa source ./env.sh komutunu çalıştırarak etkin değişkenlerinizi hızlıca geri yükleyebilirsiniz.
cat << EOF > env.sh
export PROJECT_ID="${PROJECT_ID}"
export REGION="${REGION}"
export ZONE="${ZONE}"
export NETWORK="${NETWORK}"
export SUBNET="${SUBNET}"
export CLUSTER_NAME="${CLUSTER_NAME}"

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

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

chmod +x env.sh
source ./env.sh
  1. Şimdi bazı yapılandırma dosyaları ekleyin. Bu komutlar, gke-cnp-lab dizininde şu dosyaları oluşturur: terraform.tfvars, variables.tf, main.tf.
cat << EOF > terraform.tfvars
project_id   = "${PROJECT_ID}"
region       = "${REGION}"
zone         = "${ZONE}"
network_name = "${NETWORK}"
subnet_name  = "${SUBNET}"
cluster_name = "${CLUSTER_NAME}"
EOF

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  datapath_provider = "ADVANCED_DATAPATH"

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

  release_channel {
    channel = "RAPID"
  }

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

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

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

  deletion_protection = false
}

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

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

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

    taint {
      key    = "google.com/tpu"
      value  = "present"
      effect = "NO_SCHEDULE"
    }
  }
}
EOF
  1. gke-cnp-lab dizininde olduğunuzdan emin olun ve aşağıdaki komutları çalıştırın
    terraform init Çalışma dizinini başlatır. Bu ilk adımdır ve verilen yapılandırma için gereken sağlayıcıları indirir.
    terraform plan -out, Terraform'un altyapınızı dağıtmak için gerçekleştireceği işlemleri gösteren bir yürütme planı oluşturur. -out, yürütme planını adlandırılmış bir ikili dosyaya kaydetmenize olanak tanır. Herhangi bir değişiklik yapmadan ne olacağını görebilirsiniz.
    terraform apply güncellemeleri çalıştırır.
terraform init 
terraform plan -out cnpgke 
  1. Yürütme planını uygulayın. Kaydedilen yürütme planını uyguladığınız için onay istenmeden hemen yürütülür (Bu işlem 6-10 dakika sürebilir).
terraform apply cnpgke
  1. Altyapı dağıtımınızı doğrulayın:
gcloud container clusters get-credentials ${CLUSTER_NAME} --region ${REGION} --project=${PROJECT_ID}
echo -e "\n=== Verifying Cluster Nodes ==="
kubectl get nodes -L cloud.google.com/gke-tpu-accelerator,cloud.google.com/gke-tpu-topology

8b187e355548b7c5.png

4. Ağ Günlük Kaydı'nı yapılandırma

İş yüklerini ve politikaları dağıtmadan önce, bağlantı telemetrisini ve denetim politikası kararlarını Cloud Logging'e kaydetmek için GKE Ağ Günlüğü'nü yapılandırın.

  1. gke-cnp-lab dizininde NetworkLogging yapılandırma manifestini oluşturun.
cat << 'EOF' > 00-network-logging.yaml
apiVersion: networking.gke.io/v1alpha1
kind: NetworkLogging
metadata:
  name: default
spec:
  cluster:
    allow:
      delegate: false
      log: true
    deny:
      delegate: false
      log: true
EOF
  1. Yapılandırmayı kümeye uygulama
kubectl apply -f 00-network-logging.yaml
kubectl get networklogging default

Not: Kaynakta kubectl.kubernetes.io/last-applied-configuration annotation. eksik olduğunu belirten bir uyarı görebilirsiniz. Bu tamamen normal ve beklenen bir durumdur. GKE, küme başlatıldığında varsayılan bir NetworkLogging nesnesini önceden oluşturur ve kubectl apply, yeni kurallarınızı uygulamak için bu nesnenin yönetimini devralır.

5. Gemma 4 İş Yükü ve İstemci Problarını Dağıtma

Çok katmanlı politika değerlendirmelerini test etmek için izole ad alanları oluşturacaksınız:

  • gemma-llm: Temel Gemma 4 çıkarım iş yükünü (tier: ai-core) barındırır.
  • client-ns: Yetkili RAG sohbet istemcisini (tier: app-frontend) barındırır.
  • untrusted-tenant: Yetkisiz bir araştırma kapsayıcısı (tier: untrusted) barındırıyor.
  1. gke-cnp-lab directory, içinde, ad alanlarını ve test istemcisi kapsüllerini içeren 01-namespaces-clients.yaml manifestini oluşturun:
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
  • Ad alanlarını ve istemci dağıtımlarını uygulayın:
kubectl apply -f 01-namespaces-clients.yaml
kubectl get namespaces gemma-llm client-ns untrusted-tenant --show-labels

İş yükü vLLM ve Gemma'yı dağıtma

Hugging Face gizli anahtarınızı oluşturun. YOUR_ACTUAL_HUGGING_FACE_TOKEN ifadesini kendi jetonunuzla değiştirin:

export HF_TOKEN="YOUR_ACTUAL_HUGGING_FACE_TOKEN"
echo $HF_TOKEN
kubectl create secret generic hf-secret -n gemma-llm --from-literal=hf_token=${HF_TOKEN}
  1. vllm-tpu kullanarak Cloud TPU v5e'yi hedefleyen Gemma 4 çıkarım iş yükü manifestini oluşturun:
cat << 'EOF' > 02-gemma4-tpu-vllm.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gemma-serving
  namespace: gemma-llm
  labels:
    app: gemma-service
spec:
  replicas: 1
  selector:
    matchLabels:
      app: gemma-service
  template:
    metadata:
      labels:
        app: gemma-service
        ai.gke.io/model: gemma4
        ai.gke.io/inference-server: vllm-tpu
    spec:
      tolerations:
        - key: "google.com/tpu"
          operator: "Exists"
          effect: "NoSchedule"
      nodeSelector:
        cloud.google.com/gke-tpu-accelerator: tpu-v5-lite-podslice
        cloud.google.com/gke-tpu-topology: 2x2
      containers:
        - name: vllm-inference
          image: vllm/vllm-tpu:latest
          command: ["python3", "-m", "vllm.entrypoints.openai.api_server"]
          args:
            - "--model=google/gemma-4-E2B-it"
            - "--tensor-parallel-size=4"
            - "--host=0.0.0.0"
            - "--port=8000"
            - "--max-model-len=4096"
            - "--max-num-batched-tokens=4096"
          env:
            - name: HF_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_token
            - name: HUGGING_FACE_HUB_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_token
          volumeMounts:
            - mountPath: /dev/shm
              name: dshm
          ports:
            - name: http-inference
              containerPort: 8000
          resources:
            requests:
              google.com/tpu: "4"
              memory: "32Gi"
              cpu: "8"
            limits:
              google.com/tpu: "4"
              memory: "32Gi"
              cpu: "8"
          startupProbe:
            httpGet:
              path: /health
              port: 8000
            failureThreshold: 120
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /health
              port: 8000
            periodSeconds: 5
      volumes:
        - name: dshm
          emptyDir:
            medium: Memory
---
apiVersion: v1
kind: Service
metadata:
  name: gemma-service
  namespace: gemma-llm
spec:
  type: ClusterIP
  selector:
    app: gemma-service
  ports:
    - name: http
      protocol: TCP
      port: 8000
      targetPort: 8000
EOF
  1. Dağıtımı oluşturun.
kubectl apply -f 02-gemma4-tpu-vllm.yaml
  1. Tamamlanma durumunu izlemek için aşağıdaki komut dosyasını çalıştırın. Pod'lar, düğümün temel hazırlığı tamamlanana kadar bekler. Bu işlem 13 dakikadan uzun sürebilir.
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. Politika Değerlendirmesi ve Varsayılan Durum Hakkında Bilgi

Ağ politikalarını uygulamadan önce GKE ClusterNetworkPolicy ve standart Kubernetes NetworkPolicy'nin farklı değerlendirme katmanlarında nasıl etkileşim kurduğunu anlayın.

GKE'deki trafik, çok katmanlı bir öncelik modeliyle değerlendirilir:

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

d4cf83398c69b6b8.png

Test akışımız

===================================================
           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
===================================================

Temel Altyapıyı Oluşturma (Politika Öncesi Test)

Gemma 4 modelinin sorunsuz çalıştığını ve çıkarım isteklerini karşıladığını doğrulayın. Politika içermeyen standart Kubernetes'te, tüm ad alanları arası trafiğe dolaylı olarak izin verilir.

  1. client-ns içinde yetkili istemciden çıkarımı test edin:
kubectl exec -n client-ns deploy/rag-agent-client -- curl --connect-timeout 3 -s -X POST \
  http://gemma-service.gemma-llm.svc.cluster.local:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemma-4-E2B-it",
    "messages": [{"role": "user", "content": "Explain zero trust in one short sentence."}],
    "max_tokens": 40
  }' | jq -r '.choices[0].message.content'
  1. untrusted-tenant içinde yetkisiz hileli istemciden çıkarım testi:
kubectl exec -n untrusted-tenant deploy/rogue-client -- curl --connect-timeout 3 -s -X POST \
  http://gemma-service.gemma-llm.svc.cluster.local:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemma-4-E2B-it",
    "messages": [{"role": "user", "content": "Explain zero trust in one short sentence."}],
    "max_tokens": 40
  }' | jq -r '.choices[0].message.content'
  1. Üç ad alanındaki pod'ların meta veri sunucusuna (169.254.169.254) ulaşıp ulaşamadığını test edin:
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. Değerlendirme testi: Temel ve ağ politikası katmanı

Bu adımda, Küme Yöneticisi olarak, küme genelinde yedek varsayılan reddetme duruşu oluşturmak için Temel katman ClusterNetworkPolicy uygulayacaksınız. Daha yüksek bir katman tarafından açıkça izin verilmeyen tüm ad alanları arası iletişimler silinir.

Sıfır Güven Durumu Oluşturma (Temel Kademe)

  1. 03-baseline-deny.yaml Temel katman politika manifestini oluşturun:
cat << 'EOF' > 03-baseline-deny.yaml
apiVersion: policy.networking.k8s.io/v1alpha2
kind: ClusterNetworkPolicy
metadata:
  name: baseline-default-deny
spec:
  tier: Baseline
  priority: 1000
  subject:
    namespaces: {}
  ingress:
    # 1. Allow CoreDNS Ingress cluster-wide so DNS resolution never breaks
    - name: allow-dns-ingress
      action: Accept
      from:
        - namespaces: {}
      protocols:
        - udp:
            destinationPort:
              number: 53
        - tcp:
            destinationPort:
              number: 53
    # 2. Default Deny all other cross-namespace ingress
    - name: baseline-deny-cross-ns
      action: Deny
      from:
        - namespaces: {}
EOF
  1. Baseline katman politikasını uygulayın:
kubectl apply -f 03-baseline-deny.yaml
  1. client-ns. üzerinden istemci bağlantısını test etme
kubectl exec -n client-ns deploy/rag-agent-client -- curl --connect-timeout 3 -s -X POST \
  http://gemma-service.gemma-llm.svc.cluster.local:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemma-4-E2B-it",
    "messages": [{"role": "user", "content": "Explain zero trust in one short sentence."}],
    "max_tokens": 40
  }' | jq -r '.choices[0].message.content'
  1. Güvenilmeyen kiracıdaki yetkisiz sahte istemciden çıkarım testi:
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'

Geliştiricilere Erişim Yetkisi Verme (NetworkPolicy Katmanı)

gemma-llm uygulama ekibi, client-ns'den gelen yetkili trafiğe izin vermek için standart bir ad alanı kapsamlı NetworkPolicy uygulayacak.

  1. Geliştirici 04-app-networkpolicy.yaml NetworkPolicy manifestini oluşturun:
cat << 'EOF' > 04-app-networkpolicy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-rag-client
  namespace: gemma-llm
spec:
  podSelector:
    matchLabels:
      app: gemma-service
  policyTypes:
    - Ingress
  ingress:
    # Explicitly permit ingress only from pods matching app: rag-agent in client-ns
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: client-ns
          podSelector:
            matchLabels:
              app: rag-agent
      ports:
        - protocol: TCP
          port: 8000
EOF
  1. Politikayı uygulayın:
kubectl apply -f 04-app-networkpolicy.yaml
  1. client-ns üzerinden istemci bağlantısını test etme
kubectl exec -n client-ns deploy/rag-agent-client -- curl --connect-timeout 3 -s -X POST \
  http://gemma-service.gemma-llm.svc.cluster.local:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemma-4-E2B-it",
    "messages": [{"role": "user", "content": "Explain zero trust in one short sentence."}],
    "max_tokens": 40
  }' | jq -r '.choices[0].message.content'
  1. untrusted-tenant içinde hileli istemciden bağlantıyı test edin:
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. Değerlendirme, Global Guardrails'i (Yönetici katmanı) zorunlu kılar

Küme Yöneticisi olarak,GKE'nin değerlendirme sırasının en üstünde bir Yönetici katmanı ClusterNetworkPolicy uygulayacaksınız. Önce bu katman değerlendirilir ve eşleşen tüm kurallar diğer tüm katmanlara göre öncelikli olur. Eşleşme yoksa paket, alt katmanlar (NetworkPolicy ve Baseline) tarafından değerlendirilmek üzere aşağı aktarılır.

Bu adımda, aşağıdaki işlemleri yapan bir politika uygulayacaksınız:

  • Küme genelinde çıkış koruma önlemi: Her ad alanındaki tüm pod'ların Google Cloud Metadata Server'a (169.254.169.254/32) erişmesini engeller.
  • DNS Desteği: Pod'ların ana makine adlarını çözümleyebilmesi için 53 numaralı bağlantı noktasındaki tüm DNS trafiğine izin verir (GKE'nin yerel DNS önbelleklerini hesaba katar).
  • Giriş ve Çıkış Yetkilendirmesi: Geçiş işlemini kullanarak diğer tüm trafik kararlarını aşağı aktarır. Böylece standart geliştirici ağ politikaları ve temel varsayılan reddetme kuralları nihai kararları verebilir.
  1. Tüm ad alanlarını hedefleyen 05-admin-guardrails.yaml yönetici katmanı politika manifestini oluşturun.
cat << 'EOF' > 05-admin-guardrails.yaml
apiVersion: policy.networking.k8s.io/v1alpha2
kind: ClusterNetworkPolicy
metadata:
  name: admin-global-guardrails
spec:
  tier: Admin
  priority: 10
  subject:
    namespaces: {}
  ingress:
    - name: delegate-all-ingress
      action: Pass
      from:
        - namespaces: {}
  egress:
    - name: allow-all-dns
      action: Accept
      to:
        - networks:
            - 0.0.0.0/0
      protocols:
        - udp:
            destinationPort:
              number: 53
        - tcp:
            destinationPort:
              number: 53
    - name: block-metadata-server-global
      action: Deny
      to:
        - networks:
            - 169.254.169.254/32
    - name: delegate-other-egress
      action: Pass
      to:
        - namespaces: {}
EOF
  1. Yönetici katmanı politikasını uygulayın:
kubectl apply -f 05-admin-guardrails.yaml
  1. Üç ad alanında da meta veri hırsızlığını test edin:
echo -e "\n[1/3] Testing Metadata access from Gemma serving pod (gemma-llm)..."
kubectl exec -n gemma-llm deploy/gemma-serving -- curl --connect-timeout 3 -s -w "\nHTTP Code: %{http_code}\n" -H "Metadata-Flavor: Google" \
  http://169.254.169.254/computeMetadata/v1/instance/zone || echo "🛑 RESULT: Connection Timed Out (Blocked)"

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

echo -e "\n[3/3] Testing Metadata access from rogue client (untrusted-tenant)..."
kubectl exec -n untrusted-tenant deploy/rogue-client -- curl --connect-timeout 3 -s -w "\nHTTP Code: %{http_code}\n" -H "Metadata-Flavor: Google" \
  http://169.254.169.254/computeMetadata/v1/instance/zone || echo "🛑 RESULT: Connection Timed Out (Blocked)"
  1. client-ns üzerinden istemci bağlantısını test etme
kubectl exec -n client-ns deploy/rag-agent-client -- curl --connect-timeout 3 -s -X POST \
  http://gemma-service.gemma-llm.svc.cluster.local:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemma-4-E2B-it",
    "messages": [{"role": "user", "content": "Explain zero trust in one short sentence."}],
    "max_tokens": 40
  }' | jq -r '.choices[0].message.content'
  1. gemma-llm içinde tüm çıkışlara izin veren bir NetworkPolicy uygulayarak geliştiricinin atlatma girişimini simüle edin:
cat << 'EOF' > 06-bypass-attempt.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: dev-allow-all-egress
  namespace: gemma-llm
spec:
  podSelector: {}
  policyTypes:
    - Egress
  egress:
    - {}
EOF

kubectl apply -f 06-bypass-attempt.yaml
  1. Geliştirici bypass'ının meta veri erişiminin engellemesini kaldırıp kaldıramayacağını test edin:
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 ve Cloud Logging ile Etkileşimli Doğrulama

Kümeniz genelinde gerçek zamanlı politika yaptırımını ve denetim paketi kararlarını gözlemlemek için çekirdek düzeyinde eBPF paketi izlemeyi otomatik test yürütmeyle birleştiren çift bölmeli bir Cloud Shell oturumu kullanacaksınız.

  1. Cloud Shell menünüzdeki "+" simgesini tıklayarak ikinci bir terminal sekmesi açın.
  2. Bu yeni sekmede, takma adı oluşturmak ve gemma-llm ad alanı için canlı trafiği gözlemlemeye başlamak üzere aşağıdaki komutları çalıştırın:
# Create an alias to execute Hubble natively inside the relay pod
alias hubble="kubectl exec -it -n gke-managed-dpv2-observability deploy/hubble-relay -c hubble-cli -- hubble"

# Observe real-time traffic to and from the Gemma namespace
hubble observe --follow --namespace gemma-llm
  1. İlk Cloud Shell sekmenize geri dönün ve gke-cnp-lab dizininde olduğunuzdan emin olun.
cd ~/gke-cnp-lab
  1. Otomatik doğrulama komut dosyasını oluşturup çalıştırmak için aşağıdaki bloğu çalıştırın. Bu komut dosyası, gerekli trafik testlerini çalıştırır ve istekleri değerlendiren tam Dataplane V2 kurallarını görüntülemek için GKE'nin tam kök düzeyindeki meta veri şemasını kullanarak Cloud Logging'i sorgular:
cat << 'EOF' > verify-suite.sh
#!/usr/bin/env bash
set -e

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

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

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

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

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

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

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

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

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

chmod +x verify-suite.sh
./verify-suite.sh
  1. Komut dosyası ilk sekmenizde yürütülürken ikinci sekmenizde Hubble çıkışını izleyin.

Hubble'da (Sekme 2): Yetkilendirilmiş HTTP isteklerinin yeşil renkte YÖNLENDİRİLDİĞİNİ görürsünüz. Engellenen trafik için kırmızı (DROPPED) etkinlikler görürsünüz. The Rogue Tenant: Bağlantı, Yönetici Katmanı tarafından iletilir ve Temel Katman'da engellenir. Meta Veri Sorgusu: Bulut kimlik bilgilerine erişme isteği, Yönetici Katmanı'nda hemen engellenir.

7d68cc0e9b90f820.png

Cloud Logging'de (1. sekme): Komut dosyası, Google Cloud Logging'e gönderilen denetleme kayıtlarının aynısını çekerek işlemi tamamlar. Bu, yetkisiz trafiği durdurmaktan hangi katmanın (Yönetici veya Temel) ve hangi politikanın sorumlu olduğunu açıkça kanıtlar. Bu bilgiler, yerelleştirilmiş ve saat dilimine duyarlı zaman damgalarıyla biçimlendirilir.

b9e48fd473451ca2.png

10. Temizleme

  1. İkinci sekmeyi kapatın.
  2. İlk Cloud Shell sekmenize geri dönün.
  3. Dağıtılan Kubernetes manifest'lerini, ad alanlarını ve gizli anahtarları sırayla silin:
cd ~/gke-cnp-lab

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

# Delete workload deployments, secrets, and namespaces
kubectl delete -f 02-gemma4-tpu-vllm.yaml --ignore-not-found
kubectl delete secret hf-secret -n gemma-llm --ignore-not-found
kubectl delete -f 01-namespaces-clients.yaml --ignore-not-found
  1. Aşağıdaki komutu kullanarak altyapıyı temizleyin ve onaylamak için yes yazın.
terraform destroy --auto-approve
  1. Etkin projenizdeki tüm kaynakların tamamen sonlandırıldığını doğrulayın:
gcloud container clusters list --region=us-west4
gcloud compute networks list
  1. gke-cnp-lab dizinini ve içeriğini silin:
cd
rm -r gke-cnp-lab

11. Tebrikler

GKE ClusterNetworkPolicy ile Güvenli Yapay Zeka Çıkarımı İş Yükleri codelab'ini başarıyla tamamladınız.

Bu uygulamalı laboratuvarı tamamlayarak Google Kubernetes Engine'de hassas özel LLM iş yüklerini sunmak için sağlam, çok katmanlı ve derinlemesine savunma sağlayan bir ağ mimarisi tasarlayıp doğruladınız.

Başardıklarınız:

  • Kod olarak altyapı: Terraform'u kullanarak son derece güvenli bir özel standart GKE kümesi, özel bir bölgesel alt ağ ve özel Cloud TPU v5e donanımını dinamik olarak temel hazırlıkla oluşturduk.
  • Telemetri ve Gözlemlenebilirlik: Çalışma zamanında paket görünürlüğünü artırmak için Dataplane V2 Ağ Günlüğü'nü çekirdek düzeyinde eBPF Hubble izleme ile birlikte yapılandırdı.
  • Hiyerarşik Güvenlik Durumu: Örneğin, operasyonel görevlerin üç farklı değerlendirme katmanında net bir şekilde ayrılması:
  • Yönetici Katmanı: Küme genelinde zorunlu kılınan, atlanamayan çıkış güvenlik önlemleri, yanal meta veri kimlik bilgisi erişimini (169.254.169.254) engeller.
  • NetworkPolicy katmanı: Üretim istemci bağlantılarını güvenli bir şekilde yetkilendirmek için uygulama geliştiricilere yetki verilmiş ad alanı kapsamlı giriş sınırları.
  • Temel Katman: Yetkisiz kiracı trafiğini varsayılan olarak reddeden, küme genelinde bir yedek güvenlik ağı oluşturuldu.
  • Gerçek zamanlı denetim: Tam bir doğrulama testi paketi çalıştırın, Linux çekirdeği düzeyinde gerçek zamanlı paket düşüşlerini izleyin ve yapılandırılmış politika işlemi denetimlerini doğrudan Google Cloud Logging'de sorgulayın.

Sonraki adımlar / Daha fazla bilgi

GKE ağı hakkında daha fazla bilgi edinebilirsiniz.