无法使用 Go SQL 连接器连接到 Google Cloud SQL PostgreSQL 实例(私有 IP):iam.serviceAccounts.getAccessToken 权限被拒绝

问题描述 投票:0回答:1

我正在尝试使用 Go 中的 SQL 连接器库连接到 Google Cloud 中的 PostgreSQL 数据库实例(使用私有 IP 连接)。但是,我遇到以下错误:

ERROR Failed to dial instance {"error": "failed to get instance: Refresh error: failed to get instance metadata (connection name = \"<connection-string>\"): Get \"https://sqladmin.googleapis.com/sql/v1beta4/projects/\/instances/postgres/connectSettings?alt=json&prettyPrint=false\": compute: Received 403 `Unable to generate access token; IAM returned 403 Forbidden: Permission 'iam.serviceAccounts.getAccessToken' denied on resource (or it may not exist).
This error could be caused by a missing IAM policy binding on the target IAM service account.
For more information, refer to the Workload Identity documentation:

环境详情:

Google Cloud:启用了私有 IP 连接的 PostgreSQL 实例

服务帐户权限:

  • 云 SQL 管理
  • 云 SQL 客户端
  • 计算网络管理员
  • 项目 IAM 管理员
  • 服务帐户管理
  • 服务帐户令牌创建者
  • 存储管理员
  • 工作负载身份用户

Go 环境:在属于同一 VPC 中 GKE 集群一部分的虚拟机实例中运行代码。

这是我的 Go 代码的相关部分:

func connectDB() error {
    user := "postgres"
    password := "password"
    connectionName := "connectionName"
    sslmode := "require"
    dbName := "databaseName"

    config, err := pgx.ParseConfig(connStr)
    if err != nil {
        return err
    }

    opts := append([]cloudsqlconn.Option{},
        cloudsqlconn.WithDefaultDialOptions(cloudsqlconn.WithPrivateIP()),
    )

    d, err := cloudsqlconn.NewDialer(context.Background(), opts...)
    if err != nil {
        return err
    }

    config.DialFunc = func(ctx context.Context, network, instance string) (net.Conn, error) {
        log.FromContext(ctx).Info(fmt.Sprintf("Dialing instance: %s", instance))
        conn, err := d.Dial(ctx, connectionName)
        if err != nil {
            log.FromContext(ctx).Error(err, "Failed to dial instance")
        }
        return conn, err
    }

    dbURI := stdlib.RegisterConnConfig(config)
    dbPool, err := sql.Open("pgx", dbURI)
    if err != nil {
        return err
    }   

    err = dbPool.Ping()
    if err != nil {
        return err
    }   
    return nil
}

故障排除尝试:

验证数据库实例具有私有IP并且在同一VPC内可访问。 检查并确保服务帐户具有以下权限: 云 SQL 管理员 云 SQL 客户端 服务帐户令牌创建者 工作负载身份用户等。 确保 Go 应用程序在有权访问私有 VPC 的虚拟机内运行。

postgresql go google-cloud-platform google-cloud-sql
1个回答
0
投票

请注意您链接的错误的这一部分:“资源上的权限‘iam.serviceAccounts.getAccessToken’被拒绝(或者可能不存在)”。您提到的唯一具有该特定权限的两个角色是

  • 服务帐户令牌创建者
  • 工作负载身份用户

文档中,仅提到了工作负载身份用户,因此我将尝试对提到该角色的位置进行故障排除:

  1. 如果您没有这样做,请遵循此最佳实践
  2. 确保您按照文档完成所有步骤。提示:确保完成所有必需的步骤,1 到 6(从命名空间创建到策略到模拟到注释)
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.