Java从Appengine托管虚拟机

时间:2016-01-15 07:29:32

标签: java mysql google-app-engine google-cloud-sql google-managed-vm

尝试为具有托管VM的Java Appengine设置与Clond SQL 2nd Generation的连接。

我得到了什么:

  • VM正在使用Appengine Compat模式(FROM gcr.io/google_appengine/java-compat
  • 我在主机上看到一个MySQL管道(SSH,我可以看到/cloudsql/**套接字),但是默认的MySQL Java驱动程序不支持unix套接字
  • Google托管似乎在托管虚拟机(java.lang.ClassNotFoundException: com.mysql.jdbc.GoogleDriver
  • 上不受支持
  • 我无法通过IP连接到MySQL
    • w / o驱动程序为No suitable driver found
    • jdbc:google:mysql://__IP__:3306/__db__
    • jdbc:mysql://__IP__:3306/__db__的超时(我已将MVM外部IP添加到MySQL上的授权网络)
    • 但有趣的是,我可以从MVM机器连接到这个端口,至少打开了端口。无论如何,我不喜欢通过公开开放的IP连接的想法:PORT。 MVM每次都有一个新IP,因此我甚至无法添加防火墙规则来指定仅从我的项目访问

如何配置ManagedVM应用程序以连接到Cloud SQL?

3 个答案:

答案 0 :(得分:1)

我无法使用Java启动托管VM应用程序,因此我现在无法自己尝试,但看起来您应该能够利用this library连接到Unix套接字来自Java。有一个example,您只需要更改套接字的路径:

props.put("junixsocket.file", "/cloudsql/project-id:region:instance-id");

project-id是您的项目名称,region是您的Cloud SQL实例所在的区域(例如us-east1),而instance-id是您的云名称 - sql实例。该字符串将位于"实例连接名称"下的第二代实例的属性中。

答案 1 :(得分:1)

我们有一个新的Java库,用于从托管虚拟机和其他环境连接到云SQL实例: https://github.com/GoogleCloudPlatform/cloud-sql-mysql-socket-factory

它仍然很新,所以通常的警告适用,但我们在测试中没有发现任何问题。

答案 2 :(得分:0)

我发现的最佳方法是从ManagedVM配置S​​SL连接

你应该做两件事。

首先,使用您从Cloud SQL控制台(文件server-ca.pemclient-cert.pemclient-key.pem)获取的SSL准备Java Keystore:

echo '---------- GENERATE TrustStore'
keytool -import -alias mysqlCACert -file server-ca.pem -keystore truststore -storepass 123456

echo '---------- GENERATE KeyStore'
openssl pkcs12 -export -in client-cert.pem -inkey client-key.pem \
    -out client.p12 -name clientalias -CAfile server-ca.pem -caname root
keytool -importkeystore -deststorepass 123456 -destkeystore keystore \
    -srckeystore client.p12 -srcstoretype PKCS12 -srcstorepass 123456 -alias clientalias

您将获得两个文件:truststorekeystore,您需要将这些文件放入目标虚拟机。

其次,您应该使用自定义Dockerfile,其中包含上一步中的文件:

FROM gcr.io/google_appengine/java-compat

RUN mkdir /keys
ADD keystore /keys/
ADD truststore /keys/
ENV JAVA_OPTS -Djavax.net.ssl.keyStore=/keys/keystore -Djavax.net.ssl.keyStorePassword=123456 -Djavax.net.ssl.trustStore=/keys/truststore -Djavax.net.ssl.trustStorePassword=123456

ADD .  /app/

当然,不要忘记告诉MySQL驱动程序始终使用SSL:

dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://__CLOUD_SQL_IP__:3306/__CLOUD_SQL_DB__?useSSL=true&requireSSL=true");

PS注意,我使用密码123456来保护我的密钥。这只是一个例子。不要在你的项目中使用它。已经采取了。