1. 概览
Cloud Run 是一个完全托管的无服务器平台,供您运行可通过 HTTP 请求调用的无状态容器。本 Codelab 将演示如何将 Cloud Run 上的 Node.js 应用连接到 Cloud SQL for PostgreSQL 数据库。
学习内容
在本实验中,您将学习如何完成以下操作:
- 创建 Cloud SQL for PostgreSQL 实例(配置为使用 Private Service Connect)
- 将应用部署到 Cloud Run,以连接到 Cloud SQL 数据库
- 使用 Gemini Code Assist 为应用添加功能
学习内容
- 创建 Cloud SQL for PostgreSQL 实例(配置为使用 Private Service Connect)
- 将应用部署到 Cloud Run,以连接到 Cloud SQL 数据库
- 使用 Gemini Code Assist 为应用添加功能
2. 前提条件
- 如果您还没有 Google 账号,则必须先创建一个 Google 账号。
- 请使用个人账号,而不是工作账号或学校账号。工作账号和学校账号可能会受到限制,导致您无法启用本实验所需的 API。
3. 项目设置
- 登录 Google Cloud 控制台。
- 在 Cloud 控制台中启用结算功能。
- 完成本实验所需的 Cloud 资源费用应低于 1 美元。
- 您可以按照本实验最后的步骤删除资源,以免产生更多费用。
- 新用户符合参与 300 美元免费试用的条件。
- 创建新项目或选择重复使用现有项目。
4. 打开 Cloud Shell Editor
- 前往 Cloud Shell Editor
- 如果终端未显示在屏幕底部,请打开它:
- 点击汉堡式菜单
- 点击终端
- 点击 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 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
这段代码会创建一个基本 Web 服务器,监听由 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 格式返回的最近 5 次访问记录。
10. 恭喜
在本实验中,您学习了如何执行以下操作:
- 创建 Cloud SQL for PostgreSQL 实例(配置为使用 Private Service Connect)
- 将应用部署到 Cloud Run,以连接到 Cloud SQL 数据库
- 使用 Gemini Code Assist 为应用添加功能
清理
为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。如果您想删除整个项目,可以运行以下命令:
gcloud projects delete ${GOOGLE_CLOUD_PROJECT}