使用Terraform创建私有Cloud SQL实例及连接测试

指南一:使用Terraform创建私有Cloud SQL实例及连接测试

本文档详细记录了使用Terraform创建一个专用于VPC内部访问的Cloud SQL for PostgreSQL实例的全过程,并演示了如何从GCE和GKE环境中测试其连通性。

1. Terraform项目结构

我们创建了一个结构清晰的Terraform项目,将不同功能的资源分离到独立的文件中:

  • instance.tf: 定义Cloud SQL实例本身。
  • db.tf: 定义实例内的数据库。
  • user.tf: 定义数据库用户。
  • provider.tf: 配置GCP提供商。
  • variables.tf: 定义所有变量。
  • outputs.tf: 输出重要信息(如连接名)。
  • backend.tf: 配置Terraform状态文件的GCS后端。

2. 核心Terraform代码

2.1. 创建Cloud SQL实例 (instance.tf)

为了创建私有实例,我们在ip_configuration块中进行了关键设置:

  • ipv4_enabled = false: 禁用了公共IP地址。
  • private_network = "...": 将实例关联到指定的VPC网络。
terraform 复制代码
# instance.tf
resource "google_sql_database_instance" "main" {
  name             = var.instance_name
  database_version = "POSTGRES_13"
  region           = var.gcp_region

  settings {
    tier = var.db_tier
    ip_configuration {
      ipv4_enabled    = false
      private_network = "projects/${var.gcp_project_id}/global/networks/${var.vpc_network_name}"
    }
  }
  
  deletion_protection = false
}

2.2. 创建数据库 (db.tf)

terraform 复制代码
# db.tf
resource "google_sql_database" "default" {
  name     = "default_db"
  instance = google_sql_database_instance.main.name
}

2.3. 创建数据库用户 (user.tf)

terraform 复制代码
# user.tf
resource "google_sql_user" "default" {
  name     = var.db_user_name
  instance = google_sql_database_instance.main.name
  password = var.db_user_password
}

2.4. 配置VPC网络对等互连 (network.tf)

为了让Cloud SQL能够与我们的VPC通信,需要配置专用服务访问(Private Service Access),它通过VPC Peering实现。

注意 : 在我们的实践中,我们发现此Peering连接已存在,因此最终移除network.tf文件。但如果是首次配置,则需要以下资源:

terraform 复制代码
# network.tf (如果Peering不存在时需要)
resource "google_service_networking_connection" "private_vpc_connection" {
  network                 = "projects/${var.gcp_project_id}/global/networks/${var.vpc_network_name}"
  service                 = "servicenetworking.googleapis.com"
  reserved_peering_ranges = [google_compute_global_address.private_ip_address.name]
}

resource "google_compute_global_address" "private_ip_address" {
  name          = "private-ip-for-cloudsql"
  purpose       = "VPC_PEERING"
  address_type  = "INTERNAL"
  prefix_length = 16
  network       = "projects/${var.gcp_project_id}/global/networks/${var.vpc_network_name}"
}

3. 部署与验证

我们通过terraform apply成功部署了实例。

3.1. 验证实例IP

我们使用gcloud命令确认实例只有一个私有IP。

命令:

bash 复制代码
gcloud sql instances describe my-database-instance --project=jason-hsbc --format="json(ipAddresses)"

输出:

json 复制代码
{
  "ipAddresses": [
    {
      "ipAddress": "10.195.208.3",
      "type": "PRIVATE"
    }
  ]
}

结论 : 验证成功,实例只有一个私有IP 10.195.208.3

4. 连通性测试

4.1. 从GCE VM测试 (成功)

我们从一台位于同一VPC的GCE虚拟机my-envoy-vm-b5hr上进行了测试。

测试命令:

bash 复制代码
gcloud compute ssh my-envoy-vm-b5hr --zone=europe-west2-c --project=jason-hsbc --command="sudo apt-get update && sudo apt-get install -y postgresql-client && echo 'psql installed, now testing connection...' && env PGPASSWORD=[YOUR_PASSWORD] psql -h 10.195.208.3 -U nvd11 -d default_db -c '\l'"

测试输出:

复制代码
psql installed, now testing connection...
                                                List of databases
     Name      |       Owner       | Encoding |  Collate   |   Ctype    |            Access privileges
---------------+-------------------+----------+------------+------------+-----------------------------------------
 cloudsqladmin | cloudsqladmin     | UTF8     | en_US.UTF8 | en_US.UTF8 |
 default_db    | cloudsqlsuperuser | UTF8     | en_US.UTF8 | en_US.UTF8 |
 postgres      | cloudsqlsuperuser | UTF8     | en_US.UTF8 | en_US.UTF8 |
 template0     | cloudsqladmin     | UTF8     | en_US.UTF8 | en_US.UTF8 | =c/cloudsqladmin                       +
               |                   |          |            |            | cloudsqladmin=CTc/cloudsqladmin
 template1     | cloudsqlsuperuser | UTF8     | en_US.UTF8 | en_US.UTF8 | =c/cloudsqlsuperuser                   +
               |                   |          |            |            | cloudsqlsuperuser=CTc/cloudsqlsuperuser
(5 rows)

结论 : 从GCE VM到Cloud SQL私有IP的网络路径是通畅的

4.2. 从GKE Pod测试 (失败)

我们创建了一个临时的Pod psql-test-runner-2,并尝试从Pod内部连接。

测试命令:

bash 复制代码
kubectl exec psql-test-runner-2 -- env PGPASSWORD=[YOUR_PASSWORD] psql -h 10.195.208.3 -U nvd11 -d default_db -c "\l"

测试输出:

复制代码
psql: error: connection to server at "10.195.208.3", port 5432 failed: Connection timed out

结论 : 从GKE Pod到Cloud SQL私有IP的网络路径被阻塞 。这引发了第二份文档中详细描述的深度排查过程。
GKE连接private Cloud SQL疑难问题排查实录

相关推荐
我真的是大笨蛋5 小时前
深度解析InnoDB如何保障Buffer与磁盘数据一致性
java·数据库·sql·mysql·性能优化
江畔何人初7 小时前
pod的定义以及创建过程
linux·运维·云原生
Gary董10 小时前
高并发的微服务架构如何设计
微服务·云原生·架构
东哥爱编程10 小时前
使用Runpod进行gpu serverless推理
云原生·serverless
tod11311 小时前
力扣高频 SQL 50 题阶段总结(四)
开发语言·数据库·sql·算法·leetcode
踢足球092912 小时前
寒假打卡:2026-01-31
数据库·sql
山峰哥13 小时前
SQL优化全解析:从索引策略到查询性能飞跃
大数据·数据库·sql·编辑器·深度优先
Apple_羊先森14 小时前
ORACLE数据库巡检SQL脚本--7、检查不起作用的约束
数据库·sql·oracle
天才奇男子15 小时前
《深度解析HAProxy七层代理:原理、配置与最佳实践》
linux·运维·微服务·云原生
怣5015 小时前
MySQL表的数据检索:从基础到精通
数据库·sql·mysql