如何將 Cloud Run 中的 Node.js 應用程式連線至 PostgreSQL 適用的 Cloud SQL 資料庫

1. 總覽

Cloud SQL Node.js 連接器是將 Node.js 應用程式安全連線至 Cloud SQL 資料庫的最簡單方式。Cloud Run 是全代管無伺服器平台,可讓您執行能透過 HTTP 要求叫用的無狀態容器。本程式碼研究室將示範如何使用 IAM 驗證機制,透過服務帳戶將 Cloud Run 上的 Node.js 應用程式安全連線至 PostgreSQL 適用的 Cloud SQL 資料庫。

學習目標

本實驗室將說明如何執行下列操作:

  • 建立 PostgreSQL 資料庫適用的 Cloud SQL 執行個體
  • 將 Node.js 應用程式部署至 Cloud Run
  • 使用 Cloud SQL Node.js 連接器程式庫,將應用程式連線至資料庫

必要條件

  • 本實驗室假設您已熟悉 Cloud 控制台和 Cloud Shell 環境。

2. 事前準備

設定 Cloud 專案

  1. 登入 Google Cloud 控制台,然後建立新專案或重複使用現有專案。如果沒有 Google 帳戶,請先建立帳戶

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • 「專案名稱」是這個專案參與者的顯示名稱。這是 Google API 未使用的字元字串。你隨時可以更新該位置資訊。
  • 專案 ID 在所有 Google Cloud 專案中都是不重複的,而且設定後即無法變更。Cloud 控制台會自動產生不重複的字串,通常您不需要在意這個字串。在大多數程式碼研究室中,您需要參照專案 ID (通常會標示為 PROJECT_ID)。如果您不喜歡產生的 ID,可以產生另一個隨機 ID。你也可以嘗試自訂名稱,看看是否可用。完成這個步驟後就無法變更,且專案期間都會維持這個設定。
  • 請注意,部分 API 會使用第三個值,也就是「專案編號」。如要進一步瞭解這三種值,請參閱說明文件
  1. 接著,您需要在 Cloud 控制台中啟用帳單,才能使用 Cloud 資源/API。完成本程式碼研究室的練習不會產生任何費用,或只會產生少量費用。如要關閉資源,避免產生本教學課程以外的費用,您可以刪除自己建立的資源,或刪除整個專案。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. 執行 gcloud projects add-iam-policy-binding 指令,將「Cloud SQL Client」(Cloud SQL 用戶端) 角色新增至您剛建立的 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. 執行下列 gcloud projects add-iam-policy-binding 指令,將「Cloud SQL Instance User」(Cloud SQL 執行個體使用者) 角色新增至您剛建立的 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. 執行下列 gcloud projects add-iam-policy-binding 指令,將「記錄檔寫入者」角色新增至您剛建立的 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:機器中所需的核心數量。
  • --memory:整數值,表示機器所需的記憶體大小。請提供大小單位 (例如 3072MB 或 9GB)。如未指定單位,系統會假設您使用的是 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_18 \
      --tier=db-custom-1-3840 \
      --region=us-central1 \
      --edition=ENTERPRISE \
      --database-flags=cloudsql.iam_authentication=on
    

這個指令可能需要幾分鐘才能完成。

執行 gcloud sql databases create 指令,在 quickstart-instance 中建立 Cloud SQL 資料庫。

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 \
  --database-roles=postgres

警告:請勿在正式版應用程式中使用 --database-roles=postgres。我們會使用這項權限,為本實驗室的程式碼提供以程式輔助方式建立及刪除資料表的必要權限。

5. 準備應用程式

準備回應 HTTP 要求的 Node.js 應用程式。

  1. 在 Cloud Shell 中建立名為 helloworld 的新目錄,然後切換至該目錄:
    mkdir helloworld
    cd helloworld
    
  2. package.json 檔案初始化為模組。
    npm init -y
    npm pkg set type="module"
    npm pkg set main="index.mjs"
    npm pkg set scripts.start="node index.mjs"
    
  3. 安裝 Cloud SQL Node.js 連接器依附元件。
    npm install @google-cloud/cloud-sql-connector
    
  4. 安裝 pg,與 PostgreSQL 資料庫互動。
    npm install pg
    
  5. 安裝 Express,接受傳入的 HTTP 要求。
    npm install express
    
  6. 建立包含應用程式程式碼的 index.mjs 檔案。這組代碼可執行下列操作:
    • 接受 HTTP 要求
    • 連線至資料庫
    • 將 HTTP 要求的時間儲存在資料庫中
    • 傳回最近五次要求的時間
    在 Cloud Shell 中執行下列指令:
    cat > index.mjs << "EOF"
    import express from 'express';
    import pg from 'pg';
    import {Connector} from '@google-cloud/cloud-sql-connector';
    
    const {Pool} = pg;
    
    const connector = new Connector();
    const clientOpts = await connector.getOptions({
        instanceConnectionName: process.env.INSTANCE_CONNECTION_NAME,
        authType: 'IAM'
    });
    
    const pool = new Pool({
        ...clientOpts,
        user: process.env.DB_USER,
        database: process.env.DB_NAME
    });
    
    const app = express();
    
    app.get('/', async (req, res) => {
      await pool.query('INSERT INTO visits(created_at) VALUES(NOW())');
      const {rows} = await pool.query('SELECT created_at FROM visits ORDER BY created_at DESC LIMIT 5');
      console.table(rows); // prints the last 5 visits
      res.send(rows);
    });
    
    const port = parseInt(process.env.PORT) || 8080;
    app.listen(port, async () => {
      console.log('process.env: ', process.env);
      await pool.query(`CREATE TABLE IF NOT EXISTS visits (
        id SERIAL NOT NULL,
        created_at timestamp NOT NULL,
        PRIMARY KEY (id)
      );`);
      console.log(`helloworld: listening on port ${port}`);
    });
    
    EOF
    

這段程式碼會建立基本的網路伺服器,用於監聽 PORT 環境變數定義的通訊埠。應用程式現在已可部署。

6. 部署 Cloud Run 應用程式

執行下列指令,將應用程式部署至 Cloud Run:

  • --region:執行個體的區域位置 (例如:us-central1、asia-east1、us-east1)。
  • --source:要部署的原始碼。在本例中,. 是指目前資料夾 helloworld 中的原始碼。
  • --set-env-vars:設定應用程式使用的環境變數,將應用程式導向 Cloud SQL 資料庫。
  • --service-account:將 Cloud Run 部署作業繫結至服務帳戶,該帳戶具有連線至本程式碼實驗室開頭建立的 Cloud SQL 資料庫的權限。
  • --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

如果系統提示您確認是否要繼續,請按下 yEnter

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

幾分鐘後,應用程式應會提供網址供您造訪。

前往該網址,即可查看應用程式的運作情形。每次造訪網址或重新整理頁面時,系統都會以 JSON 格式傳回最近五次造訪記錄。

7. 恭喜

您已在 Cloud Run 上部署 Node.js 應用程式,該應用程式可連線至在 Cloud SQL 上執行的 PostgreSQL 資料庫。

涵蓋內容:

  • 建立 PostgreSQL 適用的 Cloud SQL 資料庫
  • 將 Node.js 應用程式部署至 Cloud Run
  • 使用 Cloud SQL Node.js 連接器將應用程式連線至 Cloud SQL

清除所用資源

如要避免系統向您的 Google Cloud 帳戶收取本教學課程所用資源的費用,請刪除含有相關資源的專案,或者保留專案但刪除個別資源。如要刪除整個專案,請執行:

gcloud projects delete ${GOOGLE_CLOUD_PROJECT}