نحوه اتصال یک برنامه Go در Cloud Run به یک Cloud SQL برای پایگاه داده PostgreSQL

1. بررسی اجمالی

رابط Cloud SQL Go ساده ترین راه برای اتصال ایمن برنامه Go شما به پایگاه داده Cloud SQL شما است. Cloud Run یک پلت فرم بدون سرور کاملاً مدیریت شده است که به شما امکان می دهد کانتینرهای بدون حالتی را اجرا کنید که از طریق درخواست های HTTP قابل فراخوانی هستند. این Codelab نحوه اتصال یک برنامه Go در Cloud Run را به یک پایگاه داده Cloud SQL برای PostgreSQL به طور ایمن با یک حساب سرویس با استفاده از تأیید اعتبار IAM نشان می دهد.

آنچه خواهید آموخت

در این آزمایشگاه با نحوه انجام کارهای زیر آشنا می شوید:

  • یک Cloud SQL برای پایگاه داده PostgreSQL ایجاد کنید
  • یک برنامه Go را در Cloud Run اجرا کنید
  • برنامه خود را با استفاده از Go Connector به Cloud SQL متصل کنید

پیش نیازها

  • این آزمایشگاه آشنایی با محیط های Cloud Console و Cloud Shell را فرض می کند.

2. قبل از شروع

راه اندازی پروژه ابری

  1. به Google Cloud Console وارد شوید و یک پروژه جدید ایجاد کنید یا از یک موجود استفاده مجدد کنید. اگر قبلاً یک حساب Google ندارید، باید آن را ایجاد کنید .

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • نام پروژه نام نمایشی برای شرکت کنندگان این پروژه است. این یک رشته کاراکتری است که توسط API های Google استفاده نمی شود. شما می توانید آن را در هر زمان به روز کنید.
  • شناسه پروژه در تمام پروژه‌های Google Cloud منحصربه‌فرد است و تغییرناپذیر است (پس از تنظیم نمی‌توان آن را تغییر داد). Cloud Console به طور خودکار یک رشته منحصر به فرد تولید می کند. معمولاً برای شما مهم نیست که چیست. در اکثر کدها، باید به شناسه پروژه ارجاع دهید (معمولاً به عنوان PROJECT_ID شناخته می شود). اگر شناسه تولید شده را دوست ندارید، ممکن است یک شناسه تصادفی دیگر ایجاد کنید. از طرف دیگر، می‌توانید خودتان را امتحان کنید و ببینید آیا در دسترس است یا خیر. پس از این مرحله نمی توان آن را تغییر داد و در طول مدت پروژه باقی می ماند.
  • برای اطلاع شما، یک مقدار سوم وجود دارد، یک شماره پروژه که برخی از APIها از آن استفاده می کنند. در مورد هر سه این مقادیر در مستندات بیشتر بیاموزید.
  1. در مرحله بعد، برای استفاده از منابع Cloud/APIها باید صورتحساب را در کنسول Cloud فعال کنید . اجرا کردن از طریق این کد لبه نباید هزینه زیادی داشته باشد، اگر اصلاً باشد. برای اینکه منابع را خاموش کنید تا بیش از این آموزش متحمل صورتحساب نشوید، می توانید منابعی را که ایجاد کرده اید حذف کنید یا کل پروژه را حذف کنید. کاربران جدید Google Cloud واجد شرایط برنامه آزمایشی رایگان 300 دلاری هستند.

راه اندازی محیط

Cloud Shell را با کلیک بر روی نماد سمت راست نوار جستجو فعال کنید.

ecdc43ada29e91b.png

از Cloud Shell، API ها را فعال کنید:

gcloud services enable compute.googleapis.com sqladmin.googleapis.com \
  run.googleapis.com artifactregistry.googleapis.com \
  cloudbuild.googleapis.com servicenetworking.googleapis.com

اگر از شما خواسته شد که مجوز دهید، برای ادامه روی "مجوز" کلیک کنید.

6356559df3eccdda.png

تکمیل این دستور ممکن است چند دقیقه طول بکشد، اما در نهایت باید یک پیام موفقیت آمیز مشابه این پیام تولید کند:

Operation "operations/acf.p2-327036483151-73d90d00-47ee-447a-b600-a6badf0eceae" finished successfully.

3. یک حساب سرویس راه اندازی کنید

یک حساب سرویس Google Cloud ایجاد و پیکربندی کنید تا توسط Cloud Run استفاده شود تا مجوزهای صحیح برای اتصال به Cloud SQL را داشته باشد.

  1. دستور gcloud iam service-accounts create به صورت زیر اجرا کنید تا یک حساب سرویس جدید ایجاد کنید:
    gcloud iam service-accounts create quickstart-service-account \
      --display-name="Quickstart Service Account"
    
  2. دستور add-iam-policy-binding پروژه های gcloud را به صورت زیر اجرا کنید تا نقش Cloud SQL Client را به حساب سرویس Google Cloud که ایجاد کرده اید اضافه کنید. در Cloud Shell، عبارت ${GOOGLE_CLOUD_PROJECT} با نام پروژه شما جایگزین می‌شود. اگر با آن احساس راحتی می کنید، می توانید این تعویض را به صورت دستی نیز انجام دهید.
    gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
      --member="serviceAccount:quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
      --role="roles/cloudsql.client"
    
  3. دستور add-iam-policy-binding پروژه های gcloud را به شرح زیر اجرا کنید تا نقش کاربری Cloud SQL Instance را به حساب سرویس Google Cloud که ایجاد کرده اید اضافه کنید.
    gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
      --member="serviceAccount:quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
      --role="roles/cloudsql.instanceUser"
    
  4. دستور add-iam-policy-binding پروژه های gcloud را به صورت زیر اجرا کنید تا نقش Log Writer را به حساب سرویس Google Cloud که ایجاد کرده اید اضافه کنید.
    gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
      --member="serviceAccount:quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
      --role="roles/logging.logWriter"
    

4. Cloud SQL را راه اندازی کنید

دستور gcloud sql instances create برای ایجاد یک نمونه Cloud SQL اجرا کنید.

  • –database-version : نوع و نسخه موتور پایگاه داده. اگر نامشخص باقی بماند، پیش‌فرض API استفاده می‌شود. برای مشاهده نسخه های موجود فعلی، به مستندات نسخه های پایگاه داده gcloud مراجعه کنید.
  • –cpu : تعداد هسته های مورد نظر در دستگاه.
  • –حافظه : مقدار عدد کامل که میزان حافظه مورد نظر در دستگاه را نشان می دهد. یک واحد اندازه باید ارائه شود (به عنوان مثال، 3072 مگابایت یا 9 گیگابایت). اگر هیچ واحدی مشخص نشده باشد، GB فرض می شود.
  • –region : موقعیت منطقه ای نمونه (به عنوان مثال: us-central1، asia-east1، us-east1).
  • –database-flags : اجازه تنظیم پرچم ها را می دهد. در این مورد، ما cloudsql.iam_authentication را روشن می کنیم تا Cloud Run برای اتصال به Cloud SQL با استفاده از حساب سرویسی که قبلا ایجاد کرده بودیم، فعال شود.
    gcloud sql instances create quickstart-instance \
      --database-version=POSTGRES_14 \
      --cpu=1 \
      --memory=4GB \
      --region=us-central1 \
      --database-flags=cloudsql.iam_authentication=on
    

تکمیل این دستور ممکن است چند دقیقه طول بکشد.

دستور gcloud sql databases create برای ایجاد یک پایگاه داده Cloud SQL در quickstart-instance اجرا کنید.

gcloud sql databases create quickstart_db \
  --instance=quickstart-instance

یک کاربر پایگاه داده PostgreSQL برای حساب سرویسی که قبلا ایجاد کرده اید برای دسترسی به پایگاه داده ایجاد کنید.

gcloud sql users create quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam \
  --instance=quickstart-instance \
  --type=cloud_iam_service_account

5. برنامه را آماده کنید

برنامه Go را آماده کنید که به درخواست های HTTP پاسخ دهد.

  1. در Cloud Shell یک دایرکتوری جدید به نام helloworld ایجاد کنید، سپس به آن دایرکتوری تغییر دهید:
    mkdir helloworld
    cd helloworld
    
  2. go mod init برای مقداردهی اولیه برنامه Go جدید اجرا کنید.
    go mod init github.com/GoogleCloudPlatform/golang-samples/run/helloworld
    
  3. وابستگی Cloud SQL Go Connector را نصب کنید.
    go get cloud.google.com/go/cloudsqlconn
    go get cloud.google.com/go/cloudsqlconn/postgres/pgxv4
    
  4. یک فایل main.go با کد برنامه ایجاد کنید. این کد قادر است:
    • درخواست های HTTP را بپذیرید
    • به پایگاه داده متصل شوید
    • زمان درخواست HTTP را در پایگاه داده ذخیره کنید
    • زمان پنج درخواست آخر را برگردانید
    دستور زیر را در Cloud Shell اجرا کنید:
    cat > main.go << "EOF"
    package main
    
    import (
      "database/sql"
      "encoding/json"
      "fmt"
      "log"
      "net/http"
      "os"
      "time"
    
      "cloud.google.com/go/cloudsqlconn"
      "cloud.google.com/go/cloudsqlconn/postgres/pgxv4"
    )
    
    // visitData is used to pass data to the HTML template.
    type visitData struct {
      RecentVisits []visit
    }
    
    // visit contains a single row from the visits table in the database.
    // Each visit includes a timestamp.
    type visit struct {
      VisitTime time.Time
    }
    
    // getDB creates a connection to the database
    // based on environment variables.
    func getDB() (*sql.DB, func() error) {
      cleanup, err := pgxv4.RegisterDriver("cloudsql-postgres", cloudsqlconn.WithIAMAuthN())
      if err != nil {
        log.Fatalf("Error on pgxv4.RegisterDriver: %v", err)
      }
    
      dsn := fmt.Sprintf("host=%s user=%s dbname=%s sslmode=disable", os.Getenv("INSTANCE_CONNECTION_NAME"), os.Getenv("DB_USER"), os.Getenv("DB_NAME"))
      db, err := sql.Open("cloudsql-postgres", dsn)
      if err != nil {
        log.Fatalf("Error on sql.Open: %v", err)
      }
    
      createVisits := `CREATE TABLE IF NOT EXISTS visits (
        id SERIAL NOT NULL,
        created_at timestamp NOT NULL,
        PRIMARY KEY (id)
      );`
      _, err = db.Exec(createVisits)
      if err != nil {
        log.Fatalf("unable to create table: %s", err)
      }
    
      return db, cleanup
    }
    
    func main() {
      port := os.Getenv("PORT")
      if port == "" {
        port = "8080"
      }
      log.Printf("Listening on port %s", port)
      db, cleanup := getDB()
      defer cleanup()
    
      http.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) {
        // Insert current visit
        _, err := db.Exec("INSERT INTO visits(created_at) VALUES(NOW())")
        if err != nil {
          log.Fatalf("unable to save visit: %v", err)
        }
    
        // Get the last 5 visits
        rows, err := db.Query("SELECT created_at FROM visits ORDER BY created_at DESC LIMIT 5")
        if err != nil {
          log.Fatalf("DB.Query: %v", err)
        }
        defer rows.Close()
    
        var visits []visit
        for rows.Next() {
          var visitTime time.Time
          err := rows.Scan(&visitTime)
          if err != nil {
            log.Fatalf("Rows.Scan: %v", err)
          }
          visits = append(visits, visit{VisitTime: visitTime})
        }
        response, err := json.Marshal(visitData{RecentVisits: visits})
        if err != nil {
          log.Fatalf("renderIndex: failed to parse totals with json.Marshal: %v", err)
        }
        w.Write(response)
      })
      if err := http.ListenAndServe(":"+port, nil); err != nil {
        log.Fatal(err)
      }
    }
    
    EOF
    

این کد یک وب سرور اصلی ایجاد می کند که به پورت تعریف شده توسط متغیر محیط PORT گوش می دهد. برنامه اکنون آماده استقرار است.

6. برنامه Cloud Run را مستقر کنید

دستور زیر را برای استقرار برنامه خود اجرا کنید:

  • –region : موقعیت منطقه ای نمونه (به عنوان مثال: us-central1، asia-east1، us-east1).
  • –source : کد منبعی که قرار است مستقر شود. در این مورد، . به کد منبع در پوشه فعلی helloworld اشاره دارد.
  • –set-env-vars : متغیرهای محیطی را تنظیم می کند که توسط برنامه کاربردی برای هدایت برنامه به پایگاه داده Cloud SQL استفاده می شود.
  • –service-account : استقرار Cloud Run را به حساب سرویس با مجوزهایی برای اتصال به پایگاه داده Cloud SQL ایجاد شده در ابتدای این Codelab مرتبط می کند.
  • –allow-unauthenticated : به درخواست های احراز هویت نشده اجازه می دهد تا برنامه از طریق اینترنت قابل دسترسی باشد.
gcloud run deploy helloworld \
  --region=us-central1 \
  --source=. \
  --set-env-vars INSTANCE_CONNECTION_NAME="${GOOGLE_CLOUD_PROJECT}:us-central1:quickstart-instance" \
  --set-env-vars DB_NAME="quickstart_db" \
  --set-env-vars DB_USER="quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam" \
  --service-account="quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
  --allow-unauthenticated

اگر از شما خواسته شد، y و Enter را فشار دهید تا تأیید کنید که می‌خواهید ادامه دهید:

Do you want to continue (Y/n)? y

پس از چند دقیقه، برنامه باید یک URL برای بازدید شما ارائه دهد.

برای مشاهده عملکرد برنامه خود به URL بروید. هر بار که از URL بازدید می کنید یا صفحه را بازخوانی می کنید، پنج بازدید اخیر را خواهید دید که به صورت JSON بازگردانده شده اند.

7. تبریک می گویم

شما یک برنامه Go را در Cloud Run مستقر کرده اید که می تواند به پایگاه داده PostgreSQL در حال اجرا در Cloud SQL متصل شود.

آنچه ما پوشش داده ایم:

  • ایجاد یک Cloud SQL برای پایگاه داده PostgreSQL
  • استقرار یک برنامه Go در Cloud Run
  • اتصال برنامه خود به Cloud SQL با استفاده از Go Connector

تمیز کردن

برای جلوگیری از تحمیل هزینه به حساب Google Cloud خود برای منابع استفاده شده در این آموزش، یا پروژه حاوی منابع را حذف کنید یا پروژه را نگه دارید و منابع فردی را حذف کنید. اگر می خواهید کل پروژه را حذف کنید، می توانید اجرا کنید:

gcloud projects delete ${GOOGLE_CLOUD_PROJECT}