无需停机即可将实时域切换到 Google 云 运行

Switch a live domain to Google Cloud Run without downtime

我在我的自定义云 运行 域 foo-eu7vrotrfq-uc.a.run.app 上设置了 Google 云 运行。我有一个域 foo.com,目前正在为实时流量提供服务。我想开始在 Cloud 运行 上提供 foo.com 服务,而不会中断约 100 个并发用户。

目前的域映射功能似乎无法做到这一点。域映射需要更新 DNS 才能颁发证书。根据 the documentation,这最多需要 15 分钟(在我的测试中大约需要 5 分钟)。在这 15 分钟内,foo.com 将无法正常投放。

这里有一些想法:

有没有人找到解决此问题的方法?似乎没有办法在不导致停机的情况下为现有域切换到云 运行。

这是一项艰巨的任务,但我认为您有多种选择。总结:

  1. 原生解决方案:注册域名,等待云运行识别,最后一步翻转DNS。会有 停机时间,因为 Cloud 运行 需要从 Let's Encrypt 获取 HTTPS 证书。

  2. Cloudflare 代理(使用 Host header 重写,这是一项企业计划功能),可能没有停机时间。

真正让这种情况变得困难的是 HTTPS。 Cloud 运行 当前不允许上传您自己的 TLS 证书,因此它可以立即开始服务流量(您可以稍后切换到 Cloud Run-managed 证书)。


选项 1

Keep in mind that DNS records, by their nature, will take several hours to propagate across the globe and to residential/edge locations. You need both OLD and NEW endpoints running at all times for maybe 24 hours.

首先,确保您在 Cloud Console 上为您的 Cloud 运行 应用程序创建域映射

此操作很可能表明您需要通过 Google 网站管理员工具域所有权验证。仅此操作可能需要一些时间。所以现在就做吧。

当您能够创建域映射时,它会为您提供一些 DNS 记录以使用它们更新您的域,如下所示,但不要更新您域的 DNS尚未记录:

此时,Google 云的负载平衡前端正在配置为将到达您的 foo.com 域名的流量路由到您的应用程序:

curl -vH "Host: foo.com" http://216.239.32.21

< HTTP/1.1 302 Found
< Location: https://example.com/

似乎 Cloud 运行 现在可以识别 foo.com 的存在。它不会因 HTTP 404 而失败,而是强制执行 https:// 重定向。

但是,云 运行 还无法 从 Let's Encrypt 为您的域获取 TLS 证书,因为 Let's Encrypt 无法访问 foo.com 来验证质询–DNS 仍指向您的旧服务器。

当您尝试通过伪造主机 header 并使用 https:// 来查询这些 IP 之一时,您会看到:

curl -kvH "Host: foo.com" https://216.239.32.21

curl: (35) error:14004410:SSL routines:CONNECT_CR_SRVR_HELLO:sslv3 alert handshake failure

此错误表示 Cloud 运行 尚未从 Let's Encrypt 成功检索证书并开始使用它。

此时,您必须将您的域指向 Cloud 运行 提供的 IP 地址,并且 会有一些停机时间,直到 Cloud 运行从 Let's Encrypt 获取证书(因为它会不断重试)。但这可能需要一些时间:5、10、20 分钟,很难保证。请记住,DNS 记录被大量缓存,因此这可能需要更长的时间。


选项 2

如果您使用 Cloudflare 作为负载均衡器,则可以使用 Page Rules to rewrite Host header。这仅在他们的企业计划中可用。有了这个,对 foo.com 的任何请求都将被重写并代理到您的 Cloud 运行 应用程序,例如 foo-eu7vrotrfq-uc.a.run.app.

这不使用 Cloud 运行 "domain mapping" 功能,因此您的 Cloud 运行 设置根本不知道您的 foo.com 域。

但是,如果您当前未使用 Cloudflare,请遵循这些指南以避免停机,因为与 Cloud 运行 类似,Cloudflare 需要为您的域名提供证书。

如果您使用的是 Cloudflare,这将是一个更平稳的过渡方式,如果出现问题,您可以使用 Cloudflare Page Rules 快速恢复。


总的来说,我认为你提出了一个很好的问题,感谢你对它进行了详尽的解释。你的分析是正确的。

由于 Cloud 运行 强制使用 https:// 并且 Let's Encrypt 需要访问您的应用程序以为其批准 TLS 证书(同样,Cloudflare 需要时间为您的域提供证书),这是不容易。

我将此反馈带回团队进行讨论,也许我们需要一种不同的方式来为域提供 TLS 证书,以防止迁移期间出现停机。我可能会写一个关于这个的指南。