如何将 IAM 服务帐号连接到 Cloud SQL 实例
Posted
技术标签:
【中文标题】如何将 IAM 服务帐号连接到 Cloud SQL 实例【英文标题】:How to connect an IAM service account to a Cloud SQL instance 【发布时间】:2021-05-09 03:28:13 【问题描述】:在 Google Cloud SQL 上,针对 PostgreSQL 的 IAM 数据库身份验证最近已普遍可用。
所以,我仔细按照这里的说明进行操作:Overview of Cloud SQL IAM database authentication。
我认为我已经正确配置了我的 Cloud SQL 实例,因为对于用户帐户,它可以正常工作。简而言之:
-
我在我的 Google Cloud 项目中使用了自己的用户帐户,并向其中添加了角色
CloudSQL Instance Viewer
我将它添加为我的 CloudSQL 实例的用户
我授予它对我数据库中所有表的所有权限
使用此处描述的命令:https://cloud.google.com/sql/docs/postgres/iam-logins,我可以登录到我的数据库:
PGPASSWORD=$(gcloud auth print-access-token) psql --host=HOSTNAME \
--username=EMAIL \
--dbname=DATABASE_NAME
太棒了!
但是现在,我真正不明白的是,它应该如何在使用服务帐户运行的应用程序中工作?医生并没有说太多。这是否意味着我必须以编程方式执行此 gcloud auth print-access-token
的等效操作并将其结果作为连接到我的数据库的密码传递?
【问题讨论】:
【参考方案1】:为了在实例上使用 IAM 用户或 IAM 服务帐户用户身份验证,用户或 SA 电子邮件(或我们在本例中处理的 SA 电子邮件片段)在使用数据库进行身份验证时替换了传统的用户名参数。
此外,密码组件也发生了变化,您无需为 IAM 用户设置密码,而是使用 OAuth2 访问令牌,客户端必须通过单独的 API 调用请求该令牌。这些访问令牌仅在过期后的 60 分钟内有效 - 但是,一旦令牌过期,它不会断开客户端连接,但如果该客户端连接断开并且必须重新连接到实例,并且已经超过一个小时,那么新的连接尝试需要提取并提供新的访问令牌。
对于这个用例,即无人参与的应用程序,服务帐户 IAM 用户是最好的选择。您的客户端实现需要使用 API client library(例如 java),它提供了一个便利类,用于通过 JSON 密钥文件(可从您的云控制台为 SA 下载)提取服务帐户凭据,即,
GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json")).createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN)).refreshIfExpired();
请注意,为了获得适当的访问令牌,范围必须设置为 Cloud SQL Admin API - 上面的示例显示了它在上述库和初始化程序的上下文中是如何工作的。请注意,必须在访问令牌为available 之前调用“refreshIfExpired()”。
拥有 GoogleCredential 实例后,您可以通过在其上调用 getAccessToken()
从中获取访问令牌,然后可以将其作为服务帐户 IAM 用户名的密码提供给您的数据库客户端的连接参数/字符串,即,
AccessToken token = credential.getAccessToken();
不过,您需要在此重点考虑的是此流程是否对您的客户端应用程序有意义。如果您的客户端应用程序通过连接池或其他一些连接管理库访问数据库,这些库会自动重试或使用静态凭证设置新连接 - 由于需要生成新的证书,使用 Postgres IAM 用户身份验证可能不合适在没有访问令牌可用(即第一次登录尝试)或访问令牌已过期的每次连接尝试中的“密码”(访问令牌)。这最终意味着在您的客户端代码中承担更多责任,以管理连接建立、在断开/关闭的连接上重新连接,并牺牲旨在在更传统的静态凭据环境中执行此操作的库的许多效率和便利性。
【讨论】:
太棒了!它工作得很好,事实上,我应该阅读更多关于服务帐户的内容。当我在 GKE 上时,我通过访问实例元数据来检索访问令牌进行了调查,我怀疑我可以达到相同的结果,但您的解决方案肯定更简单。关于您的警告,我的动机是,由于我的服务已经通过服务帐户在 GKE pod 中运行,我可以利用它连接到数据库并避免将密码存储在任何 kube 机密中。现在,你说的缺点是我必须处理令牌过期......以上是关于如何将 IAM 服务帐号连接到 Cloud SQL 实例的主要内容,如果未能解决你的问题,请参考以下文章
使用自定义服务帐号部署到 Cloud Run 失败并出现 iam.serviceaccounts.actAs 错误
如何使用 IAM Auth 将 python websocket 连接到 AppSync 订阅?