العثور على مشاكل التطبيقات وحلّها باستخدام Gemini Cloud Assist

1- مقدمة

Gemini Cloud Assist هو وكيل متكامل الميزات يدعم أحمال عملك على Google Cloud. الوكيل هو شريكك في تصميم تطبيقات جديدة أو تعديل التطبيقات الحالية، ونشر أحمال العمل وتشغيلها في Google Cloud، وتحديد المشاكل في أحمال العمل وحلّها، وتحسينها من حيث التكلفة والأداء.

يحسّن Gemini Cloud Assist قدرتك على الاستجابة للأخطاء غير المتوقّعة وحالات التوقف.

المواضيع التي ستتعرّف عليها

  1. النشر: كيفية نشر واجهة خلفية وقاعدة بيانات أساسيتَين على Google Cloud
  2. تحديد الأخطاء وحلّها: كيفية أتمتة Gemini Cloud Assist لعملية التحقيق وتحليل السبب الجذري لمشاكل السحابة الإلكترونية والرموز البرمجية
  3. الإصلاح: كيف يساعد Gemini Cloud Assist في تحديد الإصلاحات استنادًا إلى السبب الجذري

2. إعداد المشروع

حساب Google

إذا لم يكن لديك حساب Google شخصي، عليك إنشاء حساب Google.

استخدِم حسابًا شخصيًا بدلاً من حساب تديره مؤسسة أو حساب تديره المؤسسة التعليمية.

تسجيل الدخول إلى Google Cloud Console

سجِّل الدخول إلى Google Cloud Console باستخدام حساب Google شخصي.

تفعيل الفوترة

إعداد حساب فوترة شخصي

إذا أعددت الفوترة باستخدام أرصدة Google Cloud، يمكنك تخطّي هذه الخطوة.

لإعداد حساب فوترة شخصي، انتقِل إلى هنا لتفعيل الفوترة في Cloud Console.

ملاحظات:

  • يجب أن تبلغ تكلفة إكمال هذا المختبر أقل من دولار أمريكي واحد في موارد السحابة الإلكترونية.
  • يمكنك اتّباع الخطوات في نهاية هذا المختبر لحذف الموارد وتجنُّب تحصيل المزيد من الرسوم.
  • يمكن للمستخدمين الجدد الاستفادة من فترة تجريبية مجانية بقيمة 300 دولار أمريكي.

إنشاء مشروع (اختياري)

إذا لم يكن لديك مشروع حالي تريد استخدامه لهذا المختبر، يمكنك إنشاء مشروع جديد هنا.

3. فتح محرِّر Cloud Shell

  1. انقر على هذا الرابط للانتقال مباشرةً إلى محرِّر Cloud Shell.
  2. إذا طُلب منك منح الإذن في أي وقت اليوم، انقر على منح الإذن للمتابعة.انقر لتفويض Cloud Shell
  3. إذا لم تظهر الوحدة الطرفية في أسفل الشاشة، افتحها:
    • انقر على عرض.
    • انقر على الوحدة الطرفيةفتح نافذة طرفية جديدة في "محرِّر Cloud Shell"
  4. في الوحدة الطرفية، اضبط مشروعك باستخدام هذا الأمر:
    gcloud config set project [PROJECT_ID]
    
    • مثال:
      gcloud config set project lab-project-id-example
      
    • إذا تعذّر عليك تذكُّر رقم تعريف مشروعك، يمكنك إدراج جميع أرقام تعريف مشاريعك باستخدام:
      gcloud projects list
      
      ضبط رقم تعريف المشروع في نافذة Cloud Shell Editor
  5. من المفترض أن تظهر لك هذه الرسالة:
    Updated property [core/project].
    

4. تفعيل واجهات برمجة التطبيقات

فعِّل واجهات برمجة التطبيقات التالية لمكوّنات التطبيق التي تريد نشرها، ولاستخدام Google Cloud Assist:

في الوحدة الطرفية، فعِّل واجهات برمجة التطبيقات:

```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. إعداد المشروع

ستنشئ التطبيق الأساسي وعملية النشر لاختبار Cloud Assist.

إنشاء الدليل

  1. افتح محرِّر Cloud Shell أو بيئة المطوّر التي تختارها.
  2. أنشئ مجلدًا جديدًا:
    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. في الوحدة الطرفية، شغِّل الأمر التالي لفتح مساحة عمل في محرِّر Cloud Shell:
cloudshell open-workspace ~/gemini-cloud-assist-debug

إنشاء الملفات

ستنشئ الآن ملفات البداية اللازمة للتطبيق.

  1. أنشئ ملف Dockerfile عن طريق تشغيل الأمر التالي في الوحدة الطرفية. يتولّى هذا الملف إنشاء حاوية التطبيق.
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. أنشئ الملف main.py عن طريق تشغيل الأمر التالي في الوحدة الطرفية. يحتوي هذا الملف على التطبيق المكتوب بلغة Python.
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. أنشئ الملف requirements.txt عن طريق تشغيل الأمر التالي في الوحدة الطرفية. يتولّى هذا الملف متطلبات حزمة Python.
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. أنشئ الملف main.tf عن طريق تشغيل الأمر التالي في الوحدة الطرفية. يتولّى هذا الملف موارد Google Cloud التي سيتم إنشاؤها.
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. أنشئ الملف variables.tf عن طريق تشغيل الأمر التالي في الوحدة الطرفية. يتولّى هذا الملف متغيرات Terraform لموارد Google Cloud.
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. أنشئ الملف setup_via_tf.sh عن طريق تشغيل الأمر التالي في الوحدة الطرفية. يتولّى هذا الملف متطلبات حزمة Python.
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. شغِّل الأمر التالي لجعل نص البرنامج النصي للواجهة قابلاً للتنفيذ:
chmod +x ~/gemini-cloud-assist-debug/setup_via_tf.sh
  1. أنشئ ملف ‎.env يحتوي على رقم تعريف مشروعك على Google Cloud للنشر. عدِّل الحقل YOUR_PROJECT_ID:
cat <<EOF > ~/gemini-cloud-assist-debug/.env
PROJECT_ID=YOUR_PROJECT_ID
USE_PUBLIC_IP=true
EOF

6. نشر التطبيق

الرمز البرمجي للتطبيق وموارد Google Cloud جاهزة للتفعيل. قد تستغرق هذه العملية مدة تصل إلى 15 دقيقة.

شغِّل الأمر التالي من الوحدة الطرفية:

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

أثناء نشر المكوّنات، تصفَّح الملفات في محرِّر Cloud Shell لمعرفة المزيد.

7. إنشاء خطأ وتحديد المشاكل فيه وحلّها

سنفعِّل الآن خطأً من التطبيق. افتح Cloud Run في اللوحة اليمنى. بعد ذلك، انقر على خدمة auth-issue-demo.

  1. في أعلى صفحة تفاصيل الخدمة ، يظهر عنوان URL. انسخ عنوان URL وافتح علامة تبويب متصفّح جديدة. ألصِق عنوان URL وأضِف /connect إليه. سيبدو عنوان URL على النحو التالي:

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

  1. انتقِل إلى عنوان URL. قد يستغرق بدء مثيل Cloud Run بضع ثوانٍ. سيظهر لك خطأ.
  2. ارجِع إلى صفحة تفاصيل خدمة Cloud Run. انقر على إمكانية المراقبة، ثم انقر على السجلات. ستظهر لك سجلات الحاوية، بما في ذلك الخطأ. إذا لم يكن سجلّ الأخطاء متاحًا بعد، انتظِر بضع ثوانٍ وأعِد تحميل الصفحة باستخدام الرمز في أعلى يسار الشاشة.
  3. انقر على سجلّ الأخطاء لقراءة المزيد. انقر على رمز التحقيق في سطر السجلّ الرئيسي. بعد ذلك، انقر على التحقيق في السجلّ.

سيتم فتح لوحة محادثة Cloud Assist. يستغرق التحقيق من دقيقتَين إلى 3 دقائق حتى يكتمل.

بعد اكتمال التحقيق، يمكنك قراءة النتائج والاقتراحات. هناك اقتراح بإضافة المنحة المناسبة إلى حساب الخدمة لكي يتمكّن Cloud Run من الوصول إلى مثيل AlloyDB.

8. إصلاح الخطأ

أصلِح الخطأ في إذن حساب الخدمة.

  1. انتقِل إلى Cloud IAM.
  2. انقر على الزر منح الإذن بالوصول. في لوحة "المشرف"، ابدأ بكتابة auth-demo وانتظِر ظهور حساب الخدمة.
  3. بعد ذلك، أضِف دور AlloyDB Client إلى حساب الخدمة، ثم انقر على حفظ.

قد يستغرق انتشار هذا الإجراء دقيقة واحدة.

بعد الانتظار، ارجِع وأعِد تحميل التطبيق. ستظهر لك الآن رسالة نجاح من قاعدة بيانات AlloyDB.

9- تهانينا

تهانينا! لقد أكملت بنجاح هذه المقدمة عن تحقيقات السحابة الإلكترونية وعملية تحديد المشاكل في أذونات التطبيق وحلّها على Google Cloud.

ما هي الخطوات التالية؟