我正在尝试将我的服务器代码在我们的Kubernetes集群(托管在Google Container Engine上)中作为Docker容器运行到Google Cloud SQL托管的MySQL 5.7实例。我遇到的问题是数据库服务器拒绝了每个连接,并带有Access denied for user 'USER'@'IP' (using password: YES)
。数据库凭据(用户名,密码,数据库名称和SSL证书)都是正确的,并且在通过其他MySQL客户端或在本地实例上作为容器运行的同一应用程序进行连接时有效。
我已经验证了应用程序的本地和服务器托管版本上的所有凭据是否相同,并且我正在连接的用户指定了通配符%
主机。老实说,真的不确定接下来要检查什么...
连接代码的编辑版本如下:
let connectionCreds = {
host: Config.SQL.HOST,
user: Config.SQL.USER,
password: Config.SQL.PASSWORD,
database: Config.SQL.DATABASE,
charset: 'utf8mb4',
};
if (Config.SQL.SSL_ENABLE) {
connectionCreds['ssl'] = {
key: fs.readFileSync(Config.SQL.SSL_CLIENT_KEY_PATH),
cert: fs.readFileSync(Config.SQL.SSL_CLIENT_CERT_PATH),
ca: fs.readFileSync(Config.SQL.SSL_SERVER_CA_PATH)
}
}
this.connection = MySQL.createConnection(connectionCreds);
附加信息:服务器应用程序是使用 mysql2 库在 Node 中构建的,以连接到数据库。没有导致网络问题的特殊防火墙规则,库正在连接但无法进行身份验证这一事实证实了这一点。
设置Cloud SQL Proxy后,我设法找出了实际错误是什么:在机密和Pod配置之间的某个地方,在数据库名称中添加了一个额外的换行符,导致任何连接尝试失败。通过设置代理,这一点很清楚,因为显示了一条实际的错误消息。
(值得注意的是,我用来验证凭据是否准确的所有记录都没有明确显示换行符,并且被控制台显示添加了换行符来包装显示的事实所掩盖,并且它恰好与数据库名称结束的位置完全对齐)
你读过关于 https://cloud.google.com/sql/docs/mysql/connect-container-engine 的文档吗?
在容器引擎中,需要在应用程序 Pod 旁边设置云 SQL 代理容器并与之通信。然后,云 SQL 代理将对云 SQL 服务进行实际调用。
如果容器在本地工作,我假设你在开发计算机上设置了应用程序默认凭据。它可能会失败,因为这些凭据不在容器即服务帐户文件中。尝试配置服务帐户文件,或使用--scopes
参数创建 GKE 集群,以使您的实例能够访问云 SQL。