Cloud SQL必须通过cloud-sql-proxy代理连接,因其无真实公网IP,仅支持加密隧道;phpMyAdmin需配置本地端口(如127.0.0.1:3307),不可直连实例名,且SSL、认证、多实例映射均由proxy统一处理。
cloud-sql-proxy 不是可选项,而是必须项——Google Cloud SQL 默认不开放公网 IP,所有连接都必须走代理通道。直接填 host 为实例的公网域名(如 my-project:us-central1:my-instance)在 phpMyAdmin 里根本连不通,会卡在 DNS 解析失败或 TCP 连接超时。
Cloud SQL 实例没有真正意义上的“公网地址”
你看到的所谓“公网 ip”其实是 gcp 控制台里显示的一个“服务端点”,它背后没有绑定真实网卡,也不响应 icmp 或裸 tcp 握手。只有 cloud-sql-proxy 启动后,在本地监听一个 127.0.0.1:port 的 socket,才真正把加密隧道落地为可被 php 连接的本地端口。
- 现象:
mysqli::real_connect(): (HY000/2003): Can't connect to MySQL server on 'my-project:us-central1:my-instance' - 原因:phpMyAdmin 尝试直连 GCP 的逻辑地址,但该地址不是 DNS 可解析的域名,也不是路由可达的 IP
- 验证方式:在服务器上执行
nslookup my-project:us-central1:my-instance,必然失败
多实例必须用 --instances 参数显式声明
不能靠改 $cfg['Servers'][$i]['host'] 切换实例——cloud-sql-proxy 启动时就决定了它代理哪些实例,phpMyAdmin 只能连它暴露出来的本地端口。
- 错误做法:在 config.inc.php 里写多个
host指向不同实例名,期望 JS 切换;实际所有请求都发往同一个本地端口,后端根本不知道你要连谁 - 正确做法:启动代理时用逗号分隔多个实例,并为每个分配独立本地端口:
cloud-sql-proxy \ --instances=my-project:us-central1:instance-a=tcp:3307,my-project:us-central1:instance-b=tcp:3308 \ --http-address=0.0.0.0 \ --http-port=9191
- 对应 phpMyAdmin 配置中,
$cfg['Servers'][1]['host'] = '127.0.0.1'; $cfg['Servers'][1]['port'] = '3307';,$cfg['Servers'][2]['host'] = '127.0.0.1'; $cfg['Servers'][2]['port'] = '3308';
SSL 和认证必须由 proxy 统一处理,phpMyAdmin 不能插手
Cloud SQL 要求所有连接启用 SSL,且证书校验严格。但 phpMyAdmin 的 MySQLi/PDO 层无法加载 GCP 提供的 client key/cert 文件(路径权限、格式、PEM 解析都不兼容),强行配置只会报 SSL connection error: protocol version mismatch 或直接拒绝握手。
-
cloud-sql-proxy启动时自动拉取 IAM 凭据、协商 TLS 1.2+、完成服务端身份校验,对上层透明 - phpMyAdmin 只需设
$cfg['Servers'][$i]['ssl'] = false;(因为连接走的是本地明文 TCP,安全由 proxy 保障) - 若误开
ssl = true并填了证书路径,MySQLi 会尝试二次加密封装,导致 handshake failure
session 和 FPM worker 必须按实例隔离,否则连接错绑
和阿里云 RDS 类似,多个 Cloud SQL 实例共用同一套 phpMyAdmin + PHP-FPM,容易触发连接复用污染。尤其当两个实例用相同用户名(如 root)但不同密码时,mysqlnd 驱动可能复用前一个连接的认证上下文,导致第二个实例报 Access denied for user 或秒断。
- 每个实例配独立
$cfg['SaveDir'](如/var/lib/phpmyadmin/sessions/gcp-a/) - 每个实例跑独立 FPM pool(
www-gcp-a.conf),设pm.max_children = 8(不超过 Cloud SQL 的max_connections上限) - 确认 nginx/Apache 的
fastcgi_pass指向对应 pool,不能全打到php-fpm.sock
GCP 的代理模型本质是“单向隧道”,所有复杂性(IAM、TLS、实例路由)都被收口到 cloud-sql-proxy 进程里。想绕过它直连,等于试图用 HTTP 客户端访问 gRPC 接口——协议层就不匹配。最容易被忽略的点是:很多人以为只要 proxy 在跑,phpMyAdmin 就能随便切实例,其实 proxy 的 --instances 列表和 phpMyAdmin 的 host/port 配置必须一一对应,漏掉一个端口映射,那个实例就永远黑屏。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











