使用 IAM 用户连接到 Cloud SQL

gmi*_*ile 6 postgresql google-cloud-sql cloud-sql-proxy google-cloud-iam

我无法测试在 Google Cloud 的 PostgreSQL 产品中使用 IAM 用户的能力。

这是我的思考过程:

  1. 我在 Google Cloud 上的 PostgreSQL 实例上设置了相应的标志:

    $ gcloud sql instances describe [MY_DB_INSTANCE] --format json | jq '.settings.databaseFlags'
    [
      {
        "name": "cloudsql.iam_authentication",
        "value": "on"
      }
    ]
    $
    
    Run Code Online (Sandbox Code Playgroud)
  2. 我有一个 IAM 用户,我在数据库实例中创建了该用户:

    gcloud sql users create [MY_EMAIL] --instance=[MY_DB_INSTANCE] --type=CLOUD_IAM_USER
    
    Run Code Online (Sandbox Code Playgroud)
    $ gcloud sql users list --instance [MY_DB_INSTANCE] | grep CLOUD_IAM_USER
    [MY_EMAIL]                                      CLOUD_IAM_USER
    $
    
    Run Code Online (Sandbox Code Playgroud)
  3. 当我尝试使用以下任一命令连接到数据库时,出现身份验证错误。在这两种情况下,我都使用输出gcloud auth print-access-token作为我的密码:

    • 此方法将我的 IP 添加到白名单:

      $ gcloud sql connect [MY_DB_INSTANCE] --database=[DB_NAME] --user=[MY_EMAIL]
      Allowlisting your IP for incoming connection for 5 minutes...done.
      Connecting to database with SQL user [MY_EMAIL]. Password:
      psql: error: FATAL:  Cloud SQL IAM user authentication failed for user "[MY_EMAIL]"
      FATAL:  pg_hba.conf rejects connection for host "100.200.300.400", user "[MY_EMAIL]", database "[MY_EMAIL]", SSL off
      $
      
      Run Code Online (Sandbox Code Playgroud)

      可能与失败有关,也可能无关,但这里的错误消息令人困惑。最后一行指出...database "[MY_EMAIL]",虽然显然我并没有尝试连接到与我的电子邮件同名的数据库;我正在连接到一个具有非常具体名称的数据库,例如[DB_NAME]。

      更新。截至目前,“已知问题”页面列出了对此的确认:

      以下仅适用于默认用户('postgres'):gcloud sql connect --user

    • 此方法使用 Cloud SQL 代理:

      $ gcloud beta sql connect [MY_DB_INSTANCE] --database=[DB_NAME] --user=[MY_EMAIL]
      Starting Cloud SQL Proxy: [/usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/bin/cloud_sql_proxy -instances my-project-id:europe-west1:[MY_DB_INSTANCE]=tcp:9470 -credential_file /Users/eugene/.config/gcloud/legacy_credentials/[MY_EMAIL]/adc.json]]
      2021/01/26 16:35:03 Rlimits for file descriptors set to {&{8500 9223372036854775807}}
      2021/01/26 16:35:03 using credential file for authentication; path="/Users/eugene/.config/gcloud/legacy_credentials/[MY_EMAIL]/adc.json"
      2021/01/26 16:35:04 Listening on 127.0.0.1:9470 for my-project-id:europe-west1:[MY_DB_INSTANCE]
      2021/01/26 16:35:04 Ready for new connections
      Connecting to database with SQL user [MY_EMAIL].Password:
      psql: error: FATAL:  Cloud SQL IAM user authentication failed for user "[MY_EMAIL]"
      $
      
      Run Code Online (Sandbox Code Playgroud)
  4. 如果我从 Cloud Console 检查访问日志,对于两次登录尝试,我会看到相同的错误消息:

    2021-01-26 14:20:11.988 UTC [594848]: [2-1] db=[DB_NAME],user=[MY_EMAIL] DETAIL:  Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.
    
    Run Code Online (Sandbox Code Playgroud)

此时我很失落。

也许我的期望与连接数据库的方式不一致。我期望:

  1. gcloud auth print-access-token首先根本不需要输入密码(例如 的值),因为gcloud会自动为我生成并使用密码,

  2. 如果需要手动输入密码(通过从粘贴缓冲区复制粘贴命令的输出gcloud auth print-access-token),它会起作用(虽然它不会)。

我希望通过依赖对数据库进行身份验证的 IAM 身份验证机制,我将能够避免创建用户并使用psql(或类似地使用gcloud sql users create ... --type=BUILD_IN)为其设置密码的必要性。

我可能缺少什么?

更新。如果我不使用命令,而是gcloud sql运行代理并直接使用命令,我就能够成功连接:

$ cloud_sql_proxy -instances my-project-id:europe-west1:[MY_DB_INSTANCE]=tcp:9470
2021/01/26 17:29:56 Rlimits for file descriptors set to {&{8500 9223372036854775807}}
2021/01/26 17:29:56 Listening on 127.0.0.1:9470 for my-project-id:europe-west1:[MY_DB_INSTANCE]
2021/01/26 17:29:56 Ready for new connections
Run Code Online (Sandbox Code Playgroud)
$ env PGPASSWORD=(gcloud auth print-access-token) psql --host 127.0.0.1 --port 9470 --username=[MY_EMAIL] --dbname=[MY_DB]
psql (13.1, server 13.0)
Type "help" for help.

[MY_DB]=>
Run Code Online (Sandbox Code Playgroud)

gmi*_*ile 3

经过尝试后,能够​​选择正确的连接命令。这里是:

env PGPASSWORD=(gcloud auth print-access-token) gcloud beta sql connect [MY_DB_INSTANCE] --user=[MY_EMAIL] --database=[MY_DB]
Run Code Online (Sandbox Code Playgroud)

这里的关键似乎是指定PGPASSWORD进程的变量,然后,当提示输入密码时,只需按 Enter 键

我也尝试过,并且似乎是 中的错误gcloud sql,是通过非 beta 进行连接gcloud sql connect

$ env PGPASSWORD=(gcloud auth print-access-token) gcloud sql connect [MY_DB_INSTANCE] --user=[MY_EMAIL] --database=[MY_DB]
Allowlisting your IP for incoming connection for 5 minutes...done.
Connecting to database with SQL user [MY_EMAIL].Password:
psql: error: FATAL:  database "[MY_EMAIL]" does not exist
$
Run Code Online (Sandbox Code Playgroud)

请注意它的说法database "[MY_EMAIL]" does not exist,而数据库被指定为命令行标志--database=[MY_DB]。对我来说似乎是一个错误。