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

相关推荐
Apple_羊先森1 小时前
ORACLE数据库巡检SQL脚本--19、磁盘读次数最高的前5条SQL语句
数据库·sql·oracle
ShiLiu_mtx2 小时前
k8s - 7
云原生·容器·kubernetes
l1t3 小时前
DeepSeek总结的PostgreSQL的GPT推理SQL移植到DuckDB的性能优化方法
sql·gpt·postgresql
山岚的运维笔记5 小时前
SQL Server笔记 -- 第20章:TRY/CATCH
java·数据库·笔记·sql·microsoft·sqlserver
认真的薛薛8 小时前
数据库-sql语句
数据库·sql·oracle
爱学英语的程序员8 小时前
面试官:你了解过哪些数据库?
java·数据库·spring boot·sql·mysql·mybatis
匀泪9 小时前
云原生(LVS NAT模式集群实验)
服务器·云原生·lvs
不剪发的Tony老师10 小时前
Shaper:一款免费开源的数据可视化工具
sql·数据可视化
DolitD10 小时前
云流技术深度剖析:国内云渲染主流技术与开源和海外厂商技术实测对比
功能测试·云原生·开源·云计算·实时云渲染
ghostwritten11 小时前
春节前夕,运维的「年关」:用 Kubeowler 给集群做一次「年终体检」
运维·云原生·kubernetes