Gemini Cloud Assist ile uygulama sorunlarını bulma ve düzeltme

1. Giriş

Gemini Cloud Assist, Google Cloud iş yüklerinizi destekleyen tam özellikli bir aracıdır. Aracı, yeni uygulamalar tasarlama veya mevcut uygulamaları güncelleme, iş yüklerini Google Cloud'da dağıtma ve çalıştırma, iş yüklerinde sorun giderme ve bunları maliyet ve performans açısından optimize etme konusunda ortağınızdır.

Gemini Cloud Assist, beklenmedik hatalara ve hizmet kesintilerine yanıt verme becerinizi geliştirir.

Neler öğreneceksiniz?

  1. Dağıtım: Temel bir arka ucu ve veritabanını Google Cloud'a dağıtma.
  2. Hata ayıklama: Gemini Cloud Assist, bulut ve kod sorunlarının araştırılmasını ve temel neden analizini nasıl otomatikleştirir?
  3. Düzeltme: Gemini Cloud Assist, temel nedene göre düzeltmeleri belirlemeye nasıl yardımcı olur?

2. Proje ayarlama

Google Hesabı

Kişisel Google Hesabınız yoksa Google Hesabı oluşturmanız gerekir.

İş veya okul hesabı yerine kişisel hesap kullanın.

Google Cloud Console'da oturum açma

Kişisel bir Google Hesabı kullanarak Google Cloud Console'da oturum açın.

Faturalandırmayı Etkinleştir

Kişisel faturalandırma hesabı oluşturma

Faturalandırmayı Google Cloud kredilerini kullanarak ayarladıysanız bu adımı atlayabilirsiniz.

Kişisel faturalandırma hesabı oluşturmak için Cloud Console'da faturalandırmayı etkinleştirmek üzere buraya gidin.

Bazı notlar:

  • Bu laboratuvarı tamamlamak için 1 ABD dolarından daha az tutarda bulut kaynağı kullanmanız gerekir.
  • Daha fazla ücret ödememek için bu laboratuvarın sonundaki adımları uygulayarak kaynakları silebilirsiniz.
  • Yeni kullanıcılar 300 ABD doları değerinde ücretsiz deneme sürümünden yararlanabilir.

Proje oluşturma (isteğe bağlı)

Bu laboratuvarda kullanmak istediğiniz mevcut bir projeniz yoksa buradan yeni bir proje oluşturun.

3. Cloud Shell Düzenleyici'yi açın

  1. Doğrudan Cloud Shell Düzenleyici'ye gitmek için bu bağlantıyı tıklayın.
  2. Bugün herhangi bir noktada yetkilendirmeniz istenirse devam etmek için Yetkilendir'i tıklayın.Cloud Shell'i yetkilendirmek için tıklayın.
  3. Terminal ekranın alt kısmında görünmüyorsa açın:
    • Görünüm'ü tıklayın.
    • Terminal'i tıklayın.Cloud Shell Düzenleyici'de yeni terminal açma
  4. Terminalde şu komutla projenizi ayarlayın:
    gcloud config set project [PROJECT_ID]
    
    • Örnek:
      gcloud config set project lab-project-id-example
      
    • Proje kimliğinizi hatırlamıyorsanız tüm proje kimliklerinizi şu komutla listeleyebilirsiniz:
      gcloud projects list
      
      Cloud Shell Düzenleyici terminalinde proje kimliğini ayarlama
  5. Şu mesajı görmeniz gerekir:
    Updated property [core/project].
    

4. API'leri etkinleştir

Uygulama bileşenlerinin dağıtılması ve Google Cloud Assist'in kullanılması için aşağıdaki API'leri etkinleştirin:

Terminalde API'leri etkinleştirin:

```bash
gcloud services enable \
  container.googleapis.com \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com \
  alloydb.googleapis.com \
  run.googleapis.com
```
<br>
When the command finishes, you should see an output like the following: 
<br>

```console
Operation "operations/acf.p2-176675280136-b03ab5e4-3483-4ebf-9655-43dc3b345c63" finished successfully.
```

5. Projeyi hazırlama

Cloud Assist'i test etmek için temel uygulamayı ve dağıtımı oluşturacaksınız.

Dizini oluşturma

  1. Cloud Shell Düzenleyici'yi veya tercih ettiğiniz geliştirme ortamını açın.
  2. Yeni klasör oluşturma:
    mkdir -p ~/gemini-cloud-assist-debug
    mkdir -p ~/gemini-cloud-assist-debug/auth_issue_demo
    mkdir -p ~/gemini-cloud-assist-debug/terraform
    cd ~/gemini-cloud-assist-debug
    
  3. Terminalde, Cloud Shell Editor çalışma alanını açmak için aşağıdaki komutu çalıştırın:
cloudshell open-workspace ~/gemini-cloud-assist-debug

Dosyaları oluşturma

Şimdi uygulama için gerekli başlangıç dosyalarını oluşturacaksınız.

  1. Terminalde aşağıdaki komutu çalıştırarak Dockerfile'ı oluşturun. Bu dosya, uygulama kapsayıcısının oluşturulmasını sağlar.
cat <<EOF > ~/gemini-cloud-assist-debug/auth_issue_demo/Dockerfile
FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY main.py .

CMD ["gunicorn", "--bind", "0.0.0.0:8080", "main:app"]
EOF
  1. Terminalde aşağıdaki komutu çalıştırarak main.py dosyasını oluşturun. Bu dosya, Python'da yazılmış uygulamayı içerir.
cat <<EOF > ~/gemini-cloud-assist-debug/auth_issue_demo/main.py
import os
import logging
from flask import Flask
from google.cloud.alloydb.connector import Connector
import sqlalchemy

app = Flask(__name__)

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Configuration from Environment Variables
# The fully qualified instance URI: projects/<PROJECT>/locations/<REGION>/clusters/<CLUSTER>/instances/<INSTANCE>
ALLOYDB_URI = os.environ.get("ALLOYDB_URI") 
DB_USER = os.environ.get("DB_USER", "auth-debug")
DB_PASS = os.environ.get("DB_PASS", "debug-auth")
DB_NAME = os.environ.get("DB_NAME", "postgres")
USE_PUBLIC_IP = os.environ.get("USE_PUBLIC_IP", "false").lower() == "true"

# Initialize Connector lazily
_connector = None

def get_connector():
    global _connector
    if _connector is None:
        _connector = Connector()
    return _connector

def getconn():
    connector = get_connector()
    ip_type = "PUBLIC" if USE_PUBLIC_IP else "PRIVATE"
    
    conn = connector.connect(
        ALLOYDB_URI,
        "pg8000",
        user=DB_USER,
        password=DB_PASS,
        db=DB_NAME,
        ip_type=ip_type
    )
    return conn

@app.route("/")
def index():
    return "AlloyDB Auth Demo. /connect to test.", 200

@app.route("/connect")
def connect_db():
    if not ALLOYDB_URI:
        return "FAILURE: ALLOYDB_URI env var is not set.", 500

    try:
        logger.info(f"Attempting connection to {ALLOYDB_URI} with user {DB_USER}...")
        
        # Create connection pool
        pool = sqlalchemy.create_engine(
            "postgresql+pg8000://",
            creator=getconn,
        )
        
        with pool.connect() as db_conn:
            # Simple query to validate connection
            result = db_conn.execute(sqlalchemy.text("SELECT NOW()")).fetchone()
            timestamp = result[0]
            
        msg = f"SUCCESS: Connected to AlloyDB! DB Time: {timestamp}"
        logger.info(msg)
        return msg, 200

    except Exception as e:
        logger.exception("Connection failed")
        # Return the error to the caller to visualize the auth failure
        return f"FAILURE: Connection Error.\nDetails: {str(e)}", 500

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))
EOF
  1. Terminalde aşağıdaki komutu çalıştırarak requirements.txt dosyasını oluşturun. Bu dosya, Python paketi gereksinimlerini işler.
cat <<EOF > ~/gemini-cloud-assist-debug/auth_issue_demo/requirements.txt
flask==3.1.3
gunicorn==25.3.0
google-cloud-alloydb-connector[pg8000]==1.12.1
sqlalchemy==2.0.49
EOF
  1. Terminalde aşağıdaki komutu çalıştırarak main.tf dosyasını oluşturun. Bu dosya, oluşturulacak Google Cloud kaynaklarını işler.
cat <<EOF > ~/gemini-cloud-assist-debug/terraform/main.tf
provider "google" {
  project = var.project_id
  region  = var.region
}

# Enable APIs
locals {
  apis = [
    "alloydb.googleapis.com",
    "run.googleapis.com",
    "artifactregistry.googleapis.com",
    "compute.googleapis.com",
    "geminicloudassist.googleapis.com",
    "monitoring.googleapis.com",
    "cloudasset.googleapis.com",
    "cloudbuild.googleapis.com",
    "recommender.googleapis.com",
    "appoptimize.googleapis.com"
  ]
}

resource "random_password" "db_pass" {
  count            = var.db_password == null ? 1 : 0
  length           = 16
  special          = true
  override_special = "!#$%&*()-_=+[]{}<>:?"
}

locals {
  db_password = var.db_password != null ? var.db_password : random_password.db_pass[0].result
}

resource "google_project_service" "apis" {
  for_each           = toset(local.apis)
  service            = each.value
  disable_on_destroy = false
}

# Service Account
resource "google_service_account" "auth_demo_sa" {
  account_id   = var.service_account_name
  display_name = "Auth Demo SA"
}

# AlloyDB Cluster
resource "google_alloydb_cluster" "rma_cluster" {
  cluster_id = var.cluster_id
  location   = var.region

  # Initial password, managed via variable or generated randomly
  initial_user {
    password = local.db_password
  }

  # Use default network as in the manual setup
  network_config {
    network = "projects/${var.project_id}/global/networks/default"
  }

  depends_on = [google_project_service.apis["alloydb.googleapis.com"]]
}

# AlloyDB Instance
resource "google_alloydb_instance" "rma_instance_1" {
  cluster       = google_alloydb_cluster.rma_cluster.name
  instance_id   = var.instance_id
  instance_type = "PRIMARY"

  machine_config {
    cpu_count = 2
  }

  network_config {
    enable_public_ip = true
  }

  depends_on = [google_alloydb_cluster.rma_cluster]
}

# Cloud Run Service
resource "google_cloud_run_service" "auth_issue_demo" {
  name     = var.cloud_run_service_name
  location = var.region

  template {
    spec {
      containers {
        image = var.cloud_run_image
        env {
          name  = "ALLOYDB_URI"
          value = "projects/${var.project_id}/locations/${var.region}/clusters/${var.cluster_id}/instances/${var.instance_id}"
        }
        env {
          name  = "DB_USER"
          value = "postgres"
        }
        env {
          name  = "DB_PASS"
          value = local.db_password
        }
        env {
          name  = "USE_PUBLIC_IP"
          value = "true"
        }
      }
      service_account_name = google_service_account.auth_demo_sa.email
    }
  }

  traffic {
    percent         = 100
    latest_revision = true
  }

  depends_on = [google_project_service.apis["run.googleapis.com"], google_alloydb_instance.rma_instance_1]
}

# Allow unauthenticated access to Cloud Run service (matching --allow-unauthenticated)
resource "google_cloud_run_service_iam_member" "public_access" {
  location = google_cloud_run_service.auth_issue_demo.location
  project  = google_cloud_run_service.auth_issue_demo.project
  service  = google_cloud_run_service.auth_issue_demo.name
  role     = "roles/run.invoker"
  member   = "allUsers"
}
EOF
  1. Terminalde aşağıdaki komutu çalıştırarak variables.tf dosyasını oluşturun. Bu dosya, Google Cloud kaynakları için Terraform değişkenlerini işler.
cat <<EOF > ~/gemini-cloud-assist-debug/terraform/variables.tf
variable "project_id" {
  description = "The ID of the Google Cloud project."
  type        = string
}

variable "region" {
  description = "The region to deploy resources in."
  type        = string
  default     = "us-central1"
}

variable "cluster_id" {
  description = "The ID of the AlloyDB cluster."
  type        = string
  default     = "rma-cluster"
}

variable "instance_id" {
  description = "The ID of the AlloyDB instance."
  type        = string
  default     = "rma-instance-1"
}

variable "service_account_name" {
  description = "The name of the service account."
  type        = string
  default     = "auth-demo-sa"
}

variable "cloud_run_service_name" {
  description = "The name of the Cloud Run service."
  type        = string
  default     = "auth-issue-demo"
}

variable "cloud_run_image" {
  description = "The container image for the Cloud Run service."
  type        = string
}

variable "db_password" {
  description = "The database password. If not provided, a random one will be generated."
  type        = string
  sensitive   = true
  default     = null
}
EOF
  1. Terminalde aşağıdaki komutu çalıştırarak setup_via_tf.sh dosyasını oluşturun. Bu dosya, Python paketi gereksinimlerini işler.
cat <<EOF > ~/gemini-cloud-assist-debug/setup_via_tf.sh
#!/bin/bash
set -e

# Get script directory and change to project root
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "$SCRIPT_DIR"

# Load configuration from .env
if [ -f .env ]; then
    set -a
    source .env
    set +a
else
    echo "ERROR: .env file not found. Please create one with PROJECT_ID."
    exit 1
fi

if [ -z "$PROJECT_ID" ]; then
    echo "ERROR: PROJECT_ID is not set in .env file."
    exit 1
fi

REGION="us-central1"
CLUSTER_ID="rma-cluster"
INSTANCE_ID="rma-instance-1"
SA_NAME="auth-demo-sa"
SERVICE_NAME="auth-issue-demo"

echo "--- Terraform Setup for Auth Demo ---"
echo "Using Project: $PROJECT_ID"

# Get current Cloud Run image
echo "Fetching current Cloud Run image..."
IMAGE=$(gcloud run services describe $SERVICE_NAME --region=$REGION --project=$PROJECT_ID --format="value(spec.template.spec.containers[0].image)" 2>/dev/null || true)

if [ -z "$IMAGE" ]; then
    echo "WARNING: Could not find existing Cloud Run service image."
    echo "Using a placeholder image (gcr.io/cloudrun/hello) for initial Terraform apply."
    IMAGE="gcr.io/cloudrun/hello"
fi

echo "Found Image: $IMAGE"

cd terraform

# Initialize Terraform
echo "Initializing Terraform..."
terraform init

echo "Formatting Terraform files..."
terraform fmt

echo "Validating Terraform configuration..."
terraform validate

echo "------------------------------------------------"
echo "Applying changes..."
echo "------------------------------------------------"

terraform apply -var="project_id=$PROJECT_ID" -var="cloud_run_image=$IMAGE" -auto-approve

echo "------------------------------------------------"
echo "Building and deploying updated Cloud Run service..."
echo "------------------------------------------------"

gcloud run deploy $SERVICE_NAME \
  --source ../auth_issue_demo \
  --region $REGION \
  --project $PROJECT_ID \
  --service-account $SA_NAME@$PROJECT_ID.iam.gserviceaccount.com \
  --quiet
EOF
  1. Kabuk komut dosyasını yürütülebilir hale getirmek için aşağıdaki komutu çalıştırın:
chmod +x ~/gemini-cloud-assist-debug/setup_via_tf.sh
  1. Dağıtım için Google Cloud proje kimliğinizi içeren bir .env dosyası oluşturun. YOUR_PROJECT_ID alanını güncelleyin:
cat <<EOF > ~/gemini-cloud-assist-debug/.env
PROJECT_ID=YOUR_PROJECT_ID
USE_PUBLIC_IP=true
EOF

6. Uygulamayı dağıtma

Uygulama kodu ve Google Cloud kaynakları dağıtıma hazır olmalıdır. Bu işlem 15 dakika kadar sürebilir.

Terminalden aşağıdaki komutu çalıştırın:

cd ~/gemini-cloud-assist-debug
./setup_via_tf.sh

Bileşenler dağıtılırken daha fazla bilgi edinmek için Cloud Shell Düzenleyici'deki dosyalara göz atın.

7. Hata oluşturma ve hataları ayıklama

Şimdi uygulamadan bir hata tetikleyeceğiz. Sol bölmede Cloud Run'ı açın. Ardından auth-issue-demo hizmetini tıklayın.

  1. Hizmet ayrıntıları sayfasının üst kısmında bir URL bulunur. URL'yi kopyalayın ve yeni bir tarayıcı sekmesi açın. URL'yi yapıştırın ve sonuna /connect ekleyin. URL'niz aşağıdaki gibi görünür:

https://auth-issue-demo-.us-central1.run.app/connect

  1. URL'ye gidin. Cloud Run örneğinin başlatılması birkaç saniye sürebilir. Hata alırsınız.
  2. Cloud Run hizmet ayrıntıları sayfasına geri dönün. Gözlemlenebilirlik'i, ardından Günlükler'i tıklayın. Hata içeren kapsayıcının günlüklerini görürsünüz. Hata günlüğü henüz kullanılamıyorsa birkaç saniye bekleyin ve sağ üstteki simgeyi kullanarak sayfayı yenileyin.
  3. Daha fazla bilgi edinmek için hata günlüğünü tıklayın. Ana günlük satırında İncele simgesini tıklayın. Ardından Günlüğü İncele'yi tıklayın.

Cloud Assist sohbet bölmesi açılır. İncelemenin tamamlanması 2-3 dakika sürer.

Araştırma tamamlandıktan sonra sonuçları ve önerileri okuyabilirsiniz. Cloud Run'ın AlloyDB örneğine erişebilmesi için hizmet hesabına uygun iznin eklenmesi önerilir.

8. Hatayı düzeltin

Hizmet hesabı izin hatasını düzeltin.

  1. Cloud IAM'e gidin.
  2. Erişim izni ver düğmesini tıklayın. Yönetici bölmesinde auth-demo yazarak başlayın ve hizmet hesabının görünmesini bekleyin.
  3. Ardından, hizmet hesabına AlloyDB Client rolünü ekleyin ve Kaydet'i tıklayın.

Bu işlemin yayılması bir dakika kadar sürer.

Bekleme süresi dolduktan sonra geri dönüp uygulamayı yenileyin. Artık AlloyDB veritabanından başarı mesajı alacaksınız.

9. Tebrikler

Tebrikler! Cloud Investigations'a ve Google Cloud'da bir uygulamanın izinlerinde hata ayıklama sürecine yönelik bu tanıtımı başarıyla tamamladınız.

Sırada ne var?