java - Cloud SQL 代理和权限不足

标签 java spring-boot kubernetes google-cloud-sql google-kubernetes-engine

我正在尝试在 Google 的容器引擎 (GKE) 上部署我的 Spring Boot/JHipster 应用程序。我已经解决了大部分问题,但我的数据库实例(一个在 Google Cloud SQL 上运行的 PostgreSQL 实例,使用 Google SQL 代理)有问题。

我已按照说明进行操作 herehere设置我的应用程序。

  1. 我已经在云中设置了我的 PostreSQL 实例,并创建了我的应用程序的数据库和用户。
  2. 我创建了一个具有 Cloud SQL 客户端角色的 SQL 服务——我获取了 JSON key ,并使用它来创建我的 cloudsql-instance-credentials。我还创建了我的 cloudsql-db-credentials。
  3. 我已将额外的内容添加到我的部署 yaml 文件中。我基本上从 this GitHub sample 克隆了 yaml 文件并将所有对 wordpress 的引用替换为我自己的 Docker 镜像(托管在 Google Container Registry 中)。我还更新了代理 block ,如下所示:

deployment.yaml 片段:

  - image: gcr.io/cloudsql-docker/gce-proxy:1.09
      name: cloudsql-proxy
          command: ["/cloud_sql_proxy", "--dir=/cloudsql",
                    "-instances=[my-project]:us-central1:[my-sql-instance-id]=tcp:5432",
                    "-credential_file=/secrets/cloudsql/credentials.json"]

最后,我更新了我的 Spring Boot 配置 yaml 文件,如下所示:

datasource:
    type: com.zaxxer.hikari.HikariDataSource
    url: jdbc:postgresql://google/[my-database]?socketFactory=com.google.cloud.sql.postgres.SocketFactory&socketFactoryArg=[my-project]:us-central1:[my-sql-instance-id]
    username: ${DB_USER}
    password: ${DB_PASSWORD}

当我kubectl create 我的部署时,图像会部署,但无法启动应用程序。这是我日志中的重要部分:

Caused by: java.lang.RuntimeException: Unable to retrieve information about Cloud SQL instance [[my-project]:us-central1:[my-sql-instance-id]]
    at com.google.cloud.sql.core.SslSocketFactory.obtainInstanceMetadata(SslSocketFactory.java:411)
    at com.google.cloud.sql.core.SslSocketFactory.fetchInstanceSslInfo(SslSocketFactory.java:284)
    at com.google.cloud.sql.core.SslSocketFactory.getInstanceSslInfo(SslSocketFactory.java:264)
    at com.google.cloud.sql.core.SslSocketFactory.createAndConfigureSocket(SslSocketFactory.java:183)
    at com.google.cloud.sql.core.SslSocketFactory.create(SslSocketFactory.java:152)
    at com.google.cloud.sql.postgres.SocketFactory.createSocket(SocketFactory.java:50)
    at org.postgresql.core.PGStream.<init>(PGStream.java:60)
    at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:144)
    at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:52)
    at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:216)
    at org.postgresql.Driver.makeConnection(Driver.java:404)
    at org.postgresql.Driver.connect(Driver.java:272)
    ... 37 common frames omitted
Caused by: com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
  "code" : 403,
  "errors" : [ {
    "domain" : "global",
    "message" : "Insufficient Permission",
    "reason" : "insufficientPermissions"
  } ],
  "message" : "Insufficient Permission"
}
    at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:146)
    at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
    at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:321)
    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1065)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
    at com.google.cloud.sql.core.SslSocketFactory.obtainInstanceMetadata(SslSocketFactory.java:372)
    ... 48 common frames omitted

这个“Insufficient Permission”错误在 StackOverflow 上经常出现,但我还没有找到与我的情况完全相同的问题。这似乎是一个普通的 OAuth 级错误。我觉得我已经根据说明仔细检查了我的设置几次,但我不确定在哪里可以找到任何其他线索。

有什么想法吗?

更新:

感谢 Vadim 的指点,我已经设法解决了“Insufficient Permission”问题。遗憾的是,当我的应用程序尝试建立与数据库的连接时(具体来说,当 Liquibase 尝试开始连接到数据库以运行迁移脚本时),我的应用程序在启动时仍然失败。

我的新错误是在驱动程序的套接字级别:

liquibase.exception.DatabaseException: org.postgresql.util.PSQLException: The connection attempt failed.
    at liquibase.integration.spring.SpringLiquibase.afterPropertiesSet(SpringLiquibase.java:390)
    at io.github.jhipster.config.liquibase.AsyncSpringLiquibase.initDb(AsyncSpringLiquibase.java:82)
    at io.github.jhipster.config.liquibase.AsyncSpringLiquibase.afterPropertiesSet(AsyncSpringLiquibase.java:72)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624)
    ... 24 common frames omitted
Caused by: org.postgresql.util.PSQLException: The connection attempt failed.
    at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:272)
    at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:52)
    at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:216)
    at org.postgresql.Driver.makeConnection(Driver.java:404)
    at org.postgresql.Driver.connect(Driver.java:272)
    at java.sql.DriverManager.getConnection(DriverManager.java:664)
    at java.sql.DriverManager.getConnection(DriverManager.java:247)
    at org.postgresql.ds.common.BaseDataSource.getConnection(BaseDataSource.java:86)
    at org.postgresql.ds.common.BaseDataSource.getConnection(BaseDataSource.java:71)
    at liquibase.integration.spring.SpringLiquibase.afterPropertiesSet(SpringLiquibase.java:385)
    ... 28 common frames omitted
Caused by: java.net.SocketException: already connected
    at java.net.Socket.connect(Socket.java:569)
    at sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:673)
    at org.postgresql.core.PGStream.<init>(PGStream.java:61)
    at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:144)
    ... 37 common frames omitted

最佳答案

Vadim 解决了我提出的问题,但第二个问题——套接字已连接问题——最终被我的一位同事解决了。

套接字问题的根源与数据源配置有关。事实证明,我正在混合和匹配两种不同的访问 Cloud SQL 环境的机制。

  1. 使用 Cloud SQL 代理;和
  2. 使用 Google 套接字工厂

因为我已经成功配置了 Cloud SQL 代理,所以我的 Spring Boot 环境中不需要那个奇怪的 JDBC URL。我可以使用 127.0.0.1:5432 进行连接,如下所示:

datasource:
    type: com.zaxxer.hikari.HikariDataSource
    url: jdbc:postgresql://127.0.0.1:5432/[my-database-name]
    username: ${DB_USER}
    password: ${DB_PASSWORD}

现在我已经替换了我的 JDBC URL,我的应用程序连接成功。

关于java - Cloud SQL 代理和权限不足,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45889759/

相关文章:

java - GWT 2.3 中的拖放

java - @JsonApiRelationId 和 @JsonApiRelation 有什么区别?

java - 如何在不加载 Java 类的情况下检查它?

Spring-boot 与 MyBatis 不会回滚事务

networking - Prometheus Pod无法调用apiserver端点

kubernetes - 如何使用用户名和密码对 Kubernetes kubectl 进行身份验证?

java - 如何将调用注释的类名和方法作为 "value"传递给注释属性

java - Spring(Boot)对同一类的不同层进行验证注解

java - Kubernetes 在 Pod 中使用外部服务

java - 禁用 spring security 不起作用