WebP Cloud Services Blog

WebP Cloud Services 在去 Cloudflare 化上的一点摸索

· Nova Kwok

This article is also available in English, at WebP Cloud uses Cloudflare Workers to fetch content from the origin server in order to protect the origin server and start providing origin fetch time information..

Vendor lock-in,字面翻译为「供应商」锁定,Wikipedia 的翻译为「厂商陷阱」。

In economics, vendor lock-in, also known as proprietary lock-in or customer lock-in, makes a customer dependent on a vendor for products, unable to use another vendor without substantial switching costs.

Cloudflare 的产品非常不错,被许多人称为「赛博佛祖」,我们也是大量使用了 Cloudflare 的产品,也分享了不少的文章,比如:

但随着我们和 Cloudflare 的整合越来越深,看到越来越多的人都 All in Cloudflare 之后,我们内部也在思考一些「去 Cloudflare」的方案,尤其是我们也看到了一些…不那么友好的案例之后,例如:

尤其是 WebP Cloud 作为一个和 Cloudflare 部分业务有重合关系的小小的 SaaS 服务,我们没法接受被 Cloudflare 突然拔线而导致的长时间 Downtime,同时我们也明白 Cloudflare ToS 中对于非托管于 Cloudflare 自身产品(例如 Images/Stream/R2) 的几乎纯图片流量的态度一直处于灰色地带:

Finally, we made it clear that customers can serve video and other large files using the CDN so long as that content is hosted by a Cloudflare service like Stream, Images, or R2.

Video and large files hosted outside of Cloudflare will still be restricted on our CDN

Goodbye, section 2.8 and hello to Cloudflare’s new terms of service

既然我们的业务(其实也包括不少图片非托管于 Cloudflare 本身而只是用 Cloudflare 当 CDN 的图床服务)处于这个奇怪的暧昧地带,且在这个大方向都是在说如何「白嫖 Cloudflare」的时代,我们也想提点不一样的声音。

WebP Cloud Services Infra

在 WebP Cloud Services,我们和 Cloudflare 绑定的功能有如下:

NS 服务

NS 服务其实是最麻烦的一个环节,因为 NS 记录的全球通告可能至少持续 48 小时,如果 Cloudflare 突然暂停了我们的 NS 解析,我们需要立即从域名注册商手里迁移 NS 解析到我们的备用选择。

这一步我们通过一个目前没有在使用的域名演习了一下,并保留了完整的操作文档。

网站

目前我们的网站代码均托管于 GitHub,在 master 分支有修改时,Cloudflare Pages 会自动拉取最新的 Commit 进行构建并上线,为了防止 Cloudflare Pages 突然故障或者暂停我们的服务,我们在所有网站的仓库中加入了 Dockerfile,并设置了 GitHub Actions 在每个 Master 分支的时候自动构建镜像。

为了方便管理,我们每个网站都是一个独立/完整/stateless 的镜像,例如: https://blog.webp.se 的镜像为 ghcr.io/webp-pt/blog.webp.se:latest,启动方式也非常简单,没有任何外部依赖:

version: '3'

services:
  blog:
    image: ghcr.io/webp-pt/blog.webp.se:latest
    ports:
      - "4001:80"
  dashboard:
    image: ghcr.io/webp-pt/dashboard.webp.se:latest
    ports:
      - "4002:80"
...

只需要写好 Nginx 规则,然后把对应的域名反向代理到对应的服务上即可,这一步我们已经完成,并保留了完整的操作文档,如果服务出现问题,我们只需要修改 DNS 记录即可完成切换。

CDN && WAF

这里的难点在于 SSL 管理和防止暴露源站,由于我们在 Hetzner 中本身有带公网 IP 的 Load Balancer (目前 Cloudflare 解析地址也是对应的 Load Balancer 地址)。

所以这一步我们的难点在于维护一个可用的 SSL 证书,好在有 certbot ,我们可以在 Cloudflare 还在正常为我们提供服务的时候可以直接生成证书:

certbot certonly --agree-tos --dns-cloudflare --dns-cloudflare-credentials ./cloudflare.ini -d *.webp.se -d webp.se -d *.webp.li -d webp.li -d *.webp.ee -d webp.ee -d *.webp.fi -d webp.fi --work-dir /root/ssl --logs-dir /root/ssl --config-dir /root/ssl

拿到证书之后我们可以通过 API(https://docs.hetzner.cloud/#certificates-update-a-certificate) 直接上传到 Hetzner 上。

这样虽然没有了 Cloudflare CDN 提供的就近接入,但是我们依然可以保证在两个可用区(美国和德国)正常提供服务,当然,中国大陆用户访问速度可能会变慢。

WAF 规则部分被我们改写为了一些 Nginx 的规则,我们很清楚这样做远远没有在 Cloudflare 网络边缘那么有效,但是,聊胜于无。

Workers

这个是让我们最头疼的地方,因为这个是 Cloudflare 的专有产品,最符合 Vender-lockin 的说法。

我们调研过一些 AWS 的方案,例如 Lambda@Edge ,但发现均表现不佳。

所以如果没有 Workers 可用,我们的服务会有如下变化:

Custom Domain

目前我们 Custom Domain 使用了 Cloudflare for SaaS 的方案,我们只需要在程序和 Cloudflare 之间维持状态同步即可实现 Custom Domain 的接入(更详细的记录我们会单独有博文分享)

这里如果我们不使用这个方案,我们需要额外包装 certbot 之类的程序为自定义域名生成证书和提供服务,这个方案我们还在内部 PoC 中。

以上,便是我们 WebP Cloud Services 团队在去 Cloudflare 化上的一点摸索和记录,希望可以给有类似想法的同学提供一点思路,也希望可以给无脑 All in Cloudflare 的同学一点启发~


WebP Cloud Services 团队是一个来自上海和赫尔辛堡的三人小团队,由于我们不融资,且没有盈利压力 ,所以我们会坚持做我们认为正确的事情,力求在我们的资源和能力允许范围内尽量把事情做到最好, 同时也会在不影响对外提供的服务的情况下整更多的活,并在我们产品上实践各种新奇的东西。

如果你觉得我们的这个服务有意思或者对我们服务感兴趣,欢迎登录 WebP Cloud Dashboard 来体验,如果你好奇它还有哪些神奇的功能,可以来看看我们的文档 WebP Cloud Services Docs,希望大家玩的开心~


Discuss on Hacker News