postgresql - 从具有私有和公共 IP 的虚拟机连接到私有 IP 上的 Google Cloud SQL 实例失败
问题描述
我要设置的内容:
- 具有私有 IP、Postgresql 数据库的 Cloud SQL 实例
- 与 SQL 实例在同一 VPC 网络上的具有一个公共 IP 和一个私有 IP 的 VM(VM、SQL 实例和 VPC 都在同一区域中)
- 虚拟机具有具有足够 Cloud SQL 客户端/查看者权限的服务帐号
- 连接到 SQL 实例的 VM 上的 SQL 代理。
-ip_address_types=PRIVATE
我使用在某些文档中找到的论点来运行它。
配置代码
用于重现令我困惑的状态的稍微简化的 Terraform 代码在这里: https ://github.com/hallvors/gcp-network-issue-demo 要对此进行测试,请执行以下操作:
- 创建一个新的一次性 Google Cloud 项目。
- 为方便起见,您可以运行 bootstrap.sh 来启用正确的服务(它会询问 Google 项目的 ID,并假设您有一个已登录并有权访问的 gcloud 客户端)。
- 在项目中创建一个service account,为了方便就将其设为owner,并在其中保存一个key文件
./local-secrets/google-project-credentials.json
- 使用项目 ID 和服务帐户的电子邮件更新 terraform.tfvars
terraform workspace new staging
terraform init
terraform apply
完成 Terraform 后,您应该在项目中设置了一个数据库和一个 VM。
- SSH 进入虚拟机并运行
sudo apt install postgresql-client-common postgresql-client
- 查找数据库实例的 IP 地址
- 运行此(根据需要修改详细信息)
psql --host 10.167.0.3 -U gcp-network-issue-demo-staging-db-user gcp-network-issue-demo-staging-database
怎么了?
- 任何实际使用连接的尝试,例如 psql 客户端或 db-migrate,都会超时
- 如果我从设置中删除 VM 的公共 IP 地址,它可以正常连接。但是,我需要一个可公开访问的 VM 以供其他服务连接到它。
我错过了什么?
解决方案
这个问题的原因是我无法理解网络接口可以同时具有公共和私有 IP/网络。因此,我的代码为 google_compute_instance 设置了一个公共接口和一个专用网络接口:
# Update VM needs a public IP
network_interface {
network = "default"
access_config {
}
}
network_interface {
network = var.network
subnetwork = var.subnetwork
}
现在,我仍然不完全了解网络,但您似乎无法(容易?)指定数据库连接尝试应使用的接口,并且它不会自动选择正确的接口。修复在这个提交中,配置了对私有网络和公共网络接口的访问:
https://github.com/hallvors/gcp-network-issue-demo/commit/ea14174c1087c89b92310b5b4913e12a4e17130d
推荐阅读
- git - git pull/push 在单个 TCP 连接中
- android - 在某些 com.google.android.gms.* 模块中崩溃
- batch-file - chcp 后无法识别标签和命令
- email - Incredimail 电子邮件不会滚动
- javascript - 从 HTML 调用 Golang
- sql - 如何在不使用变量的情况下选择在不同日期一列值相同的行?
- sql - 使用子查询(公用表表达式)作为过滤器
- linux - 使用带有 -q 的 git 命令但在失败时不会保持安静?
- atom-editor - Atom 文本编辑器颜色随机更改
- java - 试图让我的 parseSentence 方法起作用。它只会错误计算应该分配的点数