从具有私有 IP 和 public IP 的虚拟机连接到私有 IP 上的 Google 云 SQL 实例失败
Connecting to Google Cloud SQL instance on private IP from a VM with both private and public IPs fails
我要设置的内容:
- Cloud SQL 具有私有 IP 的实例,Postgresql 数据库
- 具有一个 public IP 和一个私有 IP 的 VM 在与 SQL 实例相同的 VPC 网络上(VM、SQL 实例和 VPC 都在同一区域中)
- VM 有一个具有足够 Cloud SQL client/viewer 权限的服务帐户
- SQL VM 上的代理连接到 SQL 实例。我 运行 它带有我在一些文档中找到的
-ip_address_types=PRIVATE
参数。
配置代码
用于重现令我困惑的状态的略微简化的 Terraform 代码如下:
https://github.com/hallvors/gcp-network-issue-demo
要对此进行测试,请执行以下操作:
- 创建一个新的一次性 Google 云项目。
- 为了您的方便,您可以 运行 bootstrap.sh 启用正确的服务(它将询问 Google 项目的 ID,并假设您有一个 gcloud 客户端,它是已登录并具有访问权限)。
- 在项目中创建一个服务帐户,方便起见,将其设为所有者,并在
./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 的 public IP 地址,它可以正常连接。但是,我需要一个 public 可访问的 VM 以便其他服务连接到它..
我错过了什么?
这个问题的原因是我未能理解网络接口可以有 both public 和私有 IPs/networks。所以我的代码为 public 设置了一个接口,为 google_compute_instance:
的专用网络设置了一个接口
# Update VM needs a public IP
network_interface {
network = "default"
access_config {
}
}
network_interface {
network = var.network
subnetwork = var.subnetwork
}
现在,我仍然不完全了解网络,但您似乎不能(很容易?)指定数据库连接尝试应使用的接口,并且它不会自动选择正确的接口。修复在此提交中,配置对专用网络和 public 一对一网络接口的访问:
https://github.com/hallvors/gcp-network-issue-demo/commit/ea14174c1087c89b92310b5b4913e12a4e17130d
我要设置的内容:
- Cloud SQL 具有私有 IP 的实例,Postgresql 数据库
- 具有一个 public IP 和一个私有 IP 的 VM 在与 SQL 实例相同的 VPC 网络上(VM、SQL 实例和 VPC 都在同一区域中)
- VM 有一个具有足够 Cloud SQL client/viewer 权限的服务帐户
- SQL VM 上的代理连接到 SQL 实例。我 运行 它带有我在一些文档中找到的
-ip_address_types=PRIVATE
参数。
配置代码
用于重现令我困惑的状态的略微简化的 Terraform 代码如下: https://github.com/hallvors/gcp-network-issue-demo 要对此进行测试,请执行以下操作:
- 创建一个新的一次性 Google 云项目。
- 为了您的方便,您可以 运行 bootstrap.sh 启用正确的服务(它将询问 Google 项目的 ID,并假设您有一个 gcloud 客户端,它是已登录并具有访问权限)。
- 在项目中创建一个服务帐户,方便起见,将其设为所有者,并在
./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 的 public IP 地址,它可以正常连接。但是,我需要一个 public 可访问的 VM 以便其他服务连接到它..
我错过了什么?
这个问题的原因是我未能理解网络接口可以有 both public 和私有 IPs/networks。所以我的代码为 public 设置了一个接口,为 google_compute_instance:
的专用网络设置了一个接口 # Update VM needs a public IP
network_interface {
network = "default"
access_config {
}
}
network_interface {
network = var.network
subnetwork = var.subnetwork
}
现在,我仍然不完全了解网络,但您似乎不能(很容易?)指定数据库连接尝试应使用的接口,并且它不会自动选择正确的接口。修复在此提交中,配置对专用网络和 public 一对一网络接口的访问:
https://github.com/hallvors/gcp-network-issue-demo/commit/ea14174c1087c89b92310b5b4913e12a4e17130d