本页面介绍如何将使用 IAM 数据库身份验证的用户或服务账号添加到数据库,以及如何管理这些用户和服务账号。如需详细了解 IAM 集成,请参阅 IAM 身份验证。
准备工作
- 登录您的 Google Cloud 账号。如果您是 Google Cloud 新手,请创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
- 安装 Google Cloud CLI。
-
如需初始化 gcloud CLI,请运行以下命令:
gcloud init
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
- 安装 Google Cloud CLI。
-
如需初始化 gcloud CLI,请运行以下命令:
gcloud init
-
启用 Cloud Key Management Service API。
- 确保您的用户账号具有 Cloud SQL Admin 角色。
- 在 Cloud SQL 实例上启用 IAM 数据库身份验证。
- 对于包含用户需要访问的数据库的每个项目,请确保向需要该权限的用户授予 IAM 访问权限。请参阅授予、更改和撤消对资源的访问权限。
- 确保您已为需要访问项目中的数据库的每个服务添加了服务账号。
将 IAM 用户或服务账号添加到数据库实例
对于您要有权访问数据库实例的每位 IAM 用户,您都必须为其创建一个新的数据库用户。数据库用户名必须是 IAM 用户的电子邮件地址,例如 test-user@example.com
。
@
和 .
)。
服务账号使用 service-account-name@project-id.iam.gserviceaccount.com
格式。
如需添加 IAM 用户或服务账号,您需要添加新的数据库用户并选择 IAM 作为身份验证方法:
控制台
-
在 Google Cloud 控制台中,转到 Cloud SQL 实例页面。
- 如需打开实例的概览页面,请点击实例名称。
- 从 SQL 导航菜单中选择用户。
- 点击添加用户账号。系统会打开将用户账号添加到实例 instance_name 标签页。
- 点击 Cloud IAM 单选按钮。
- 在主账号字段中添加要添加的用户或服务账号的电子邮件地址。
- 点击添加。该用户现在位于用户列表中。
如果未将用户分配给 Cloud SQL Instance User 角色,则用户名左侧会显示一个 图标。
如需向用户授予登录权限,请点击该图标,然后选择添加 IAM 角色。图标不会再出现。该用户现在是该角色的成员。
gcloud
创建用户账号
使用电子邮件地址(如 test-user@example.com
)来标识用户。
请替换以下内容:
- USERNAME:用户的电子邮件地址。
- INSTANCE_NAME:您要向用户授予访问权限的实例的名称。
gcloud sql users create USERNAME \ --instance=INSTANCE_NAME \ --type=cloud_iam_user
创建服务账号
替换以下内容:
- SERVICE_ACCT:服务账号的电子邮件地址。
- INSTANCE_NAME:您要向服务账号授予访问权限的实例的名称。
gcloud sql users create SERVICE_ACCT \ --instance=INSTANCE_NAME \ --type=cloud_iam_service_account
Terraform
如需在启用了 IAM 数据库身份验证的实例上添加 IAM 用户和服务账号,请使用 Terraform 资源。
应用更改
如需在 Google Cloud 项目中应用 Terraform 配置,请完成以下部分中的步骤。
准备 Cloud Shell
- 启动 Cloud Shell。
-
设置要在其中应用 Terraform 配置的默认 Google Cloud 项目。
您只需为每个项目运行一次以下命令,即可在任何目录中运行它。
export GOOGLE_CLOUD_PROJECT=PROJECT_ID
如果您在 Terraform 配置文件中设置显式值,则环境变量会被替换。
准备目录
每个 Terraform 配置文件都必须有自己的目录(也称为“根模块”)。
-
在 Cloud Shell 中,创建一个目录,并在该目录中创建一个新文件。文件名必须具有
.tf
扩展名,例如main.tf
。在本教程中,该文件称为main.tf
。mkdir DIRECTORY && cd DIRECTORY && touch main.tf
-
如果您按照教程进行操作,可以在每个部分或步骤中复制示例代码。
将示例代码复制到新创建的
main.tf
中。(可选)从 GitHub 中复制代码。如果端到端解决方案包含 Terraform 代码段,则建议这样做。
- 查看和修改要应用到您的环境的示例参数。
- 保存更改。
-
初始化 Terraform。您只需为每个目录执行一次此操作。
terraform init
(可选)如需使用最新的 Google 提供程序版本,请添加
-upgrade
选项:terraform init -upgrade
应用更改
-
查看配置并验证 Terraform 将创建或更新的资源是否符合您的预期:
terraform plan
根据需要更正配置。
-
通过运行以下命令并在提示符处输入
yes
来应用 Terraform 配置:terraform apply
等待 Terraform 显示“应用完成!”消息。
- 打开您的 Google Cloud 项目以查看结果。在 Google Cloud 控制台的界面中找到资源,以确保 Terraform 已创建或更新它们。
删除更改
如需删除更改,请执行以下操作:
- 如需停用删除防护,请在 Terraform 配置文件中将
deletion_protection
参数设置为false
。deletion_protection = "false"
- 运行以下命令并在提示符处输入
yes
,以应用更新后的 Terraform 配置:terraform apply
-
运行以下命令并在提示符处输入
yes
,以移除之前使用 Terraform 配置应用的资源:terraform destroy
REST v1
创建用户账号
在使用任何请求数据之前,请先进行以下替换:
- project-id:您的项目 ID
- instance-id:您要向其添加用户的实例的 ID
- username:用户的电子邮件地址
- operation-id:操作的 ID
HTTP 方法和网址:
POST https://sqladmin.googleapis.com/v1/projects/project-id/instances/instance-id/users
请求 JSON 正文:
{ "name": "username", "type": "CLOUD_IAM_USER" }
如需发送您的请求,请展开以下选项之一:
您应该收到类似以下内容的 JSON 响应:
{ "kind": "sql#operation", "targetLink": "https://sqladmin.googleapis.com/v1/projects/project-id/instances/instance-id", "status": "DONE", "user": "user@example.com", "insertTime": "2020-02-07T22:44:16.656Z", "startTime": "2020-02-07T22:44:16.686Z", "endTime": "2020-02-07T22:44:20.437Z", "operationType": "CREATE_USER", "name": "operation-id", "targetId": "instance-id", "selfLink": "https://sqladmin.googleapis.com/v1/projects/project-id/operations/operation-id", "targetProject": "project-id" }
创建服务账号
在使用任何请求数据之前,请先进行以下替换:
- service-acct:您的服务账号电子邮件地址
- project-id:您的项目 ID
- instance-id:您要向其添加服务账号的实例的 ID
- operation-id:操作的 ID
HTTP 方法和网址:
POST https://sqladmin.googleapis.com/v1/projects/project-id/instances/instance-id/users
请求 JSON 正文:
{ "name": "service-acct", "type": "CLOUD_IAM_SERVICE_ACCOUNT" }
如需发送您的请求,请展开以下选项之一:
您应该收到类似以下内容的 JSON 响应:
{ "kind": "sql#operation", "targetLink": "https://sqladmin.googleapis.com/v1/projects/project-id/instances/instance-id", "status": "DONE", "user": "user@example.com", "insertTime": "2020-11-20T04:08:00.211Z", "startTime": "2020-11-20T04:08:00.240Z", "endTime": "2020-11-20T04:08:02.003Z", "operationType": "CREATE_USER", "name": "operation-id", "targetId": "instance-id", "selfLink": "https://sqladmin.googleapis.com/v1/projects/project-id/operations/operation-id", "targetProject": "project-id" }
REST v1beta4
创建用户账号
在使用任何请求数据之前,请先进行以下替换:
- project-id:您的项目 ID
- instance-id:您要向其添加用户的实例的 ID
- username:用户的电子邮件地址
- operation-id:操作的 ID
HTTP 方法和网址:
POST https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/instances/instance-id/users
请求 JSON 正文:
{ "name": "username", "type": "CLOUD_IAM_USER" }
如需发送您的请求,请展开以下选项之一:
您应该收到类似以下内容的 JSON 响应:
{ "kind": "sql#operation", "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/instances/instance-id", "status": "DONE", "user": "user@example.com", "insertTime": "2020-02-07T22:44:16.656Z", "startTime": "2020-02-07T22:44:16.686Z", "endTime": "2020-02-07T22:44:20.437Z", "operationType": "CREATE_USER", "name": "operation-id", "targetId": "instance-id", "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/operations/operation-id", "targetProject": "project-id" }
创建服务账号
在使用任何请求数据之前,请先进行以下替换:
- service-acct:您的服务账号电子邮件地址
- project-id:您的项目 ID
- instance-id:您要向其添加服务账号的实例的 ID
- operation-id:操作的 ID
HTTP 方法和网址:
POST https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/instances/instance-id/users
请求 JSON 正文:
{ "name": "service-acct", "type": "CLOUD_IAM_SERVICE_ACCOUNT" }
如需发送您的请求,请展开以下选项之一:
您应该收到类似以下内容的 JSON 响应:
{ "kind": "sql#operation", "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/instances/instance-id", "status": "DONE", "user": "user@example.com", "insertTime": "2020-11-20T04:08:00.211Z", "startTime": "2020-11-20T04:08:00.240Z", "endTime": "2020-11-20T04:08:02.003Z", "operationType": "CREATE_USER", "name": "operation-id", "targetId": "instance-id", "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/operations/operation-id", "targetProject": "project-id" }
向用户或服务账号添加 IAM 政策绑定
在给定项目 ID 和绑定的情况下,此过程将政策绑定添加到特定项目的 IAM 政策。绑定命令由成员、角色和可选条件组成。
数据库用户名必须是 IAM 用户的电子邮件地址,例如 test-user@example.com
。它必须使用英文引号,因为它包含特殊字符(@
和 .
)。
控制台
-
在 Google Cloud 控制台中,转到 IAM 页面。
- 点击添加。
- 在新成员中,输入电子邮件地址。您可以将单个用户、服务账号或群组添加为成员,但每个项目必须至少有一个主账号作为成员。
- 在角色中,导航到 Cloud SQL,然后选择 Cloud SQL Instance User 和 Cloud SQL Client。
- 对于个人用户和服务账号,请选择 Cloud SQL Client。
- 点击保存。
gcloud
运行带有 --role=roles/cloudsql.instanceUser
标志的 gcloud projects add-iam-policy-binding
。
向用户账号添加政策绑定
替换以下内容:
- PROJECT_ID:您要授权用户使用的项目的 ID。
- USERNAME:用户的电子邮件地址。
gcloud projects add-iam-policy-binding PROJECT_ID \ --member=user:USERNAME \ --role=roles/cloudsql.instanceUser
使用 --role=roles/cloudsql.client
gcloud projects add-iam-policy-binding
。
向服务账号添加政策绑定
替换以下内容:
- PROJECT_ID:您要授权用户使用的项目的 ID。
- SERVICE_ACCT:服务账号的电子邮件地址。
gcloud projects add-iam-policy-binding PROJECT_ID \ --member=serviceAccount:SERVICE_ACCT \ --role=roles/cloudsql.instanceUser
使用 --role=roles/cloudsql.client
gcloud projects add-iam-policy-binding
。
Terraform
如需向 IAM 用户和服务账号添加所需的政策绑定,请使用 Terraform 资源。
应用更改
如需在 Google Cloud 项目中应用 Terraform 配置,请完成以下部分中的步骤。
准备 Cloud Shell
- 启动 Cloud Shell。
-
设置要在其中应用 Terraform 配置的默认 Google Cloud 项目。
您只需为每个项目运行一次以下命令,即可在任何目录中运行它。
export GOOGLE_CLOUD_PROJECT=PROJECT_ID
如果您在 Terraform 配置文件中设置显式值,则环境变量会被替换。
准备目录
每个 Terraform 配置文件都必须有自己的目录(也称为“根模块”)。
-
在 Cloud Shell 中,创建一个目录,并在该目录中创建一个新文件。文件名必须具有
.tf
扩展名,例如main.tf
。在本教程中,该文件称为main.tf
。mkdir DIRECTORY && cd DIRECTORY && touch main.tf
-
如果您按照教程进行操作,可以在每个部分或步骤中复制示例代码。
将示例代码复制到新创建的
main.tf
中。(可选)从 GitHub 中复制代码。如果端到端解决方案包含 Terraform 代码段,则建议这样做。
- 查看和修改要应用到您的环境的示例参数。
- 保存更改。
-
初始化 Terraform。您只需为每个目录执行一次此操作。
terraform init
(可选)如需使用最新的 Google 提供程序版本,请添加
-upgrade
选项:terraform init -upgrade
应用更改
-
查看配置并验证 Terraform 将创建或更新的资源是否符合您的预期:
terraform plan
根据需要更正配置。
-
通过运行以下命令并在提示符处输入
yes
来应用 Terraform 配置:terraform apply
等待 Terraform 显示“应用完成!”消息。
- 打开您的 Google Cloud 项目以查看结果。在 Google Cloud 控制台的界面中找到资源,以确保 Terraform 已创建或更新它们。
删除更改
如需删除更改,请执行以下操作:
- 如需停用删除防护,请在 Terraform 配置文件中将
deletion_protection
参数设置为false
。deletion_protection = "false"
- 运行以下命令并在提示符处输入
yes
,以应用更新后的 Terraform 配置:terraform apply
-
通过运行以下命令并在提示符处输入
yes
,移除之前使用 Terraform 配置应用的资源:terraform destroy
REST
通过修改 get-iam-policy
命令返回的 JSON 或 YAML 绑定政策,将 cloudsql.instanceUser
和 cloudsql.client
角色授予两种类型的账号。请注意,此政策更改在设置更新后的政策后才会生效。
{ "role": "roles/cloudsql.instanceUser", "members": [ "user:test-user@example.com" "serviceAccount:service1@sql.iam.gserviceaccount.com" ] } { "role": "roles/cloudsql.client", "members": [ "user:test-user@example.com" "serviceAccount:service1@sql.iam.gserviceaccount.com" ] }
向 IAM 用户授予数据库权限
默认情况下,将 IAM 用户添加到数据库实例时,该新用户不会对任何数据库授予权限。用户或服务账号连接到数据库时,可以针对已被授予 PUBLIC 访问权限的任何数据库对象运行查询。
如果他们需要其他访问权限,可以使用 GRANT 语句授予更多权限。如需查看您可以向用户和服务账号授予的完整权限列表,请参阅 GRANT 参考页面。从命令行运行 GRANT。
替换以下内容:
- USERNAME:用户的电子邮件地址。您必须使用英文引号括住电子邮件地址,因为它包含特殊字符(
@
和.
)。 - TABLE_NAME:您要向用户授予访问权限的表的名称。
grant select on TABLE_NAME to "USERNAME";
从数据库中移除 IAM 用户或服务账号
要从数据库中移除用户或服务账号,请从实例中删除该账号:
控制台
-
在 Google Cloud 控制台中,转到 Cloud SQL 实例页面。
- 如需打开实例的概览页面,请点击实例名称。
- 从 SQL 导航菜单中选择用户。
- 针对您要移除的用户,点击 。
- 选择移除。这样只会撤消对此实例的访问权限。
gcloud
撤消用户
使用电子邮件地址(如 test-user@example.com
)来标识用户。
替换以下内容:
- USERNAME:电子邮件地址。
- INSTANCE_NAME:您要从中移除用户的实例的名称。
gcloud sql users delete USERNAME \ --instance=INSTANCE_NAME
删除服务账号
替换以下内容:
- SERVICE_ACCT:服务账号的电子邮件地址。
- INSTANCE_NAME:您要从中移除用户的实例的名称。
gcloud sql users delete SERVICE_ACCT \ --instance=INSTANCE_NAME
REST v1
以下请求使用 users.delete 方法删除指定的用户账号。
在使用任何请求数据之前,请先进行以下替换:
- PROJECT_ID:您的项目 ID
- INSTANCE_ID:所需的实例 ID
- USERNAME:用户或服务账号的电子邮件地址
HTTP 方法和网址:
DELETE https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances/INSTANCE_ID/users?host=&name=USERNAME
如需发送您的请求,请展开以下选项之一:
您应该收到类似以下内容的 JSON 响应:
{ "kind": "sql#operation", "targetLink": "https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances/INSTANCE_ID", "status": "DONE", "user": "user@example.com", "insertTime": "2020-02-07T22:38:41.217Z", "startTime": "2020-02-07T22:38:41.217Z", "endTime": "2020-02-07T22:38:44.801Z", "operationType": "DELETE_USER", "name": "OPERATION_ID", "targetId": "INSTANCE_ID", "selfLink": "https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/operations/OPERATION_ID", "targetProject": "PROJECT_ID" }
REST v1beta4
以下请求使用 users.delete 方法删除指定的用户账号。
在使用任何请求数据之前,请先进行以下替换:
- PROJECT_ID:您的项目 ID
- INSTANCE_ID:所需的实例 ID
- USERNAME:用户或服务账号的电子邮件地址
HTTP 方法和网址:
DELETE https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances/INSTANCE_ID/users?host=&name=USERNAME
如需发送您的请求,请展开以下选项之一:
您应该收到类似以下内容的 JSON 响应:
{ "kind": "sql#operation", "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances/INSTANCE_ID", "status": "DONE", "user": "user@example.com", "insertTime": "2020-02-07T22:38:41.217Z", "startTime": "2020-02-07T22:38:41.217Z", "endTime": "2020-02-07T22:38:44.801Z", "operationType": "DELETE_USER", "name": "OPERATION_ID", "targetId": "INSTANCE_ID", "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/operations/OPERATION_ID", "targetProject": "PROJECT_ID" }
在审核日志中查看登录信息
您可以启用审核日志以捕获对数据库的 IAM 登录。如果出现登录问题,您可以使用审核日志来诊断问题。
配置后,您可以使用日志浏览器来查看成功登录的数据访问审核日志。
例如,日志可能包含类似如下所示的信息:
{
insertId: "..."
logName: "projects/.../logs/cloudaudit.googleapis.com%2Fdata_access"
protoPayload: {
@type: "type.googleapis.com/google.cloud.audit.AuditLog"
authenticationInfo: {
principalEmail: "..."
}
authorizationInfo: [
0: {
granted: true
permission: "cloudsql.instances.login"
resource: "instances/..."
resourceAttributes: {
}
}
]
methodName: "cloudsql.instances.login"
request: {
@type: "type.googleapis.com/google.cloud.sql.authorization.v1.InstancesLoginRequest"
clientIpAddress: "..."
database: "..."
databaseSessionId: ...
instance: "projects/.../locations/us-central1/instances/..."
user: "..."
}
requestMetadata: {
callerIp: "..."
destinationAttributes: {
}
requestAttributes: {
auth: {
}
time: "..."
}
}
resourceName: "instances/..."
serviceName: "cloudsql.googleapis.com"
status: {
}
}
receiveTimestamp: "..."
resource: {
labels: {
database_id: "...:..."
project_id: "..."
region: "us-central"
}
type: "cloudsql_database"
}
severity: "INFO"
timestamp: "..."
}
排查登录失败问题
尝试登录失败时,出于安全考虑,PostgreSQL 会返回最少的错误消息。例如:
PGPASSWORD=not-a-password psql --host=... --username=... --dbname=...
psql: error: could not connect to server: FATAL: Cloud SQL IAM user authentication failed for user "..."
FATAL: pg_hba.conf rejects connection for host "...", user "...", database "...", SSL off
您可以查看 PostgreSQL 错误日志以详细了解错误。如需了解详情,请参阅查看日志。
例如,对于前面的错误,以下日志条目说明了您可以执行来解决该问题的操作。
F ... [152172]: [1-1] db=...,user=... FATAL: Cloud SQL IAM user authentication failed for user "..."
I ... [152172]: [2-1] db=...,user=... DETAIL: Request is missing required authentication credential. Expected OAuth 2 access token, log in cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.
检查您收到的错误消息。如果消息未指明您使用的是“Cloud SQL IAM 用户身份验证”还是“Cloud SQL IAM 服务账号身份验证”,请验证用于登录的数据库用户类型是 CLOUD_IAM_USER
或 CLOUD_IAM_SERVICE_ACCOUNT
。您可以使用 Google Cloud 控制台或 gcloud sql
users list
命令检查此项。对于 IAM 用户,验证数据库用户名是否为 IAM 用户的电子邮件地址。
如果您使用的是 IAM 数据库身份验证,请查看错误消息的详细信息。您可以在数据库错误日志中找到错误消息。如果消息指明您发送用作密码的访问令牌 (OAuth 2.0) 无效,您可以使用 gcloud auth application-default print-access-token
gcloud
命令查找令牌的详细信息,如下所示:
curl -H "Content-Type: application/x-www-form-urlencoded" \ -d "access_token=$(gcloud auth application-default print-access-token)" \ https://www.googleapis.com/oauth2/v1/tokeninfo
验证该令牌适用于预期的 IAM 用户或服务账号,并且未过期。
如果详细信息指明缺少权限,请验证已使用预定义的 Cloud SQL Instance User
角色或实例项目的 IAM 政策中的自定义角色为 IAM 用户或服务账号授予了 cloudsql.instances.login
权限。如需其他帮助,请使用 IAM 政策问题排查工具。
如果由于 IAM 数据库身份验证不可用而导致登录失败,则用户可以使用默认的 PostgreSQL 用户名和密码登录。这种登录方法仍可为用户提供整个数据库的访问权限。 验证连接是否为安全连接。
后续步骤
- 详细了解 IAM 数据库身份验证。
- 了解如何登录 Cloud SQL 数据库。
- 了解如何配置实例以使用 IAM 数据库身份验证。