1. 總覽
Cloud Run 是全代管無伺服器平台,能夠讓您執行可透過 HTTP 要求叫用的無狀態容器。本程式碼研究室將示範如何將 Cloud Run 上的 Node.js 應用程式連結至 PostgreSQL 適用的 Cloud SQL 資料庫。
學習目標
本實驗室的學習內容包括:
- 建立 PostgreSQL 適用的 Cloud SQL 執行個體 (已設定為使用 Private Service Connect)
- 將可連線至 Cloud SQL 資料庫的應用程式部署至 Cloud Run
- 使用 Gemini Code Assist 為應用程式新增功能
學習目標
- 建立 PostgreSQL 適用的 Cloud SQL 執行個體 (已設定為使用 Private Service Connect)
- 將可連線至 Cloud SQL 資料庫的應用程式部署至 Cloud Run
- 使用 Gemini Code Assist 為應用程式新增功能
2. 先決條件
- 如果您還沒有 Google 帳戶,請務必建立 Google 帳戶。
- 請改用個人帳戶,而非公司或學校帳戶。工作和學校帳戶可能有限制,導致您無法啟用本實驗室所需的 API。
3. 專案設定
- 登入 Google Cloud 控制台。
- 在 Cloud 控制台中啟用帳單。
- 完成本研究室所需的 Cloud 資源費用應低於 $1 美元。
- 您可以按照本實驗室課程結尾的步驟刪除資源,避免產生其他費用。
- 新使用者可享有價值 $300 美元的免費試用期。
- 建立新專案或選擇重複使用現有專案。
4. 開啟 Cloud Shell 編輯器
- 前往 Cloud Shell 編輯器
- 如果終端機未顯示在畫面底部,請開啟:
- 按一下漢堡選單
- 按一下「Terminal」
- 按一下「New Terminal」
- 按一下漢堡選單
- 在終端機中,使用以下指令設定專案:
- 格式:
gcloud config set project [PROJECT_ID]
- 範例:
gcloud config set project lab-project-id-example
- 如果您不記得專案 ID:
- 您可以使用下列指令列出所有專案 ID:
gcloud projects list | awk '/PROJECT_ID/{print $2}'
- 您可以使用下列指令列出所有專案 ID:
- 格式:
- 如果出現授權提示訊息,請點選「授權」繼續操作。
- 您應該會看到下列訊息:
如果您看到Updated property [core/project].
WARNING
並收到Do you want to continue (Y/N)?
要求,表示您可能輸入的專案 ID 有誤。按下N
和Enter
鍵,然後再次嘗試執行gcloud config set project
指令。
5. 啟用 API
在終端機中啟用 API:
gcloud services enable \
compute.googleapis.com \
sqladmin.googleapis.com \
run.googleapis.com \
artifactregistry.googleapis.com \
cloudbuild.googleapis.com \
networkconnectivity.googleapis.com \
servicenetworking.googleapis.com \
cloudaicompanion.googleapis.com
如果出現授權提示訊息,請點選「授權」繼續操作。
這個指令可能需要幾分鐘才能完成,但最終應該會顯示類似以下的成功訊息:
Operation "operations/acf.p2-73d90d00-47ee-447a-b600" finished successfully.
6. 設定服務帳戶
建立並設定 Cloud Run 可使用的 Google Cloud 服務帳戶,讓 Cloud Run 取得連線至 Cloud SQL 的正確權限。
- 請執行以下
gcloud iam service-accounts create
指令,建立新的服務帳戶:gcloud iam service-accounts create quickstart-service-account \ --display-name="Quickstart Service Account"
- 執行以下 gcloud projects add-iam-policy-binding 指令,將「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"
7. 建立 Cloud SQL 執行個體
- 建立服務連線政策,透過 Private Service Connect 允許 Cloud Run 與 Cloud SQL 之間的網路連線
gcloud network-connectivity service-connection-policies create quickstart-policy \ --network=default \ --project=${GOOGLE_CLOUD_PROJECT} \ --region=us-central1 \ --service-class=google-cloud-sql \ --subnets=https://www.googleapis.com/compute/v1/projects/${GOOGLE_CLOUD_PROJECT}/regions/us-central1/subnetworks/default
- 為資料庫產生專屬密碼
export DB_PASSWORD=$(openssl rand -base64 20)
- 執行
gcloud sql instances create
指令建立 Cloud SQL 執行個體gcloud sql instances create quickstart-instance \ --project=${GOOGLE_CLOUD_PROJECT} \ --root-password=${DB_PASSWORD} \ --database-version=POSTGRES_17 \ --tier=db-perf-optimized-N-2 \ --region=us-central1 \ --ssl-mode=ENCRYPTED_ONLY \ --no-assign-ip \ --enable-private-service-connect \ --psc-auto-connections=network=projects/${GOOGLE_CLOUD_PROJECT}/global/networks/default
這個指令可能需要幾分鐘才能完成。
- 執行
gcloud sql databases create
指令,在quickstart-instance
中建立 Cloud SQL 資料庫。gcloud sql databases create quickstart_db \ --instance=quickstart-instance
8. 準備申請
準備可回應 HTTP 要求的 Node.js 應用程式。
- 在 Cloud Shell 中建立名為
helloworld
的新目錄,然後切換至該目錄:mkdir helloworld cd helloworld
- 將
package.json
檔案初始化為模組。npm init -y npm pkg set type="module" npm pkg set main="index.mjs" npm pkg set scripts.start="node index.mjs"
- 安裝
pg
與 PostgreSQL 資料庫互動。npm install pg
- 安裝 Express,以便接受傳入的 HTTP 要求。
npm install express
- 使用應用程式程式碼建立
index.mjs
檔案。這段程式碼可執行以下操作:- 接受 HTTP 要求
- 連線至資料庫
- 將 HTTP 要求的時間儲存在資料庫中
- 傳回最近五次要求的時間
cat > index.mjs << "EOF" import express from 'express'; import pg from 'pg'; const { Pool } = pg; const pool = new Pool({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, ssl: { require: true, rejectUnauthorized: false, // required for self-signed certs // https://node-postgres.com/features/ssl#self-signed-cert } }); 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 環境變數定義的通訊埠。應用程式現在已準備就緒,可以部署了。
9. 將應用程式部署至 Cloud Run
- 執行 gcloud projects add-iam-policy-binding 指令,如以下所示,將「Network User」角色新增至 Cloud Run 服務帳戶,以便為您要建立的 Cloud Run 服務建立政策。
gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \ --member "serviceAccount:service-$(gcloud projects describe ${GOOGLE_CLOUD_PROJECT} --format="value(projectNumber)")@serverless-robot-prod.iam.gserviceaccount.com" \ --role "roles/compute.networkUser"
- 執行下列指令,將應用程式部署至 Cloud Run:
gcloud run deploy helloworld \ --region=us-central1 \ --source=. \ --set-env-vars DB_NAME="quickstart_db" \ --set-env-vars DB_USER="postgres" \ --set-env-vars DB_PASSWORD=${DB_PASSWORD} \ --set-env-vars DB_HOST="$(gcloud sql instances describe quickstart-instance --project=${GOOGLE_CLOUD_PROJECT} --format='value(settings.ipConfiguration.pscConfig.pscAutoConnections.ipAddress)')" \ --service-account="quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \ --network=default \ --subnet=default \ --allow-unauthenticated
- 如有提示,請按下
Y
和Enter
鍵,確認要繼續操作:Do you want to continue (Y/n)? Y
幾分鐘後,應用程式應會提供網址供您造訪。
前往該網址,查看應用程式的運作情形。每次造訪網址或重新整理頁面時,系統都會以 JSON 格式傳回最近五次的造訪記錄。
10. 恭喜
在本研究室中,您已瞭解如何執行下列作業:
- 建立 PostgreSQL 適用的 Cloud SQL 執行個體 (已設定為使用 Private Service Connect)
- 將可連線至 Cloud SQL 資料庫的應用程式部署至 Cloud Run
- 使用 Gemini Code Assist 為應用程式新增功能
清除所用資源
如要避免系統向您的 Google Cloud 帳戶收取本教學課程所用資源的費用,請刪除含有相關資源的專案,或者保留專案但刪除個別資源。如要刪除整個專案,您可以執行以下指令:
gcloud projects delete ${GOOGLE_CLOUD_PROJECT}