টিপিইউ, ক্লাউড স্টোরেজ ফিউজ এবং পরিচালিত ড্রনেট সহ মাল্টি-ক্লাস্টার জিকেই ইনফারেন্স গেটওয়ে তৈরি করুন।

১. সংক্ষিপ্ত বিবরণ

এই ল্যাবটি আপনাকে এআই ইনফ্রাস্ট্রাকচারের সাথে পরিচয় করিয়ে দেবে, যা এআই ওয়ার্কলোড চালানোর জন্য ব্যবহার করা যেতে পারে। আপনি নিম্নলিখিত বিষয়গুলো নিয়ে কাজ করবেন:

গুগল কুবারনেটিস ইঞ্জিন (GKE) - কন্টেইনার অর্কেস্ট্রেশনের মূল প্ল্যাটফর্ম।

GKE পরিচালিত DRANET — ডাইনামিক রিসোর্স অ্যালোকেশন নেটওয়ার্কিং, যা সরাসরি আপনার TPU পডগুলিতে উচ্চ-গতির ইন্টারকানেক্ট ফ্যাব্রিক বরাদ্দ করে।

GKE ইনফারেন্স গেটওয়ে - এটি গুগল ক্লাউডের একটি পরিচালিত গেটওয়ে অবজেক্ট যা ইনফারেন্সের জন্য অভিযোজিত। এক্ষেত্রে আমরা এর মাল্টি-ক্লাস্টার সক্ষমতা ব্যবহার করব।

টেনসর প্রসেসিং ইউনিট (টিপিইউ) - গুগলের নিজস্বভাবে নির্মিত অ্যাক্সিলারেটর চিপ।

ক্লাউড স্টোরেজ ফিউজ - একটি স্টোরেজ ইন্টারফেস যা পডগুলিকে সরাসরি ক্লাউড স্টোরেজ বাকেট মাউন্ট করার সুযোগ দেয়, যার ফলে বিশাল আকারের মডেল ওয়েট তাৎক্ষণিকভাবে লোড করা যায়।

কনফিগার করার জন্য আপনাকে একটি কাস্টম ভিপিসি (VPC), একটি ক্লাউড স্টোরেজ বাকেট এবং দুটি ভিন্ন অঞ্চলে দুটি ক্লাস্টার স্থাপন করতে হবে। প্রতিটি ক্লাস্টারের নেটওয়ার্কিংয়ের জন্য ম্যানেজড ড্রনেট (DRANET) ব্যবহার করে একটি টিপিইউ নোডপুল (TPU nodepool) থাকবে। ক্লাস্টারগুলোকে একটি ফ্লিটে (Fleet ) যুক্ত করার পর, আপনি আপনার বাকেটে জেমা মডেলের ওয়েটগুলো (Gemma model weights) ক্যাশ করবেন এবং একটি ভিএলএলএম (vLLM) ওয়ার্কলোড স্থাপন করবেন যা ক্লাউড স্টোরেজ ফিউজের (Cloud Storage FUSE) মাধ্যমে তাৎক্ষণিকভাবে সেই ওয়েটগুলো মাউন্ট (mount) করবে। সবশেষে, ট্র্যাফিক রাউট করার জন্য জিকেই ইনফারেন্স গেটওয়ে (GKE Inference Gateway) কনফিগার করা হবে, যা আপনাকে একটি লাইভ ক্রস-রিজিওনাল ফেইলওভার পরীক্ষা করার সুযোগ দেবে।

কনফিগারেশনগুলোতে Terraform , gcloud এবং kubectl এর সমন্বয় ব্যবহার করা হবে।

এই ল্যাবে তোমরা নিম্নলিখিত কাজটি কীভাবে সম্পাদন করতে হয় তা শিখবে:

  • ভিপিসি, নেটওয়ার্ক, স্টোরেজ সেট আপ করুন
  • স্ট্যান্ডার্ড মোডে GKE ক্লাস্টার সেট আপ করুন
  • TPU নোডপুল তৈরি করুন এবং পরিচালিত DRANET ব্যবহার করুন
  • ফ্লিটে ক্লাস্টার যোগ করুন
  • ক্যাশে মডেলের ওজন
  • মাল্টি-ক্লাস্টার GKE ইনফারেন্স গেটওয়ে সেটআপ করুন এবং ফেইলওভার পরীক্ষা করুন

এই ল্যাবে, আপনারা নিম্নলিখিত প্যাটার্নটি তৈরি করবেন।

চিত্র ১।

52b36edd128f9ffa.png

২. গুগল ক্লাউড পরিষেবা সেটআপ

স্ব-গতিতে পরিবেশ সেটআপ

  1. Google Cloud Console- এ সাইন-ইন করুন এবং একটি নতুন প্রজেক্ট তৈরি করুন অথবা বিদ্যমান কোনো প্রজেক্ট পুনরায় ব্যবহার করুন। যদি আপনার আগে থেকে Gmail বা Google Workspace অ্যাকাউন্ট না থাকে, তবে আপনাকে অবশ্যই একটি তৈরি করতে হবে।

295004821bab6a87.png

37d264871000675d.png

96d86d3d5655cdbe.png

  • প্রজেক্টের নামটি হলো এই প্রজেক্টের অংশগ্রহণকারীদের প্রদর্শিত নাম। এটি একটি ক্যারেক্টার স্ট্রিং যা গুগল এপিআই ব্যবহার করে না। আপনি যেকোনো সময় এটি আপডেট করতে পারেন।
  • প্রজেক্ট আইডি সমস্ত গুগল ক্লাউড প্রজেক্ট জুড়ে অনন্য এবং অপরিবর্তনীয় (একবার সেট করার পর এটি পরিবর্তন করা যায় না)। ক্লাউড কনসোল স্বয়ংক্রিয়ভাবে একটি অনন্য স্ট্রিং তৈরি করে; সাধারণত এটি কী তা নিয়ে আপনার মাথা ঘামানোর দরকার নেই। বেশিরভাগ কোডল্যাবে, আপনাকে আপনার প্রজেক্ট আইডি উল্লেখ করতে হবে (যা সাধারণত PROJECT_ID হিসাবে চিহ্নিত করা হয়)। তৈরি করা আইডিটি আপনার পছন্দ না হলে, আপনি এলোমেলোভাবে আরেকটি তৈরি করতে পারেন। বিকল্পভাবে, আপনি আপনার নিজের আইডি দিয়ে চেষ্টা করে দেখতে পারেন যে সেটি উপলব্ধ আছে কিনা। এই ধাপের পরে এটি পরিবর্তন করা যাবে না এবং প্রজেক্টের পুরো সময়কাল জুড়ে এটি অপরিবর্তিত থাকবে।
  • আপনার অবগতির জন্য জানানো যাচ্ছে যে, তৃতীয় একটি ভ্যালু রয়েছে, যা হলো প্রজেক্ট নম্বর , এবং কিছু এপিআই এটি ব্যবহার করে থাকে। ডকুমেন্টেশনে এই তিনটি ভ্যালু সম্পর্কে আরও বিস্তারিত জানুন।
  1. এরপর, ক্লাউড রিসোর্স/এপিআই ব্যবহার করার জন্য আপনাকে ক্লাউড কনসোলে বিলিং চালু করতে হবে। এই কোডল্যাবটি সম্পন্ন করতে খুব বেশি খরচ হবে না, এমনকি আদৌ কোনো খরচ নাও হতে পারে। এই টিউটোরিয়ালের পর বিলিং এড়াতে রিসোর্সগুলো বন্ধ করার জন্য, আপনি আপনার তৈরি করা রিসোর্সগুলো অথবা প্রজেক্টটি ডিলিট করে দিতে পারেন। নতুন গুগল ক্লাউড ব্যবহারকারীরা ৩০০ মার্কিন ডলারের ফ্রি ট্রায়াল প্রোগ্রামের জন্য যোগ্য।

ক্লাউড শেল শুরু করুন

যদিও গুগল ক্লাউড আপনার ল্যাপটপ থেকে দূরবর্তীভাবে পরিচালনা করা যায়, এই কোডল্যাবে আপনি গুগল ক্লাউড শেল ব্যবহার করবেন, যা ক্লাউডে চলমান একটি কমান্ড লাইন পরিবেশ।

গুগল ক্লাউড কনসোল থেকে, উপরের ডানদিকের টুলবারে থাকা ক্লাউড শেল আইকনটিতে ক্লিক করুন:

ক্লাউড শেল সক্রিয় করুন

পরিবেশটি প্রস্তুত করতে এবং এর সাথে সংযোগ স্থাপন করতে মাত্র কয়েক মুহূর্ত সময় লাগবে। এটি শেষ হলে, আপনি এইরকম কিছু দেখতে পাবেন:

গুগল ক্লাউড শেল টার্মিনালের স্ক্রিনশট, যা দেখাচ্ছে যে পরিবেশটি সংযুক্ত হয়েছে।

এই ভার্চুয়াল মেশিনটিতে আপনার প্রয়োজনীয় সমস্ত ডেভেলপমেন্ট টুলস লোড করা আছে। এটি একটি স্থায়ী ৫ জিবি হোম ডিরেক্টরি প্রদান করে এবং গুগল ক্লাউডে চলে, যা নেটওয়ার্ক পারফরম্যান্স ও অথেনটিকেশনকে ব্যাপকভাবে উন্নত করে। এই কোডল্যাবে আপনার সমস্ত কাজ একটি ব্রাউজারের মধ্যেই করা যাবে। আপনাকে কিছুই ইনস্টল করতে হবে না।

৩. টেরাফর্ম দিয়ে পরিবেশ সেটআপ করুন

এই ল্যাবটি করার জন্য আপনার টিপিইউ ব্যবহারের সুযোগ প্রয়োজন। ব্যবহৃত নির্দিষ্ট সংস্করণটি হলো টিপিইউ ভি৬ই।

  • অ্যাক্সেস পেতে আপনাকে টিপিইউ প্ল্যান ডকুমেন্টটি অনুসরণ করতে হবে এবং টিপিইউ কোটা সক্রিয় করতে হবে
  • আমরা একটি ছোট আকারের স্থাপনা ব্যবহার করছি যার জন্য ৪টি TPU v6e চিপ ( ct6e-standard-4t) প্রয়োজন হবে, যা দুটি ভিন্ন অঞ্চলে একটি ২x২ স্লাইস হিসেবে থাকবে।
  • হাগিং ফেস টোকেন: জেমা মডেলের ওয়েটগুলো ডাউনলোড করার জন্য একটি অ্যাক্সেস টোকেন প্রয়োজন।

আমরা ফায়ারওয়াল নিয়ম, স্টোরেজ এবং সাবনেট সহ একটি কাস্টম ভিপিসি তৈরি করব। ক্লাউড কনসোল খুলুন এবং আপনি যে প্রজেক্টটি ব্যবহার করবেন তা নির্বাচন করুন।

  1. আপনার কনসোলের উপরে ডানদিকে অবস্থিত ক্লাউড শেল খুলুন, নিশ্চিত করুন যে আপনি ক্লাউড শেলে সঠিক প্রজেক্ট আইডি দেখতে পাচ্ছেন, অ্যাক্সেসের অনুমতি দেওয়ার জন্য যেকোনো প্রম্পট নিশ্চিত করুন। b51b80043d3bac90.png
  2. gke-tf নামে একটি ফোল্ডার তৈরি করুন এবং ফোল্ডারটিতে যান
mkdir -p gke-tf && cd gke-tf
PROJECT_ID=$(gcloud config get-value project)
  1. এখন কিছু কনফিগারেশন ফাইল যোগ করুন। এগুলো network.tf , variable.tf , providers.tf , fuse.tf ফাইলগুলো তৈরি করবে।
cat <<EOF > terraform.tfvars
project_id = "${PROJECT_ID}"
EOF

cat <<EOF > variables.tf
variable "project_id" { type = string }
variable "network_prefix" { default = "tpu-gke-dranet" }
variable "regions" { default = ["europe-west4", "us-east5"] }
variable "region_to_tpu_zone" {
  default = {
    "europe-west4" = "europe-west4-a"
    "us-east5"     = "us-east5-b"
  }
}
EOF

cat <<EOF > providers.tf
terraform {
  required_version = ">= 1.5.7"
  required_providers {
    google-beta = { source = "hashicorp/google-beta", version = "~> 7.0" }
    time = { source = "hashicorp/time", version = "~> 0.11.0" }
  }
}
provider "google-beta" { project = var.project_id }

resource "google_project_service" "base_apis" {
  for_each = toset([
    "compute.googleapis.com",
    "container.googleapis.com",
    "cloudresourcemanager.googleapis.com",
    "storage.googleapis.com"
  ])
  project            = var.project_id
  service            = each.value
  disable_on_destroy = false
}
EOF

cat <<EOF > network.tf
resource "google_compute_network" "vpc" {
  name                    = "\${var.network_prefix}-vpc"
  auto_create_subnetworks = false
  mtu                     = 8896 
  depends_on              = [google_project_service.base_apis]
}
resource "google_compute_subnetwork" "subnets" {
  for_each      = toset(var.regions)
  name          = "\${var.network_prefix}-node-subnet" 
  region        = each.value
  network       = google_compute_network.vpc.id
  ip_cidr_range = each.value == "europe-west4" ? "10.0.1.0/24" : "10.0.2.0/24"
}
resource "google_compute_subnetwork" "proxy_subnets" {
  for_each      = toset(var.regions)
  name          = "\${var.network_prefix}-proxy-subnet-\${each.value}"
  region        = each.value
  network       = google_compute_network.vpc.id
  ip_cidr_range = each.value == "europe-west4" ? "10.1.1.0/24" : "10.1.2.0/24"
  purpose       = "GLOBAL_MANAGED_PROXY"
  role          = "ACTIVE"
}
resource "google_compute_address" "gateway_ips" {
  for_each     = toset(var.regions)
  name         = "gemma-gateway-ip-\${each.value}"
  region       = each.value
  subnetwork   = google_compute_subnetwork.subnets[each.value].id
  address_type = "INTERNAL"
}
resource "google_compute_firewall" "allow_internal" {
  name    = "\${var.network_prefix}-allow-internal"
  network = google_compute_network.vpc.name
  allow { protocol = "all" }
  source_ranges = ["10.0.0.0/8", "10.1.0.0/16"]
}
resource "google_compute_firewall" "allow_health_checks" {
  name    = "\${var.network_prefix}-allow-hc"
  network = google_compute_network.vpc.name
  allow { 
    protocol = "tcp"
    ports    = ["8000"] 
  }
  source_ranges = ["130.211.0.0/22", "35.191.0.0/16"]
}
EOF

cat <<EOF > fuse.tf
resource "google_storage_bucket" "model_bucket" {
  name          = "\${var.project_id}-gemma-weights"
  location      = "US" 
  force_destroy = true 
  uniform_bucket_level_access = true
  depends_on    = [google_project_service.base_apis]
}

resource "google_service_account" "gcs_fuse_sa" {
  account_id   = "gcs-fuse-sa"
  display_name = "Service Account for GCS FUSE"
}

resource "google_storage_bucket_iam_member" "gcs_fuse_sa_admin" {
  bucket = google_storage_bucket.model_bucket.name
  role   = "roles/storage.objectAdmin"
  member = "serviceAccount:\${google_service_account.gcs_fuse_sa.email}"
}

resource "google_project_iam_binding" "workload_identity_binding" {
  project = var.project_id
  role    = "roles/iam.workloadIdentityUser"
  members = ["serviceAccount:\${var.project_id}.svc.id.goog[default/gemma-ksa]"]
}
EOF

` variable.tf ফাইলটি প্রোজেক্টের নাম, অঞ্চল এবং জোনের তথ্য যোগ করে। `ps` কমান্ডের মাধ্যমে 'regions' ভেরিয়েবলটি আপডেট করুন, default = ["europe-west4", "us-east5"] এটিতে আপনার টিপিইউ কোটা থাকা অঞ্চলগুলোর তথ্য যোগ করুন। আরও তথ্যের জন্য " GKE-তে টিপিইউ প্রাপ্যতা যাচাই করুন " এই ডকুমেন্টটি দেখুন।

network.tf ফাইলটি আপনার প্রোজেক্টে দুটি ভিন্ন জোনে সাবনেট, প্রক্সি-অনলি সাবনেট এবং ফায়ারওয়াল নিয়ম সহ একটি নতুন VPC যোগ করে।

provider.tf ফাইলটি Terraform-কে সমর্থন করার জন্য প্রাসঙ্গিক প্রোভাইডারটি যোগ করে।

fuse.tf আপনার মডেলের ওয়েট ক্যাশ করার জন্য ক্লাউড স্টোরেজ বাকেট যোগ করে এবং objectAdmin পারমিশনসহ একটি IAM সার্ভিস অ্যাকাউন্ট প্রস্তুত করে। এটি এই অ্যাকাউন্টটিকে GKE ওয়ার্কলোড আইডেন্টিটির সাথে সংযুক্ত করে।

  1. আপনি gke-tf ডিরেক্টরিতে আছেন কিনা তা নিশ্চিত করুন এবং নিম্নলিখিত কমান্ডগুলি চালান।
    terraform init - ওয়ার্কিং ডিরেক্টরি শুরু করে। এই ধাপে প্রদত্ত কনফিগারেশনের জন্য প্রয়োজনীয় প্রোভাইডারগুলো ডাউনলোড করা হয়। terraform plan - একটি এক্সিকিউশন প্ল্যান তৈরি করে, যা দেখায় আপনার ইনফ্রাস্ট্রাকচার ডেপ্লয় করার জন্য Terraform কী কী পদক্ষেপ নেবে। terraform apply –auto-approve আপডেটগুলো চালায় এবং স্বয়ংক্রিয়ভাবে অনুমোদন করে।
terraform init 
terraform plan 
  1. এখন ডিপ্লয়মেন্টটি চালান (এতে ৩-৫ মিনিট সময় লাগতে পারে)।
terraform apply -auto-approve
  1. একই gke-tf ফোল্ডারে নিম্নলিখিত gke.tf ফাইলটি তৈরি করুন।
cat <<EOF > gke.tf
resource "google_container_cluster" "clusters" {
  provider = google-beta
  for_each = toset(var.regions)
  name     = "gke-\${each.value}"
  location = var.region_to_tpu_zone[each.value]
  deletion_protection = false
  network             = google_compute_network.vpc.id
  subnetwork          = google_compute_subnetwork.subnets[each.value].id
  release_channel { channel = "RAPID" }
  datapath_provider = "ADVANCED_DATAPATH"
  networking_mode   = "VPC_NATIVE"
  
  gateway_api_config { channel = "CHANNEL_STANDARD" }
  
  ip_allocation_policy {
    cluster_ipv4_cidr_block  = ""
    services_ipv4_cidr_block = ""
  }
  
  workload_identity_config { workload_pool = "\${var.project_id}.svc.id.goog" }
  
  addons_config { 
    gcs_fuse_csi_driver_config { enabled = true } 
  }
  
  initial_node_count = 1
  node_config {
    machine_type = "e2-standard-16"
    oauth_scopes = ["https://www.googleapis.com/auth/cloud-platform"]
    workload_metadata_config { mode = "GKE_METADATA" }
  }
}

resource "google_container_node_pool" "tpu_pools" {
  provider = google-beta
  for_each = toset(var.regions)
  name     = "tpu-v6e-pool"
  location = var.region_to_tpu_zone[each.value]
  cluster  = google_container_cluster.clusters[each.value].name
  node_count = 1
  
  network_config { accelerator_network_profile = "auto" }
  
  node_config {
    machine_type = "ct6e-standard-4t"
    oauth_scopes = ["https://www.googleapis.com/auth/cloud-platform"]    
    labels = { "cloud.google.com/gke-networking-dra-driver" = "true" }
    workload_metadata_config { mode = "GKE_METADATA" }
  }
  
  lifecycle { ignore_changes = [node_config[0].labels] }
}
EOF

gke.tf ভিন্ন ভিন্ন অঞ্চলে দুটি ক্লাস্টার যুক্ত করে, ৪টি চিপযুক্ত TPU v6e চালিত দুটি TPU নোডপুল তৈরি করে এবং নোডপুলগুলোতে পরিচালিত DRANET বরাদ্দ করে।

  1. এখন ডেপ্লয়মেন্টটি চালান (এতে ১০-১৫ মিনিট সময় লাগতে পারে)।
terraform apply -auto-approve
  1. যাচাই করুন
echo -e "\n=== Verifying GKE Clusters ==="
gcloud container clusters list --filter="name:gke-europe-west4 OR name:gke-us-east5" --project=$PROJECT_ID

echo -e "\n=== Verifying VPC Network ==="
gcloud compute networks list --filter="name:tpu-gke-dranet-vpc" --project=$PROJECT_ID

echo -e "\n=== Verifying Reserved Static IPs for Gateway ==="
gcloud compute addresses list --filter="name~gemma-gateway-ip" --project=$PROJECT_ID

echo -e "\n=== Verifying GCS Bucket ==="
gcloud storage ls | grep "${PROJECT_ID}-gemma-weights"

echo -e "\n=== Verifying GCS FUSE Service Account ==="
gcloud iam service-accounts list --filter="email:gcs-fuse-sa@${PROJECT_ID}.iam.gserviceaccount.com" --project=$PROJECT_ID

৪. যানবাহন নিবন্ধন

আমাদের ক্লাস্টারটিকে একটি ফ্লিটে নিবন্ধন করতে হবে।

  1. আপনি gke-tf ডিরেক্টরিতে আছেন কিনা তা নিশ্চিত করুন এবং নিম্নলিখিত কমান্ডগুলো চালান।
cat <<EOF > fleet.tf
data "google_project" "project" {
  project_id = var.project_id
}

resource "google_project_service" "fleet_apis" {
  for_each = toset([
    "gkehub.googleapis.com",
    "multiclusterservicediscovery.googleapis.com",
    "multiclusteringress.googleapis.com",
    "trafficdirector.googleapis.com"
  ])
  project            = var.project_id
  service            = each.value
  disable_on_destroy = false
}

resource "google_project_service_identity" "mci_sa" {
  provider = google-beta
  project  = var.project_id
  service  = "multiclusteringress.googleapis.com"
  depends_on = [google_project_service.fleet_apis]
}

resource "time_sleep" "wait_for_apis" {
  create_duration = "60s"
  depends_on      = [google_project_service.fleet_apis]
}

resource "google_project_iam_member" "mci_sa_admin" {
  project    = var.project_id
  role       = "roles/container.admin"
  member     = "serviceAccount:\${google_project_service_identity.mci_sa.email}"
  depends_on = [google_project_service_identity.mci_sa, time_sleep.wait_for_apis]
}

resource "google_gke_hub_membership" "memberships" {
  provider      = google-beta
  for_each      = toset(var.regions)
  project       = var.project_id
  membership_id = "gke-\${each.value}"
  endpoint {
    gke_cluster { resource_link = "//container.googleapis.com/\${google_container_cluster.clusters[each.value].id}" }
  }
  depends_on = [time_sleep.wait_for_apis, google_container_cluster.clusters]
}

resource "google_gke_hub_feature" "mcs" {
  provider   = google-beta
  name       = "multiclusterservicediscovery"
  location   = "global"
  project    = var.project_id
  depends_on = [time_sleep.wait_for_apis]
}

resource "google_gke_hub_feature" "ingress" {
  provider   = google-beta
  name       = "multiclusteringress"
  location   = "global"
  project    = var.project_id
  depends_on = [google_gke_hub_membership.memberships, google_project_iam_member.mci_sa_admin]
  spec {
    multiclusteringress { config_membership = "projects/\${var.project_id}/locations/global/memberships/gke-us-east5" }
  }
}
EOF

fleet.tf ফাইলটি উভয় ক্লাস্টারকে একটি গ্লোবাল GKE ফ্লিটে রেজিস্টার করে এবং মাল্টি-ক্লাস্টার সার্ভিস ডিসকভারি ও ইনগ্রেস সক্ষম করে। এটি ইউএস ক্লাস্টারকে কেন্দ্রীয় কনফিগারেশন ক্লাস্টার হিসেবে মনোনীত করে, যা গেটওয়ে এপিআই-কে ট্র্যাফিক মনিটর ও রাউট করার সুযোগ দেয়।

  1. gke-tf ফোল্ডারে গিয়ে এটি চালান (এতে ৩-৫ মিনিট সময় লাগতে পারে)।
terraform plan 
terraform apply -auto-approve
  1. ফ্লিট রেজিস্ট্রেশন যাচাই করুন
gcloud container fleet memberships list --project=$PROJECT_ID

৫. মডেলের ওয়েটগুলো FUSE-এ ক্যাশ করুন।

আমরা ইউএস ক্লাস্টারে একটি অস্থায়ী কুবারনেটিস জব চালাব, যা একটি পাইথন স্ক্রিপ্টের মাধ্যমে জেমা মডেলটিকে নিরাপদে সরাসরি FUSE-এ মাউন্ট করা ক্লাউড স্টোরেজ বাকেটে ডাউনলোড করবে।

  1. নিম্নলিখিত ভেরিয়েবলগুলি তৈরি করুন
export CTX_EU="gke_${PROJECT_ID}_europe-west4-a_gke-europe-west4"
export CTX_US="gke_${PROJECT_ID}_us-east5-b_gke-us-east5"
  1. এটি google/gemma-3-27b-it মডেল ব্যবহার করে, তাই আপনাকে একটি HF টোকেন তৈরি করতে হবে। নিচের YOUR_ACTUAL_HUGGING_FACE_TOKEN এর জায়গায় আপনার আসল টোকেনটি বসান।
export HF_TOKEN="YOUR_ACTUAL_HUGGING_FACE_TOKEN"
  1. আপনি gke-tf ডিরেক্টরিতে আছেন কিনা তা নিশ্চিত করুন এবং নিম্নলিখিত কমান্ডগুলো চালান।
gcloud container clusters get-credentials gke-us-east5 --zone us-east5-b --project=$PROJECT_ID

cat <<EOF > ksa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: gemma-ksa
  namespace: default
  annotations:
    iam.gke.io/gcp-service-account: "gcs-fuse-sa@${PROJECT_ID}.iam.gserviceaccount.com"
EOF

kubectl apply -f ksa.yaml --context=$CTX_US
kubectl delete secret hf-secret --context=$CTX_US --ignore-not-found
kubectl create secret generic hf-secret --from-literal=hf_token=${HF_TOKEN} --context=$CTX_US

cat <<EOF > download-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: model-downloader
  namespace: default
spec:
  backoffLimit: 1
  template:
    metadata:
      annotations:
        gke-gcsfuse/volumes: "true"
    spec:
      serviceAccountName: gemma-ksa
      restartPolicy: Never
      containers:
      - name: downloader
        image: python:3.11-slim
        env:
        - name: HF_TOKEN
          valueFrom:
            secretKeyRef:
              name: hf-secret
              key: hf_token
        command:
        - bash
        - -c
        - |
          pip install -U huggingface_hub
          echo "Downloading Gemma 3 directly to GCS bucket..."
          python3 -c "from huggingface_hub import snapshot_download; import os; snapshot_download(repo_id='google/gemma-3-27b-it', local_dir='/data/gemma-weights', token=os.environ['HF_TOKEN'])"
          echo "Download complete! Safe to proceed."
        volumeMounts:
        - name: gcs-fuse-volume
          mountPath: /data/gemma-weights
      volumes:
      - name: gcs-fuse-volume
        csi:
          driver: gcsfuse.csi.storage.gke.io
          volumeAttributes:
            bucketName: "${PROJECT_ID}-gemma-weights"
EOF

kubectl apply -f download-job.yaml --context=$CTX_US
  1. এগিয়ে যাওয়ার আগে ডাউনলোড শেষ হওয়া পর্যন্ত অপেক্ষা করুন (মডেলের আকারের উপর নির্ভর করে এতে ৫-১০ মিনিট সময় লাগতে পারে)।
kubectl logs -f job/model-downloader --context=$CTX_US

(যখন "ডাউনলোড সম্পন্ন!" লেখাটি আসবে, তখন লগ থেকে বের হতে Ctrl+C চাপুন।)

৬. ওয়ার্কলোড vLLM এবং Gemma স্থাপন করুন

  1. আপনি gke-tf ডিরেক্টরিতে আছেন কিনা তা নিশ্চিত করুন এবং নিম্নলিখিত কমান্ডগুলো চালান।
cat <<EOF > workload.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: gemma-ksa
  namespace: default
  annotations:
    iam.gke.io/gcp-service-account: "gcs-fuse-sa@${PROJECT_ID}.iam.gserviceaccount.com"
---
apiVersion: resource.k8s.io/v1
kind: ResourceClaimTemplate
metadata:
  name: all-netdev
  namespace: default
spec:
  spec:
    devices:
      requests:
      - name: req-netdev
        exactly:
          deviceClassName: netdev.google.com
          allocationMode: All
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: vllm-gemma
  namespace: default
  labels:
    app: gemma-server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: gemma-server
  template:
    metadata:
      labels:
        app: gemma-server
      annotations:
        gke-gcsfuse/volumes: "true"
    spec:
      serviceAccountName: gemma-ksa
      nodeSelector:
        cloud.google.com/gke-tpu-accelerator: tpu-v6e-slice
        cloud.google.com/gke-tpu-topology: 2x2
      resourceClaims:
      - name: netdev
        resourceClaimTemplateName: all-netdev
      containers:
      - name: vllm-tpu
        image: vllm/vllm-tpu:latest
        command:
        - bash
        - -c
        - |
          export PYTHONUNBUFFERED=1
          echo "Booting vLLM instantly from local GCS FUSE mount..."
          
          python3 -m vllm.entrypoints.openai.api_server \
            --model /data/gemma-weights \
            --tensor-parallel-size 4 \
            --port 8000
        ports:
        - containerPort: 8000
        resources:
          requests:
            google.com/tpu: 4
          limits:
            google.com/tpu: 4
          claims:
          - name: netdev
        volumeMounts:
        - name: dshm
          mountPath: /dev/shm
        - name: gcs-fuse-volume
          mountPath: /data/gemma-weights
          readOnly: true
      volumes:
      - name: dshm
        emptyDir:
          medium: Memory
      - name: gcs-fuse-volume
        csi:
          driver: gcsfuse.csi.storage.gke.io
          readOnly: true
          volumeAttributes:
            bucketName: "${PROJECT_ID}-gemma-weights"
            mountOptions: "implicit-dirs"
            fileCacheCapacity: "100Gi"
            fileCacheForRangeRead: "true"
---
apiVersion: v1
kind: Service
metadata:
  name: vllm-gemma-service
  namespace: default
spec:
  selector:
    app: gemma-server
  ports:
  - protocol: TCP
    port: 8000
    targetPort: 8000
  type: ClusterIP
---
apiVersion: monitoring.googleapis.com/v1
kind: PodMonitoring
metadata:
  name: vllm-gemma-monitoring
  namespace: default
spec:
  selector:
    matchLabels:
      app: gemma-server
  endpoints:
  - port: 8000
    interval: 15s
    path: /metrics
EOF
  1. এখন নিম্নলিখিত স্ক্রিপ্টটি চালান (এটি দুটি অঞ্চলে স্থাপন করা হবে বলে সম্পন্ন হতে ৫ থেকে ১০ মিনিট সময় লাগবে)।
for CTX in $CTX_EU $CTX_US; do
  ZONE=$(echo $CTX | cut -d_ -f3)
  CLUSTER=$(echo $CTX | cut -d_ -f4)
  gcloud container clusters get-credentials $CLUSTER --zone $ZONE --project=$PROJECT_ID
  
  kubectl delete secret hf-secret --ignore-not-found --context=$CTX
  kubectl create secret generic hf-secret --from-literal=hf_token=${HF_TOKEN} --context=$CTX
  kubectl apply -f workload.yaml --context=$CTX
done
  1. মোতায়েন নিশ্চিত করুন
for CTX in $CTX_EU $CTX_US; do kubectl rollout status deployment/vllm-gemma --timeout=15m --context=$CTX; done
  1. একবার সম্পন্ন হলে, এটি চালিয়ে আপনি যাচাই করতে পারেন যে পরিচালিত DRANET নেটওয়ার্কিং পডগুলিতে বরাদ্দ করা হয়েছে।
for CTX in $CTX_EU $CTX_US; do
  echo "Checking DRA network interfaces on $CTX..."
  kubectl --context=$CTX exec deployment/vllm-gemma -c vllm-tpu -- ls /sys/class/net
  echo "----------------------------------------"
done

আপনি স্ট্যান্ডার্ড পড নেটওয়ার্কিং-এর জন্য অতিরিক্ত নেটওয়ার্ক ইন্টারফেস eth0 দেখতে পাবেন, এর পাশাপাশি আপনার ডেডিকেটেড TPU ফ্যাব্রিকের প্রতিনিধিত্বকারী সেকেন্ডারি ইন্টারফেস eth1, eth2, ইত্যাদিও দেখতে পাবেন।

৭. ইনফারেন্স এপিআই এবং গেটওয়ে কনফিগারেশন

এখন আপনি InferenceObjective (gemma-objective), AutoscalingMetric (tpu-cache) এবং Inference Pool(gemma-pool) তৈরি করবেন। Inference pool-টি একটি Helm chart ব্যবহার করে তৈরি করা হয়। এটি তৈরি করার প্রক্রিয়াটি ইনস্টল এবং যাচাই করে।

  1. আপনি gke-tf ডিরেক্টরিতে আছেন কিনা তা নিশ্চিত করুন এবং নিম্নলিখিত কমান্ডগুলো চালান। এটি অবজেক্টটি ডেপ্লয় করবে এবং একটি ভ্যালিডেশন চালাবে।
cat <<EOF > inference-objective.yaml
apiVersion: inference.networking.x-k8s.io/v1alpha2
kind: InferenceObjective
metadata:
  name: gemma-objective
  namespace: default
spec:
  priority: 10
  poolRef:
    name: gemma-pool
    group: "inference.networking.k8s.io" 
EOF

cat <<EOF > metrics.yaml
apiVersion: autoscaling.gke.io/v1beta1
kind: AutoscalingMetric
metadata:
  name: tpu-cache
  namespace: default
spec:
  selector:
    matchLabels:
      app: gemma-server
  endpoints:
  - port: 8000
    path: /metrics
    metrics:
    - name: vllm:kv_cache_usage_perc
      exportName: tpu-cache
EOF

for CTX in $CTX_EU $CTX_US; do
  kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/v1.1.0/config/crd/bases/inference.networking.x-k8s.io_inferenceobjectives.yaml --context=$CTX
  kubectl apply -f inference-objective.yaml --context=$CTX
  kubectl apply -f metrics.yaml --context=$CTX
done

helm install gemma-pool --kube-context $CTX_EU \
  --set inferencePool.modelServers.matchLabels.app=gemma-server \
  --set provider.name=gke \
  --version v1.1.0 \
  oci://registry.k8s.io/gateway-api-inference-extension/charts/inferencepool

helm install gemma-pool --kube-context $CTX_US \
  --set inferencePool.modelServers.matchLabels.app=gemma-server \
  --set provider.name=gke \
  --set inferenceExtension.monitoring.gke.enabled=true \
  --version v1.1.0 \
  oci://registry.k8s.io/gateway-api-inference-extension/charts/inferencepool

for CTX in $CTX_EU $CTX_US; do
  kubectl annotate inferencepool gemma-pool networking.gke.io/export="True" --context=$CTX
done

for CTX in $CTX_EU $CTX_US; do
  echo "Verifying Inference API resources on $CTX..."
  kubectl get inferencepools --context=$CTX
  kubectl get autoscalingmetrics tpu-cache --context=$CTX
done

৮. গেটওয়ে কনফিগারেশন

এখন আপনি ক্রস-রিজিওনাল গেটওয়ে কনফিগারেশন তৈরি করবেন। Gateway(cross-region-gateway), HTTPRoute (gemma-route) , HealthCheckPolicy(gemma-health-check)and GCPBackendPolicy(gemma-backend-policy. ইনফারেন্স পুলটি একটি হেলম চার্ট ব্যবহার করে তৈরি করা হয়। এটি ইনস্টলেশন সম্পন্ন করে এবং তৈরি হওয়াটি যাচাই করে। (গেটওয়েটি সক্রিয় হতে ৮-১০ মিনিট সময় লাগবে)

cat <<EOF > config-cluster.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: cross-region-gateway
  namespace: default
spec:
  gatewayClassName: gke-l7-cross-regional-internal-managed-mc
  addresses:
  - type: networking.gke.io/named-address-with-region
    value: "regions/europe-west4/addresses/gemma-gateway-ip-europe-west4"
  - type: networking.gke.io/named-address-with-region
    value: "regions/us-east5/addresses/gemma-gateway-ip-us-east5"
  listeners:
  - name: http
    protocol: HTTP
    port: 80
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: gemma-route
  namespace: default
spec:
  parentRefs:
  - name: cross-region-gateway
    kind: Gateway
  rules:
  - backendRefs:
    - group: networking.gke.io
      kind: GCPInferencePoolImport
      name: gemma-pool
      port: 8000
---
apiVersion: networking.gke.io/v1
kind: HealthCheckPolicy
metadata:
  name: gemma-health-check
  namespace: default
spec:
  targetRef:
    group: networking.gke.io
    kind: GCPInferencePoolImport
    name: gemma-pool
  default:
    config:
      type: HTTP
      httpHealthCheck:
        requestPath: /health
        port: 8000
---
apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: gemma-backend-policy
  namespace: default
spec:
  targetRef:
    group: networking.gke.io
    kind: GCPInferencePoolImport
    name: gemma-pool
  default:
    timeoutSec: 100
    balancingMode: CUSTOM_METRICS
    trafficDuration: LONG
    customMetrics:
      - name: gke.named_metrics.tpu-cache
        dryRun: false
        maxUtilizationPercent: 60
EOF

echo -e "\n=== Creating Cross-Regional Gateway Resources ==="
kubectl apply -f config-cluster.yaml --context=$CTX_US

echo -e "\n=== Provisioning Global Load Balancer (This takes 5-10 minutes) ==="
echo "Working on the Gateway... waiting for Google Cloud to assign IPs and program routes..."

# The script will hold here until the gateway is officially ready
kubectl wait --for=condition=programmed gateway/cross-region-gateway --timeout=10m --context=$CTX_US

echo -e "\n=== SUCCESS: Gateway is fully provisioned and ready! ==="

ইনফারেন্স পুল (হেলম) : আপনার উভয় অঞ্চলের মডেল সার্ভারগুলোকে একটি একক লজিক্যাল ব্যাকএন্ডে একত্রিত করে।

Gateway ও HTTPRoute : প্রকৃত গ্লোবাল ইন্টারনাল লোড ব্যালেন্সার তৈরি করে এবং আপনার মডেলগুলিতে আগত এআই প্রম্পট রাউটিং করার নিয়মাবলী নির্ধারণ করে।

হেলথচেক ও ব্যাকএন্ড পলিসি : এটি নিশ্চিত করে যে অনুরোধগুলি শুধুমাত্র সুস্থ পডগুলিতেই পাঠানো হয় এবং স্মার্ট, মেট্রিক-ভিত্তিক ট্র্যাফিক বিতরণ সক্ষম করে (যা টিপিইউ-এর উপর অতিরিক্ত চাপ প্রতিরোধ করে)।

যাচাইকরণ : আপনি পরবর্তী ধাপে যাওয়ার আগে, গুগল ক্লাউড অভ্যন্তরীণ আইপি অ্যাড্রেসগুলো সম্পূর্ণরূপে সরবরাহ করেছে কিনা তা নিশ্চিত করতে স্ক্রিপ্টটি কিছুক্ষণ থামে।

৯. ফেইলওভার পরীক্ষা

এবার ল্যাবের সেরা অংশ: আপনার আর্কিটেকচারের উচ্চ প্রাপ্যতা পরীক্ষা করা।

এই স্বয়ংক্রিয় পরীক্ষাটি ঠিক যা করবে তা নিচে দেওয়া হলো:

  • বেসলাইন টেস্ট: আমাদের সিমুলেটেড ব্যবহারকারী একটি ইনফারেন্স প্রম্পট ("ফ্রান্সের রাজধানী কী?") পাঠায়। যেহেতু ব্যবহারকারী প্রাইমারি অঞ্চলে অবস্থিত, তাই গেটওয়ে সর্বনিম্ন সম্ভাব্য ল্যাটেন্সির জন্য অনুরোধটি সেখানকার স্থানীয় টিপিইউ-গুলোতে রাউট করে দেয়।
  • বিপর্যয়: আমরা প্রাইমারি রিজিয়নের সমস্ত টিপিইউ পড বন্ধ করে ( replicas=0 ) একটি ভয়াবহ ডেটা সেন্টার বিভ্রাটের অনুকরণ করি।
  • শনাক্তকরণ: আমরা ৪৫ সেকেন্ড অপেক্ষা করি। এই সময়ের মধ্যে, গেটওয়ের স্বাস্থ্য পরীক্ষা ব্যর্থ হয়, এটি বুঝতে পারে যে প্রাথমিক ব্যাকএন্ডটি সম্পূর্ণ অফলাইন, এবং এটি গতিশীলভাবে তার গ্লোবাল রাউটিং টেবিলগুলো আপডেট করে।
  • ফেলওভার: আমাদের ব্যবহারকারী দ্বিতীয়বার একটি অনুরোধ পাঠান ("জার্মানির রাজধানী কী?")। ব্যবহারকারীর কোনো ধারণাই থাকে না যে নেটওয়ার্কে বিভ্রাট চলছে। গেটওয়ে অনুরোধটি গ্রহণ করে এবং তাৎক্ষণিকভাবে এটিকে বিশ্বজুড়ে আপনার সচল সেকেন্ডারি টিপিইউগুলোতে পুনঃনির্দেশিত করে।
  • পুনরুদ্ধার: আমরা প্রাথমিক টিপিইউগুলো পুনরুদ্ধার করে আপনার গ্লোবাল আর্কিটেকচারকে সম্পূর্ণ সুস্থ অবস্থায় ফিরিয়ে আনি।
  1. ক্লাউড শেল খুলুন এবং নিম্নলিখিতটি চালান:
cat << 'EOF' > failover-test.sh
#!/bin/bash
# Multi-Cluster Inference Failover Test

export PROJECT_ID=$(gcloud config get-value project)
export CTX_EU="gke_${PROJECT_ID}_europe-west4-a_gke-europe-west4"
export CTX_US="gke_${PROJECT_ID}_us-east5-b_gke-us-east5"

echo -e "\n=== PHASE 1: VERIFYING CURRENT STATE (BOTH CLUSTERS UP) ==="
echo "Checking US Cluster (Primary):"
kubectl get pods -l app=gemma-server --context=$CTX_US
echo "Checking EU Cluster (Secondary):"
kubectl get pods -l app=gemma-server --context=$CTX_EU

echo -e "\nDeploying Test Client in US..."
export GATEWAY_IP_US=$(gcloud compute addresses describe gemma-gateway-ip-us-east5 --region=us-east5 --project=$PROJECT_ID --format="value(address)")

kubectl run curl-test --image=curlimages/curl --restart=Never --context=$CTX_US -- sleep 3600
kubectl wait --for=condition=ready pod/curl-test --context=$CTX_US --timeout=60s

echo -e "\n=== PHASE 2: BASELINE TEST (US Client -> US TPUs) ==="
echo "Prompting the AI: 'What is the capital of France?'"
echo "Expect to see the full JSON response including token usage..."
kubectl exec curl-test --context=$CTX_US -- curl -s -X POST http://$GATEWAY_IP_US/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "/data/gemma-weights", 
    "messages": [{"role": "user", "content": "What is the capital of France?"}], 
    "max_tokens": 100
  }' | jq .

echo -e "\n=== PHASE 3: SIMULATING REGIONAL OUTAGE (Scaling US to 0) ==="
kubectl scale deployment vllm-gemma --replicas=0 --context=$CTX_US
echo "Waiting 20 seconds for pods to begin terminating..."
sleep 20

echo -e "\n=== PHASE 4: CONFIRMING STATE (PODS TERMINATING) ==="
echo "Checking US Cluster (Should be terminating):"
kubectl get pods -l app=gemma-server --context=$CTX_US
echo "Checking EU Cluster (Should still be running):"
kubectl get pods -l app=gemma-server --context=$CTX_EU

echo -e "\nWaiting 45 seconds for Gateway health checks to update global routing tables..."
sleep 45

echo -e "\n=== PHASE 5: CONFIRMING COMPLETE DOWN AND EURO UP ==="
echo "Checking US Cluster (Should be completely empty now):"
kubectl get pods -l app=gemma-server --context=$CTX_US
echo "Checking EU Cluster (Should still be running):"
kubectl get pods -l app=gemma-server --context=$CTX_EU

echo -e "\n=== PHASE 6: FAILOVER TEST (US Client -> EU TPUs) ==="
echo "Prompting the AI: 'What is the capital of Germany?'"
echo "Request is actively being rerouted to Europe. Expecting full JSON response..."
kubectl exec curl-test --context=$CTX_US -- curl -s -X POST http://$GATEWAY_IP_US/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "/data/gemma-weights", 
    "messages": [{"role": "user", "content": "What is the capital of Germany?"}], 
    "max_tokens": 100
  }' | jq .

echo -e "\n=== PHASE 7: RESTORING INFRASTRUCTURE (Scaling US to 1) ==="
kubectl scale deployment vllm-gemma --replicas=1 --context=$CTX_US
echo "Waiting for US pods to boot and mount FUSE..."
kubectl rollout status deployment/vllm-gemma --timeout=15m --context=$CTX_US

echo -e "\n=== PHASE 8: CONFIRMING BOTH SYSTEMS ARE BACK UP ==="
echo "Checking US Cluster (Restored):"
kubectl get pods -l app=gemma-server --context=$CTX_US
echo "Checking EU Cluster (Still Healthy):"
kubectl get pods -l app=gemma-server --context=$CTX_EU

echo -e "\n=== PHASE 9: CLEANUP ==="
kubectl delete pod curl-test --context=$CTX_US
echo "Failover lab complete."
EOF

chmod +x failover-test.sh
./failover-test.sh
  1. পরীক্ষা শেষ হলে আপনি পরিষ্কার করতে পারেন।

১০. পরিষ্কার করুন

  1. কাজের চাপ পরিষ্কার করুন
#!/bin/bash
echo "=== PART 1: Kubernetes & Workload Cleanup ==="
export PROJECT_ID=$(gcloud config get-value project)
export CTX_EU="gke_${PROJECT_ID}_europe-west4-a_gke-europe-west4"
export CTX_US="gke_${PROJECT_ID}_us-east5-b_gke-us-east5"

echo "Deleting Gateway resources..."
for CTX in $CTX_EU $CTX_US; do
  kubectl delete gateways,httproutes,healthcheckpolicies,gcpbackendpolicies --all --context=$CTX --ignore-not-found
done

echo "Waiting 60 seconds for the external Load Balancer to detach..."
sleep 60

echo "Cleaning up workloads and custom resources..."
for CTX in $CTX_EU $CTX_US; do
  helm uninstall gemma-pool --kube-context=$CTX || true
  kubectl delete job model-downloader --context=$CTX --ignore-not-found
  kubectl delete all -l app=gemma-server --context=$CTX --ignore-not-found
  kubectl delete inferenceobjectives,autoscalingmetrics --all --context=$CTX --ignore-not-found
  kubectl delete serviceaccount gemma-ksa --context=$CTX --ignore-not-found
  kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/v1.1.0/config/crd/bases/inference.networking.x-k8s.io_inferenceobjectives.yaml --context=$CTX --ignore-not-found
done

echo -e "\n=== Part 1 Complete! Safe to proceed to Terraform Teardown. ==="
  1. পরিকাঠামোটি পরিষ্কার করুন। নিশ্চিত করুন যে আপনি gke-tf ফোল্ডারে আছেন।
cat << 'EOF' > cleanup-tf.sh
#!/bin/bash
echo "=== PART 2: Infrastructure & Terraform Teardown ==="
export PROJECT_ID=$(gcloud config get-value project)
export LAB_NETWORK="tpu-gke-dranet-vpc"

echo "Destroying GKE Fleet Features to prevent firewall resurrection..."
terraform destroy -target=google_gke_hub_feature.mcs -target=google_gke_hub_feature.ingress -auto-approve

echo "Waiting 30 seconds for the self-healing controllers to spin down..."
sleep 30

echo "Hunting down orphaned auto-generated firewall rules strictly on the lab network..."
GHOST_RULES=$(gcloud compute firewall-rules list --filter="network~${LAB_NETWORK} AND (name~mcsd OR name~k8s-fw-l7)" --format="value(name)" --project=$PROJECT_ID)

if [ ! -z "$GHOST_RULES" ]; then
  for rule in $GHOST_RULES; do
    echo "Deleting ghost rule: $rule"
    gcloud compute firewall-rules delete $rule --project=$PROJECT_ID --quiet
  done
else
  echo "No ghost rules found on ${LAB_NETWORK}."
fi

echo "=== Controllers and Firewalls dead. Destroying remaining Base Infrastructure. ==="

MAX_RETRIES=3
RETRY_COUNT=0
SUCCESS=false

while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
  # Run the destroy command. If it succeeds (exit code 0), break the loop.
  if terraform destroy -auto-approve; then
    SUCCESS=true
    break
  else
    RETRY_COUNT=$((RETRY_COUNT+1))
    echo -e "\n[WARNING] Terraform destroy encountered an error (likely a GCP resource lock)."
    
    if [ $RETRY_COUNT -lt $MAX_RETRIES ]; then
      echo "Waiting 30 seconds before retry $RETRY_COUNT of $MAX_RETRIES..."
      sleep 30
    fi
  fi
done

if [ "$SUCCESS" = true ]; then
  echo -e "\n=== Lab Cleanup Successfully Completed! ==="
else
  echo -e "\n[ERROR] Lab Cleanup failed after $MAX_RETRIES attempts."
  echo "Some resources may still be locked. Run 'terraform destroy -auto-approve' manually later to finish."
  exit 1
fi
EOF

chmod +x cleanup-tf.sh
./cleanup-tf.sh

নির্দিষ্ট রিসোর্সগুলো মুছে ফেলতে গিয়ে কোনো সমস্যার সম্মুখীন হলে, আপনার terraform destroy কমান্ড স্ক্রিপ্ট ./cleanup-tf.sh পুনরায় চালানো উচিত।

১১. অভিনন্দন

অভিনন্দন! আপনি সফলভাবে একটি উচ্চ প্রাপ্যতা সম্পন্ন, মাল্টি-ক্লাস্টার GKE ইনফারেন্স গেটওয়ে এবং GKE, পরিচালিত DRANET ও TPU v6e অ্যাক্সিলারেটর ব্যবহার করে একটি আন্তঃআঞ্চলিক এআই ইনফারেন্স আর্কিটেকচার স্থাপন করেছেন।

তাৎক্ষণিক মডেল লোডিংয়ের জন্য ক্লাউড স্টোরেজ ফিউজ (Cloud Storage FUSE) এবং লেটেন্সি-সচেতন, মাল্টি-ক্লাস্টার রাউটিংয়ের জন্য ইনফারেন্স গেটওয়ে এপিআই (Inference Gateway API)-এর সমন্বয়ের মাধ্যমে, আপনি এমন একটি স্থিতিস্থাপক ব্যাকএন্ড তৈরি করেছেন যা অভ্যন্তরীণ ব্যবহারকারীর ট্র্যাফিক ব্যাহত না করেই একটি সম্পূর্ণ আঞ্চলিক ডেটা সেন্টার বিভ্রাট মোকাবিলা করতে সক্ষম।

পরবর্তী পদক্ষেপ / আরও জানুন

আপনি GKE নেটওয়ার্কিং সম্পর্কে আরও পড়তে পারেন।

আপনার পরবর্তী ল্যাব নিন

গুগল ক্লাউডের সাথে আপনার অনুসন্ধান চালিয়ে যান, এবং এই অন্যান্য গুগল ক্লাউড ল্যাবগুলোও দেখে নিন: