在Google Cloud上从Cloud Run访问Cloud SQL

5
我有一个通过 SQLAlchemy 访问 Cloud SQL 实例的 Cloud Run 服务。然而,在 Cloud Run 的日志中,我看到了 CloudSQL connection failed. Please see https://cloud.google.com/sql/docs/mysql/connect-run for additional details: ensure that the account has access to "<connection_string>"。转到该链接,它说:

“默认情况下,您的应用程序将使用 Cloud Run(完全托管)服务帐号对连接进行授权。服务帐户的格式为 PROJECT_NUMBER-compute@developer.gserviceaccount.com。”

但是,以下链接 (https://cloud.google.com/run/docs/securing/service-identity) 表示:

“默认情况下,Cloud Run 版本使用 Compute Engine 默认服务帐号 (PROJECT_NUMBER-compute@developer.gserviceaccount.com),该服务帐号具有项目 > 编辑器 IAM 角色。这意味着默认情况下,您的 Cloud Run 版本可以读取和写入 Google Cloud 项目中的所有资源。”

那么,这不应该意味着 Cloud Run 已经可以访问 SQL 吗?我已经在 Cloud Run 部署页面上设置了 Cloud SQL 连接。你建议我如何允许 Cloud Run 访问 Cloud SQL?

编辑:我需要启用 Cloud SQL API。


1
发布您用于连接实例的代码将会很有帮助。 - Gabe Weiss
如果您有cloudbuild.yaml文件,您能否发布一下? - Jason R Stevens CFA
2个回答

8
不,Cloud Run默认情况下不能访问Cloud SQL。您需要遵循以下两个路径之一。
1. 使用本地unix套接字文件连接SQL:您需要像您所说的那样配置权限,并使用标志部署以指示意图连接到数据库。请参考https://cloud.google.com/sql/docs/mysql/connect-run
2. 使用私有IP连接SQL:这涉及将Cloud SQL实例部署到VPC网络中,从而使其获得私有IP地址。然后,您可以使用Cloud Run VPC Access Connector(目前为beta版)允许Cloud Run容器能够连接到该VPC网络,其中包括SQL数据库的IP地址(无需IAM权限)。请参考https://cloud.google.com/vpc/docs/configure-serverless-vpc-access

-1

Cloud SQL代理解决方案

我使用cloud-sql-proxy在Cloud Build提供的workspace目录中创建本地unix套接字文件。

以下是主要步骤:

  1. 拉取一个Berglas容器,用_VAR1替换其调用,这是我使用Berglas加密的环境变量CMCREDENTIALS。您可以根据需要添加多个这样的_VAR{n}
  2. 通过wget安装cloudsqlproxy。
  3. 运行一个中间步骤(此构建的测试)。此步骤使用存储在提供的临时/workspace目录中的变量。
  4. 构建您的镜像。
  5. 推送您的镜像。
  6. 使用Cloud Run部署并包括标志--set-environment-variables

完整的cloudbuild.yaml

# basic cloudbuild.yaml
steps:
# pull the berglas container and write the secrets to temporary files 
# under /workspace
  - name: gcr.io/berglas/berglas
    id: 'Install Berglas'
    env:
    - '${_VAR1}=berglas://${_BUCKET_ID_SECRETS}/${_VAR1}?destination=/workspace/${_VAR1}'

    args: ["exec", "--", "/bin/sh"]

# install the cloud sql proxy
  - id: 'Install Cloud SQL Proxy'
    name: alpine:latest
    entrypoint: sh
    args:
      - "-c"
      - "\
      wget -O /workspace/cloud_sql_proxy \
      https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 && \
      sleep 2 && \
      chmod +x /workspace/cloud_sql_proxy"
    waitFor: ['-']

# using the secrets from above, build and run the test suite
  - name: 'python:3.8.3-slim'
    id: 'Run Unit Tests'
    entrypoint: '/bin/bash'
    args: 
      - "-c"
      - "\
      (/workspace/cloud_sql_proxy -dir=/workspace/${_SQL_PROXY_PATH} -instances=${_INSTANCE_NAME1} & sleep 2) && \
      apt-get update && apt-get install -y --no-install-recommends \
      build-essential libssl-dev libffi-dev libpq-dev python3-dev wget && \
      rm -rf /var/lib/apt/lists/* && \
      export ${_VAR1}=$(cat /workspace/${_VAR1}) && \ 
      export INSTANCE_NAME1=${_INSTANCE_NAME1} && \
      export SQL_PROXY_PATH=/workspace/${_SQL_PROXY_PATH} && \
      pip install -r dev-requirements.txt && \
      pip install -r requirements.txt && \
      python -m pytest -v && \
      rm -rf /workspace/${_SQL_PROXY_PATH} && \
      echo 'Removed Cloud SQL Proxy'"
    
    waitFor: ['Install Cloud SQL Proxy', 'Install Berglas']
    dir: '${_APP_DIR}'

# Using the application/Dockerfile build instructions, build the app image
  - name: 'gcr.io/cloud-builders/docker'
    id: 'Build Application Image'
    args: ['build',
           '-t',
           'gcr.io/$PROJECT_ID/${_IMAGE_NAME}',
           '.',
          ]
    dir: '${_APP_DIR}'

# Push the application image
  - name: 'gcr.io/cloud-builders/docker'
    id: 'Push Application Image'
    args: ['push',
           'gcr.io/$PROJECT_ID/${_IMAGE_NAME}',
          ]

# Deploy the application image to Cloud Run
# populating secrets via Berglas exec ENTRYPOINT for gunicorn
  - name: 'gcr.io/cloud-builders/gcloud'
    id: 'Deploy Application Image'
    args: ['beta', 
           'run',
           'deploy', 
           '${_IMAGE_NAME}',
           '--image',
           'gcr.io/$PROJECT_ID/${_IMAGE_NAME}',
           '--region',
           'us-central1',
           '--platform', 
           'managed',
           '--quiet',
           '--add-cloudsql-instances',
           '${_INSTANCE_NAME1}',
           '--set-env-vars',
           'SQL_PROXY_PATH=/${_SQL_PROXY_PATH},INSTANCE_NAME1=${_INSTANCE_NAME1},${_VAR1}=berglas://${_BUCKET_ID_SECRETS}/${_VAR1}',
           '--allow-unauthenticated',
           '--memory',
           '512Mi'
          ]

# Use the defaults below which can be changed at the command line
substitutions:
  _IMAGE_NAME: your-image-name
  _BUCKET_ID_SECRETS: your-bucket-for-berglas-secrets
  _INSTANCE_NAME1: project-name:location:dbname
  _SQL_PROXY_PATH: cloudsql
  _VAR1: CMCREDENTIALS


# The images we'll push here
images: [
  'gcr.io/$PROJECT_ID/${_IMAGE_NAME}'
]

Dockerfile 的使用

以下内容从位于目录 <myrepo>/application 内的源代码构建 Python 应用程序。此 Dockerfile 位于 application/Dockerfile 下。

# Use the official lightweight Python image.
# https://hub.docker.com/_/python
FROM python:3.8.3-slim

# Add build arguments
# Copy local code to the container image.
ENV APP_HOME /application

WORKDIR $APP_HOME

# Install production dependencies.
RUN apt-get update && apt-get install -y --no-install-recommends \
    build-essential \
    libpq-dev \
    python3-dev \
    libssl-dev \
    libffi-dev \
    && rm -rf /var/lib/apt/lists/*

# Copy the application source
COPY . ./

# Install Python dependencies
RUN pip install -r requirements.txt --no-cache-dir

# Grab Berglas from Google Cloud Registry
COPY --from=gcr.io/berglas/berglas:latest /bin/berglas /bin/berglas

# 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.
ENTRYPOINT exec /bin/berglas exec -- gunicorn --bind :$PORT --workers 1 --threads 8 app:app 

希望这能帮助到某些人,尽管对于原始的 OP 来说可能过于具体(Python + Berglas)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接