使用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疑难问题排查实录

相关推荐
SHolmes18544 小时前
INSERT INTO … SELECT … 常见问答(含样例)
sql
啟明起鸣6 小时前
【Go 与云原生】先从 Go 对与云原生的依赖关系讲起,再讲讲 一个简单的 Go 项目热热身
开发语言·云原生·golang
现在,此刻6 小时前
clickhouse和pgSql跨库查询方案对比
数据库·sql·clickhouse·性能优化
@不会写代码的小张7 小时前
传统的企业服务如何部署在k8s集群中
云原生·容器·kubernetes
nvd118 小时前
指南:为何及如何使用Envoy作为跳板机代理Cloud SQL
sql
Juchecar9 小时前
超越经典23种设计模式:新模式、反模式与函数式编程
设计模式·云原生·函数式编程
l1t10 小时前
利用短整数类型和部分字符串优化DuckDB利用数组求解数独SQL
开发语言·数据库·sql·duckdb
啟明起鸣11 小时前
【Go 与云原生】让一个 Go 项目脱离原生的操作系统——我们开始使用 Docker 制造云容器进行时
docker·云原生·golang
驾数者12 小时前
Flink SQL核心概念解析:Table API与流表二元性
大数据·sql·flink