Firebase Cloud Functions无法连接到Google SQL PostgreSQL实例。

3

更新:底部添加了IAM设置的截图。

我已经尝试了以下方式但没有成功:

我在新项目中设置了Firebase Functions来运行一个express服务器,该服务器连接到PostgreSQL数据库并为API提供端点(以允许简单地从DebStroutData数据库读取记录)。

我已经授权了数据库,允许我的本地机器连接。在开发模式下它可以完美地工作。(我运行firebase serve来在本地模拟云功能。)

现在出现了问题 - 我无法在生产环境中连接到数据库。我知道原因是因为Firebase云函数实际上没有特定的IP地址,我无法在数据库中将这些IP地址列入白名单并允许连接。

所以,我已经尝试了以下步骤:

  1. 我已经将所有运行在Google中心区域的IP地址范围列入白名单:151.101.0.0/17(云函数运行在 https://[[remote-cloudfunctions-url]].cloudfunctions.net/app - 没有成功。

  2. 我尝试通过此文档 https://cloud.google.com/sql/docs/postgres/connect-functions 从Firebase内部连接到数据。这意味着创建一个服务帐户,提供适当的权限,并使用应用程序的内部实例名称作为主机:"optivois-prod:us-east1:[[postgres-instance-connection-name]]"。但这里也没有成功。

    以下是我的配置:

const Pool = require('pg').Pool
const pool = new Pool({ 
  user: '[[db_user]]',
  host: '/cloudsql/[[postgres-instance-connection-name]]/.s.PGSQL.5432',
  database: '[[db_name]]',
  password: '[[db_password]]'
})
  1. 我曾尝试为应用程序创建私有IP地址,但以另一种方式无法正常工作。

想知道是否有任何关于此问题的想法、思路或问题。

这是 Google Cloud IMA 成员的屏幕截图: 在这里输入图片描述

以下是错误堆栈(我已确保实例名称正确,并且具有访问数据库的权限):

3:52:41.541 PM
app
Function execution started 
3:52:42.862 PM
app
CloudSQL warning: your action is needed to update your function and avoid potential disruptions. Please see https://cloud.google.com/functions/docs/sql#troubleshooting for additional details: ensure that the account has access to "[[postgres-instance-connection-name]]" (and make sure there's no typo in that name). Error during createEphemeral for [[postgres-instance-connection-name]]: googleapi: Error 403: The client is not authorized to make this request., notAuthorized 
3:52:43.117 PM
app
Failed to receive message from instance optivois-prod:us-east1:postgres12-dreamfactory: ZERO_APP::1: stream aborted: server handler returned error: ERROR_NOT_AUTHORIZED: end user google account not authorized to access instance: [[postgres-instance-connection-name]] 
3:52:43.130 PM
app
Error getting residents:  Error: connect ECONNREFUSED /cloudsql/[[postgres-instance-connection-name]]/.s.PGSQL.5432 
3:52:43.130 PM
app
    at PipeConnectWrap.afterConnect [as oncomplete] (net.js:1141:16) 
3:52:43.130 PM
app
    at PipeConnectWrap.callbackTrampoline (internal/async_hooks.js:120:14) { 
3:52:43.130 PM
app
  errno: 'ECONNREFUSED', 
3:52:43.130 PM
app
  code: 'ECONNREFUSED', 
3:52:43.130 PM
app
  syscall: 'connect', 
3:52:43.130 PM
app
  address: '/cloudsql/[[postgres-instance-connection-name]]/.s.PGSQL.5432' 
3:52:43.130 PM
app
}
3:52:43.135 PM
app
TypeError: Cannot read property 'rows' of undefined
3:52:43.135 PM
app
at /workspace/queries.js:19:39
3:52:43.135 PM
app
at PendingItem.callback (/workspace/node_modules/pg-pool/index.js:352:16)
3:52:43.135 PM
app
at Client._connectionCallback (/workspace/node_modules/pg-pool/index.js:244:23)
3:52:43.135 PM
app
at Client._handleErrorWhileConnecting (/workspace/node_modules/pg/lib/client.js:305:19)
3:52:43.135 PM
app
at Client._handleErrorEvent (/workspace/node_modules/pg/lib/client.js:315:19)
3:52:43.135 PM
app
at Connection.emit (events.js:315:20)
3:52:43.135 PM
app
at Connection.EventEmitter.emit (domain.js:483:12)
3:52:43.135 PM
app
at Socket.reportStreamError (/workspace/node_modules/pg/lib/connection.js:53:12)
3:52:43.135 PM
app
at Socket.emit (events.js:315:20)
3:52:43.135 PM
app
at Socket.EventEmitter.emit (domain.js:483:12)
3:52:43.146 PM
app
Function execution took 1605 ms, finished with status: 'crash'

您是否检查了Cloud Function的服务帐户,并确保它在IAM上具有“Cloud SQL Client”角色? - Donnald Cucharo
我可以看到您创建了一个服务账户并为其分配了适当的角色,但是没有提到您已经配置了函数来使用它。默认情况下,Cloud Functions 使用 App Engine 服务账户,其格式为:PROJECT_ID@appspot.gserviceaccount.com。请检查您的函数详细信息,并查看您正在使用哪个服务账户。 - Donnald Cucharo
@DonnaldCucharo,您的意思是PROJECT_ID@appspot.gserviceaccount.com应该附加“Cloud SQL Client”角色还是其他什么?我在IAM成员列表中看到了PROJECT_ID@appspot.gserviceaccount.com,并添加了“Cloud SQL Client”和“Cloud Functions Admin”角色。我将在上面添加我的IAM成员截图。谢谢。 - akaHeimdall
刚刚注意到“从云函数连接”的文档中有这样一行:“如果授权的服务帐号属于与 Cloud SQL 实例不同的项目,请在两个项目上启用 Cloud SQL Admin API,并添加上述列出的 IAM 权限。”我正在从一个项目连接到另一个项目。看看能否进一步了解此事。 - akaHeimdall
是的,在这种情况下,您需要在两个项目中启用Cloud SQL Admin API。您能够这样做吗?阅读此线程上的答案也可能有所帮助。 - Donnald Cucharo
显示剩余3条评论
2个回答

3

为了解决这个问题,我不得不为<project-id>@appspot.gserviceaccount.com创建一个新的IAM并授予Cloud SQL Client权限。

我还通过使用socketPath: "/cloudsql/<project-id>:<region>:<instance-name>"连接SQL。


1
从图片中可以看出,您的函数部署在一个API项目上,并且您在注释中提到您的Cloud SQL实例位于另一个项目中。
要解决问题,请转到您的Cloud SQL实例所在的项目并选择IAM。您需要在其中添加您的Cloud Function正在使用的服务帐户,并在其中放置“Cloud SQL Client”角色。

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