容器化服务器应用程序无法连接到 MySQL 个数据库

Containerized server application failing to connect to MySQL databases

我正在尝试将我的服务器代码 运行 作为我们 Kubernetes 集群(托管在 Google 容器引擎上)中的 Docker 容器连接到 Google 云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);

附加信息:服务器应用程序是在 Node 中构建的,使用 mysql2 库连接到数据库。没有导致网络问题的特殊防火墙规则,图书馆正在连接但未能通过身份验证这一事实证实了这一点。

您是否阅读了有关 https://cloud.google.com/sql/docs/mysql/connect-container-engine 的文档?

在容器引擎中,您需要在您的应用程序 pod 旁边设置一个云 SQL 代理容器并与之通信。云 SQL 代理随后将实际调用云 SQL 服务。

如果容器在本地运行,我假设您在开发机器上设置了应用程序默认凭据。它可能会失败,因为这些凭据不在您的容器中作为服务帐户文件。尝试配置服务帐户文件,或使用 --scopes 参数创建 GKE 集群,使您的实例可以访问云 SQL.

设置 Cloud SQL Proxy 之后,我设法找出实际错误是什么:在秘密和 pod 配置之间的某个地方,一个额外的换行符被添加到数据库名称,导致任何连接尝试失败。设置代理后,这一点就很清楚了,因为显示了一条实际的错误消息。

(值得注意的是,我用来验证凭据是否准确的所有围绕凭据的日志记录都没有明确显示换行符,并且被控制台显示添加换行符以换行显示这一事实所掩盖,它恰好与数据库名称结束的位置对齐)