我正在尝试使用 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 实例
服务帐户权限:
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 的虚拟机内运行。