Cloud Run 连接本地 VPN:配置 Direct VPC egress
Cloud VPN 隧道并不会把 Cloud Run 放进网络。将服务挂到正确的子网,路由其真实的源地址范围,再验证那个修订版本。
隧道是通的,虚拟机也能访问本地服务器,但 Cloud Run 服务对同一台主机却超时。这往往是这项工作的正常起点,而问题很少真的在隧道本身。 Cloud Run 的修订版本默认并不在你的 VPC 内;一旦接入,它使用的是自己的源地址,而不是你已经路由过的虚拟机子网。下面的操作步骤会先挂接服务,再为其真实源范围配置路由,最后从处理该请求的修订版本验证通路。请按这个顺序执行,因为跳过第一步正是这类问题最后变成一次毫无作用的 VPN 变更的原因。
先挂接修订版本,再排查隧道
Cloud Run 支持 Direct VPC egress,它无需 Serverless VPC Access 连接器,就能把服务的流量放到你 VPC 中的子网上。对已有服务来说,更新大致如下:
gcloud run services update SERVICE \
--region=REGION --network=NETWORK --subnet=SUBNET \
--vpc-egress=private-ranges-only
替换占位符,评估这次部署对线上流量的影响,并在服务所在区域选择一个地址容量充足、网络权限正确的子网。
选择与目标匹配的出口模式
private-ranges-only 会把其判定为私有的目标经 VPC 发出。它并不等于「所有能通过 VPN 到达的东西」,当本地服务所处的范围不被该设置判定为私有时,这个缺口就会出现。如果目标不在覆盖范围内,all-traffic 是另一种有文档说明的模式,它会把所有流量都经 VPC 发出,包括服务的公共依赖。请有意识地选择,并把后果写入变更记录。
已经在使用连接器的服务属于迁移,而不是开关切换,所以要提前规划,而不是两种方式都配。
路由 Cloud Run 的源地址,而不是虚拟机的源地址
Direct VPC egress 会从所选子网分配临时地址,本地一侧必须把流量回程到该范围。为另一台虚拟机子网写的回程路由或防火墙放行,在图上看着正确,实际却会失败。子网 CIDR 要从 VPC 取,不要凭记忆,然后确认远端设备的加密 ACL 或路由表确实包含它。
使用动态路由时,要核实 Cloud Router 实际宣告了什么、VPC 又导入了什么,包括任何自定义宣告策略。控制台里存在但未被该目标选中的路由,等同于没有路由。
必须同时满足的三个条件
一条可用的通路需要以下全部条件,而每一条失败时的表现都不一样:
- VPC 中有一条经预期 Cloud VPN 连接通往本地网段的路由。
- 本地一侧有一条指向 Cloud Run 子网的回程路由。
- 防火墙与 IPsec 保护范围允许相应源地址、目标地址和端口。
缺少路由通常表现为超时,且远端没有任何记录。回程路由问题表现为请求到达、回包消失。防火墙或选择器问题可能表现为拒绝,也可能是静默丢弃,取决于设备。判断你遇到的是三者中的哪一种,能大幅缩小下一条命令的范围。
不要把单个临时 Cloud Run 地址加进白名单。请使用子网范围,并采用适合该应用的授权设计。
验证处理该请求的修订版本
测试前先检查已部署的网络设置和流量分配,因为更新可能创建新的修订版本,而请求仍在到达旧版本。然后从那个修订版本执行与用户请求相同的操作。如果目标是私有主机名,要在该环境中检查它的解析结果和得到的地址,因为笔记本上的企业 DNS 答案并不能证明服务的命名空间。TLS 主机名验证和远端应用自身的身份验证都要保留。
要预期 Direct VPC 有文档说明的启动连接延迟,并给客户端准备就绪或重试策略,而不是把每次冷启动都当成隧道故障来诊断。
回滚,以及这件事做不到的部分
要回滚,就把服务的网络与出口设置恢复为之前的值,并确认旧修订版本仍在提供服务。请把 gcloud 命令写进变更记录,因为部分变更的逆向操作在六周后并不显然。移除 VPC 挂接会让服务回到此前的出口路径,这在故障处理期间可能正是你想要的。
本方案覆盖的是 Cloud Run 发起的连接及其回包。它不会让本地网络在服务内部拥有可寻址的套接字,因为对外暴露属于 ingress 的决策。