使用 Cloud Run 连接到 Cloud SQL

了解如何使用 Cloud Run(全代管式)连接到 Cloud SQL。

如果您符合以下条件,本教程将对您有所帮助:

  • 在 Cloud Run(全代管式)上运行应用。
  • 使用 Cloud SQL 作为数据库。

准备工作

  1. 登录您的 Google Cloud 帐号。如果您是 Google Cloud 新手,请创建一个帐号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
  2. 在 Google Cloud Console 的项目选择器页面上,选择或创建一个 Google Cloud 项目。

    转到“项目选择器”

  3. 确保您的 Cloud 项目已启用结算功能。 了解如何确认您的项目是否已启用结算功能

  4. 在 Google Cloud Console 的项目选择器页面上,选择或创建一个 Google Cloud 项目。

    转到“项目选择器”

  5. 确保您的 Cloud 项目已启用结算功能。 了解如何确认您的项目是否已启用结算功能

创建实例

在此过程中,您将使用 Cloud Console。如需使用 gcloud 命令行工具、cURL 或 PowerShell,请参阅创建实例

  1. 转到 Google Cloud Console 中的“Cloud SQL 实例”页面。

    转到“Cloud SQL 实例”页面

  2. 选择您的项目并点击继续

  3. 点击创建实例

  4. 点击 MySQL

  5. 实例 ID 部分输入 myinstance

  6. 为根用户输入密码。

  7. 对于其他字段,请使用默认值。

  8. 点击创建

    您将返回到实例列表;您可以立即点击进入新实例来查看详细信息,但该实例只能在初始化并启动之后才可用。

在 Cloud Shell 中使用 mysql 客户端连接到实例

  1. Google Cloud Console 中,点击右上角的 Cloud Shell 图标 (Cloud Shell 图标)。

    Cloud Shell 完成初始化后,将显示以下内容:

    Welcome to Cloud Shell! Type "help" to get started.
    username@example-id:~$
    

  2. 在 Cloud Shell 提示符下,连接到您的 Cloud SQL 实例:

    gcloud sql connect myinstance --user=root
    
  3. 输入您的根密码。

    系统会显示 mysql 提示符。

创建数据库并上传数据

  1. 在 Cloud SQL 实例上创建 SQL 数据库:
    CREATE DATABASE guestbook;
    
  2. 将示例数据插入到留言板数据库中:
    USE guestbook;
    CREATE TABLE entries (guestName VARCHAR(255), content VARCHAR(255),
        entryID INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(entryID));
        INSERT INTO entries (guestName, content) values ("first guest", "I got here!");
        INSERT INTO entries (guestName, content) values ("second guest", "Me too!");
    
  3. 检索数据:
    SELECT * FROM entries;
    
    生成的查询结果是:
    +--------------+-------------------+---------+
    | guestName    | content           | entryID |
    +--------------+-------------------+---------+
    | first guest  | I got here!       |       1 |
    | second guest | Me too!           |       2 |
    +--------------+-------------------+---------+
    2 rows in set (0.00 sec)
    mysql>
    

获取实例连接名称

  1. 转到 Google Cloud Console 中的“Cloud SQL 实例”页面。

    转到“Cloud SQL 实例”页面

  2. 点击实例名称,以打开其实例详情页面。

  3. 连接到此实例下,记下实例连接名称

启用 Cloud SQL Admin API

启用 API

为 Cloud Run(全托管式)配置服务帐号

  • 确保之前创建的实例具有公共 IP 地址。您可以在 Google Cloud Console 中的实例概览页面上验证这一点。如果您需要添加 IP 地址,请参阅配置公共 IP 页面来查看相关说明。
  • 获取实例的 INSTANCE_CONNECTION_NAME。您可以在 Google Cloud Console 中的实例概览页面上找到它,也可以通过运行命令 gcloud sql instances describe [INSTANCE_NAME] 来获取。
  • 为您的服务配置服务帐号。请确保该服务帐号具有适当的 Cloud SQL 角色和权限以连接到 Cloud SQL
      您的服务的服务帐号需要以下某个 IAM 角色
      • Cloud SQL Client(首选)
      • Cloud SQL Editor
      • Cloud SQL Admin
      或者,您也可以手动分配下列 IAM 权限:
      • cloudsql.instances.connect
      • cloudsql.instances.get

    如果授权服务帐号与 Cloud SQL 实例分处不同的项目,则需要为这两个项目添加 Cloud SQL Admin API 和 IAM 权限。

与任何配置更改一样,为 Cloud SQL 连接设置新配置会导致创建新的 Cloud Run 修订版本。除非您进行了明确更新,否则后续修订版本也将自动采用此 Cloud SQL 连接。

控制台

  1. 转到 Cloud Run

  2. 配置服务:

    • 如果您要向新服务添加 Cloud SQL 连接,请执行以下操作:

      • 您需要将服务容器化并上传到 Container Registry。如果您还没有容器映像,请参阅这些有关构建和部署容器映像的说明。

      • 点击创建服务

    • 如果您要向现有服务添加 Cloud SQL 连接,请执行以下操作:

      • 点击服务名称。

      • 点击部署新的修订版本

  3. 启用连接到 Cloud SQL:

    • 点击显示可选设置

    添加 Cloud SQL 连接

    • 如果您是在向自己项目中的 Cloud SQL 实例添加连接,请从下拉菜单中选择所需的 Cloud SQL 实例。
    • 如果您使用的是来自其他项目的 Cloud SQL 实例,请在下拉列表中选择自定义连接字符串,然后以 PROJECT-ID:REGION:INSTANCE-ID 格式输入完整实例连接名称。

    • 如果您要删除连接,请将光标悬停在连接右侧以显示垃圾箱图标,然后点击该图标。

  4. 点击创建部署

命令行

在使用下面的任何命令之前,请先进行以下替换:

  • IMAGE 替换为您要部署的映像
  • SERVICE-NAME 替换为您的 Cloud Run 服务的名称
  • INSTANCE-CONNECTION-NAME 替换为 Cloud SQL 实例的实例连接名称,或以英文逗号分隔的连接名称列表。

    如果要部署新容器,请使用以下命令:

    gcloud run deploy --image IMAGE \
      --add-cloudsql-instances INSTANCE-CONNECTION-NAME \
      --update-env-vars INSTANCE_CONNECTION_NAME="INSTANCE-CONNECTION-NAME"
    如果要更新现有服务,请使用以下命令:
    gcloud run services update SERVICE-NAME \
      --add-cloudsql-instances INSTANCE-CONNECTION-NAME \
      --update-env-vars INSTANCE_CONNECTION_NAME="INSTANCE-CONNECTION-NAME"
Cloud Run(全代管式)使用服务帐号来授权您连接到 Cloud SQL。此服务帐号必须具有正确的 IAM 权限才能成功连接。除非另行配置,否则默认服务帐号采用 PROJECT_NUMBER-compute@developer.gserviceaccount.com 格式。

您可以控制其他应用或客户端能否连接到您的 Cloud SQL 实例。如需了解详情,请参阅身份验证选项,确定允许谁连接到您的实例以及从何处进行连接。

在连接属于两个不同项目的资源时,请确保这两个项目均已启用正确的 IAM 角色,且已向服务帐号授予正确的权限。

确保您的服务帐号具有下列其中一个 IAM 角色

  • Cloud SQL Client(首选)
  • Cloud SQL Editor
  • Cloud SQL Admin

或者,您也可以手动分配下列 IAM 权限

  • cloudsql.instances.connect
  • cloudsql.instances.get

如需详细了解如何将 IAM 角色添加到服务帐号,请参阅将角色授予服务帐号

准备代码

以下是连接到 Cloud SQL 数据库所需的所有 Cloud Run(全代管式)代码。某些变量值取决于您自己的数据库信息。

本教程使用 Python 3.7+。

requirements.txt 中的设置会指示 Python 需要导入哪些模块:

SQLAlchemy==1.3.12

PyMySQL==0.9.3

Dockerfile 使用官方轻量级 Python 映像:

# https://hub.docker.com/_/python
FROM python:3.7-slim

COPY requirements.txt ./

# Install production dependencies.
RUN set -ex; \
    pip install -r requirements.txt; \
    pip install gunicorn

# Copy local code to the container image.
ENV APP_HOME /app
WORKDIR $APP_HOME
COPY . ./

# Install production dependencies.
RUN pip install Flask gunicorn

# Run the web service on container startup. Here we use the gunicorn
# webserver, with one worker process and 8 threads.
# For environments with multiple CPU cores, increase the number of workers
# to be equal to the cores available.
CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 main:app

main.py 文件包含本教程中使用的所有代码:

import os
import sqlalchemy

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():

  # Set the following variables depending on your specific
  # connection name and root password from the earlier steps:
  connection_name = "[INSTANCE_CONNECTION_NAME]"
  db_password = "[DATABASE_USER_PASSWORD]"
  db_name = "guestbook"

  db_user = "root"
  driver_name = 'mysql+pymysql'
  query_string = dict({"unix_socket": "/cloudsql/{}".format(connection_name)})

  db = sqlalchemy.create_engine(
    sqlalchemy.engine.url.URL(
      drivername=driver_name,
      username=db_user,
      password=db_password,
      database=db_name,
      query=query_string,
    ),
    pool_size=5,
    max_overflow=2,
    pool_timeout=30,
    pool_recycle=1800
  )

  stmt = sqlalchemy.text("INSERT INTO entries (guestName, content) values ('another guest', 'Also this one');")
  try:
    with db.connect() as conn:
      conn.execute(stmt)
  except Exception as e:
    return 'Error: {}'.format(str(e))
  return 'Hello! You wrote something into your database!\n'

if __name__ == "__main__":
    app.run(debug=True,host='0.0.0.0',port=int(os.environ.get('PORT', 8080)))

service.yaml 文件定义应用名称和 Docker 容器:

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: run-sql
  namespace: default
spec:
  template:
    spec:
      containers:
      - image: gcr.io/PROJECT_ID/run-sql
        env:
        - name: TARGET
          value: "Python Sample v1"

.dockerignore 文件告知 Docker 忽略哪些文件:

Dockerfile
README.md
*.pyc
*.pyo
*.pyd
__pycache__

构建、提交和部署容器

  1. 创建一个新目录。
  2. 将上述步骤中的以下文件复制到新目录中:
    • requirements.txt
    • Dockerfile
    • main.py
    • service.yaml
    • .dockerfile
  3. 替换 service.yaml 文件中的变量 PROJECT_ID,并在 main.py 中设置特定于数据库的值。
  4. 构建容器映像:
    gcloud builds submit --tag gcr.io/[PROJECT_ID]/run-sql
       
  5. 将服务部署到 Cloud Run(全代管式):
    gcloud run deploy run-sql --image gcr.io/[PROJECT_ID]/run-sql
       

    在部署过程结束时记下输出的网址

  6. 配置服务以与 Cloud Run(全代管式)搭配使用:
    
    gcloud run services update run-mysql \
      --add-cloudsql-instances [INSTANCE_CONNECTION_NAME] \
      --set-env-vars CLOUD_SQL_CONNECTION_NAME=[INSTANCE_CONNECTION_NAME],\
      DB_USER=root,DB_PASS=[DATABASE_USER_PASSWORD],DB_NAME=guestbook
    
       

    使用正确的 Cloud SQL 配置值替换变量

测试应用

  1. 在浏览器中,转到上述第 5 步中记下的网址。
  2. 验证您是否看到以下消息:Hello! You wrote something into your database
  3. 连接到您的数据库并输入 select * from guestbook 以查看新条目。

清理

为避免系统因本教程中使用的资源向您的 Google Cloud 帐号收取费用,请按照以下步骤操作:

  1. 转到 Google Cloud Console 中的“Cloud SQL 实例”页面。
    转到“Cloud SQL 实例”页面
  2. 选择 myinstance 实例以打开实例详情页面。
  3. 在页面顶部的图标栏中,点击删除
  4. 删除实例窗口中输入 myinstance,然后点击删除以删除该实例。

    在删除实例后的大约 7 天内,您不能重新使用相应的实例名称。

后续步骤