指南:为何及如何使用Envoy作为跳板机代理Cloud SQL

本文档旨在复盘一次复杂的网络连接问题,并详细记录我们最终采用的解决方案:配置一台GCE虚拟机作为Envoy代理,以实现从外部网络访问VPC内部的私有Cloud SQL实例。

1. 最终方案:Envoy跳板机代理

核心思路

我们利用一台拥有公网IP的GCE虚拟机作为"跳板机"。在这台机器上运行Envoy,并将其配置为TCP代理。Envoy监听一个公共端口(如5432),并将所有收到的流量转发到Cloud SQL实例的私有IP上。

数据流
[客户端(本地/GKE)] -> (连接GCE公网IP:5432) -> [GCE VM上的Envoy] -> (转发到Cloud SQL私网IP:5432) -> [Cloud SQL实例]


2. 背景:为何选择此方案?Cloud SQL Auth Proxy的挑战

我们并非一开始就选择这个方案。在采用这个"跳板机"方案之前,我们尝试了所有官方推荐的标准方法,但都遇到了难以解决的障碍。以下是我们详细的排查历程:

阶段一:直接IP连接失败

我们的第一反应是直接从GKE Pod连接到Cloud SQL的私有IP。

  • 问题 : psql客户端报告Connection timed out(连接超时)。

  • 排查:

    1. VPC防火墙 : 我们确认并添加了正确的防火墙规则,允许了所有VPC内部、GKE Pod和Service网段之间的通信。问题依旧
    2. GKE网络策略 : 我们通过kubectl get networkpolicy确认集群中没有任何限制性的网络策略。问题依旧
    3. IP伪装 : 我们通过部署ip-masq-agent-config的ConfigMap,确保了从Pod到私有IP的流量不会被错误地伪装。问题依旧
    4. GCE测试: 我们从一台普通的GCE VM上成功连接到了Cloud SQL,证明VPC主干网路由和防火墙是通的。
  • 结论: 问题特定于GKE环境,极有可能是GKE子网与Google服务网络之间的路由传播问题。

阶段二:Cloud SQL Auth Proxy的曲折尝试

在直接连接失败后,我们转向了Google官方强烈推荐的最佳实践------使用Cloud SQL Auth Proxy。我们认为这能绕过所有底层网络问题,但现实是残酷的。

  • 尝试1: 本地使用v1旧版Proxy

    • 现象 : 我们通过apt在本地安装了Proxy,但版本非常老(1.17.0)。启动后,psql连接直接卡死,Proxy日志仅显示New connection,没有任何错误。
    • 分析: Proxy接收了连接,但在后台与Google通信时被无声地挂起。
  • 尝试2: 修正v1版Proxy的参数

    • 现象 : 我们发现v1版本不支持--private-ip参数,并根据其文档改用-ip_address_types=PRIVATE问题依旧psql连接仍然卡死。
    • 分析: 参数正确后问题仍在,我们开始怀疑是IAM权限问题。
  • 尝试3: 修正IAM权限

    • 现象 : 我们发现Proxy默认使用了本地的terraform服务账号,而我们之前只给vm-common账号授权了。在为terraform账号添加了Cloud SQL Client角色后,问题依旧
    • 分析: 权限正确后问题仍在,这几乎排除了用户配置层面的错误。
  • 尝试4: 升级到v2新版Proxy

    • 现象 : 我们手动下载了最新的v2版Proxy。这次,我们得到了一个决定性的错误信息 。Proxy日志明确报告:failed to connect to instance: ... dial tcp 10.195.208.3:3307: i/o timeout
    • 最终诊断 : 这个错误表明,Google自己的后台服务(Auth Proxy依赖的前端)无法连接到您Cloud SQL实例的私有IP。这证实了问题出在Google Cloud平台内部一个我们无法直接干预的路由或服务配置上。

最终决策

既然官方推荐的工具本身都因平台问题而失败,继续调试已无意义。我们被迫采用一种创造性的、可以完全控制的解决方案------搭建我们自己的代理服务器,这就是Envoy跳板机方案的由来。


3. Envoy配置与测试

我们最终将configs/envoy.yaml配置为一个简单的TCP代理,并成功在GCE上部署和验证了其可行性。

3.1. 关键配置

yaml 复制代码
# configs/envoy.yaml

# ... (部分省略)
  listeners:
  - name: listener_psql
    address:
      socket_address:
        address: 0.0.0.0
        port_value: 5432
    filter_chains:
    - filters:
      - name: envoy.filters.network.tcp_proxy
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
          stat_prefix: psql_tcp
          cluster: "cloud_sql_psql_cluster"
  clusters:
  - name: cloud_sql_psql_cluster
    connect_timeout: 5s
    type: STRICT_DNS
    load_assignment:
      cluster_name: cloud_sql_psql_cluster
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: "10.195.208.3" # Cloud SQL 私有IP
                port_value: 5432
# ... (部分省略)

3.2. 最终验证

我们从本地机器执行psql,连接到作为跳板机的GCE的公网IP 34.39.2.90

命令:

bash 复制代码
env PGPASSWORD="YOUR_DB_PASSWORD" psql -h s s -p 5432 -U nvd11 -d default_db -c "\l"

output

bash 复制代码
                                              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)

结果: 成功列出数据库,证明方案可行。

相关推荐
l1t4 小时前
利用短整数类型和部分字符串优化DuckDB利用数组求解数独SQL
开发语言·数据库·sql·duckdb
驾数者6 小时前
Flink SQL核心概念解析:Table API与流表二元性
大数据·sql·flink
vortex511 小时前
谷歌黑客语法挖掘 SQL 注入漏洞
android·数据库·sql
wind_one113 小时前
7.基础--SQL--DDL-数据类型及案例
数据库·sql
l1t14 小时前
利用DeepSeek改写SQLite版本的二进制位数独求解SQL
数据库·人工智能·sql·sqlite
August_._16 小时前
【MySQL】SQL语法详细总结
java·数据库·后端·sql·mysql·oracle
还是奇怪1 天前
隐藏在字符编码中的陷阱:深入剖析宽字节注入
数据库·sql·安全·web安全
麦聪聊数据1 天前
大数据与云原生数据库中的 SQL2API:优化跨平台数据访问与查询
数据库·sql·云原生
IT 小阿姨(数据库)2 天前
PostgreSQL 之上的开源时序数据库 TimescaleDB 详解
运维·数据库·sql·postgresql·开源·centos·时序数据库