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